65
64
Return Value: the uid associated with the user. INT
67
if 'unixid' not in props or props['unixid'] is None:
68
# For the time being, just choose a random unixid.
69
# This may result in duplicates, but the unixid is essentially
70
# a monitoring/logging convenience only. Oh, and dups could kill
72
props['unixid'] = random.randrange(5000,10000)
73
# raise NotImplementedError, "No algorithm for creating uids yet!"
75
# props['unixid'] = unixid
68
77
common.makeuser.make_user_db(**props)
69
user = common.db.get_user(props["login"])
79
return int(props['unixid'])
72
81
def update_user(props):
73
82
"""Create the database record for the given user.
88
97
db.update_user(**update)
91
def get_login(login, passwd, realm, existing_login, _may_save):
100
def get_login(login, passwd, _realm, _login, _may_save):
92
101
"""Callback function used by pysvn for authentication.
93
login, passwd: Credentials of the user attempting to log in.
94
passwd in clear (this should be the user's svn_pass, a
95
randomly-generated permanent password for this user, not their main
97
realm, existing_login, _may_save: The 3 arguments passed by pysvn to
99
The following has been determined empirically, not from docs:
100
existing_login will be the name of the user who owns the process on
101
the first attempt, "" on subsequent attempts. We use this fact.
103
logging.debug("Getting password for %s (realm %s)" % (login, realm))
104
# Only provide credentials on the _first_ attempt.
105
# If we're being asked again, then it means the credentials failed for
106
# some reason and we should just fail. (This is not desirable, but it's
107
# better than being asked an infinite number of times).
108
if existing_login == "":
109
logging.warning("Could not authenticate SVN for %s" % login)
110
return (False, login, passwd, False)
112
return (True, login, passwd, False)
103
logging.debug("Getting password for %s (realm %s)" % (login, _realm))
104
return (True, login, passwd, False)
114
106
def activate_user(props):
115
107
"""Create the on-disk stuff for the given user.
161
151
except Exception, exc:
162
152
logging.warning("While mkdiring info1: %s" % str(exc))
154
logging.debug("Creating /submissions")
156
svn.mkdir(conf.svn_addr + login + "/submissions",
157
"Initial creation of submissions directory")
158
except Exception, exc:
159
logging.warning("While mkdiring submissions: %s" % str(exc))
164
161
logging.debug("Creating /stuff")
166
163
svn.mkdir(conf.svn_addr + login + "/stuff",
172
169
logging.debug("Creating jail")
173
common.makeuser.make_jail(login, details.unixid, svn_pass=passwd)
175
common.makeuser.mount_jail(login)
177
do_checkout(props, svn_pass=passwd)
170
common.makeuser.make_jail(login, details.unixid)
174
tcf_path = os.path.join(conf.jail_base, 'template/opt/ivle/lib/conf/conf.py')
175
cf_path = os.path.join(conf.jail_base, login, 'opt/ivle/lib/conf/conf.py')
178
cf = open(cf_path, "w")
179
cf.write(open(tcf_path, "r").read())
180
cf.write("# The login name for the owner of the jail\n")
181
cf.write("login = %s\n" % repr(login))
183
cf.write("# The subversion-only password for the owner of the jail\n")
184
cf.write("svn_pass = %s\n" % repr(passwd))
189
logging.debug("Checking out directories in the jail")
191
svn.checkout(conf.svn_addr + login + "/stuff",
192
common.studpath.url_to_local(login + "/stuff")[1])
193
except Exception, exc:
194
logging.warning("While mkdiring stuff: %s" % str(exc))
197
svn.checkout(conf.svn_addr + login + "/submissions",
198
common.studpath.url_to_local(login + "/submissions")[1])
199
except Exception, exc:
200
logging.warning("While mkdiring submissions: %s" % str(exc))
203
svn.checkout(conf.svn_addr + login + "/info1",
204
common.studpath.url_to_local(login + "/info1")[1])
205
except Exception, exc:
206
logging.warning("While mkdiring info1: %s" % str(exc))
179
209
# FIXME: should this be nicer?
180
210
os.system("chown -R %d:%d %s" \
181
211
% (details.unixid, details.unixid,
182
212
common.studpath.url_to_local(login)[1]))
184
215
logging.info("Enabling user")
185
216
db.update_user(login, state='enabled')
192
def do_checkout(props, svn_pass=None):
193
"""Create the default contents of a user's jail by checking out from the
195
If any directory already exists, just fail silently (so this is not a
196
"wipe-and-checkout", merely a checkout if it failed or something).
198
login - the user name for the jail
202
login = props['login']
205
user = db.get_user(login)
206
# If svn_pass isn't supplied, grab it from the DB
208
svn_pass = user.svn_pass
212
svn.callback_get_login = partial(get_login, login, svn_pass)
214
if conf.svn_addr[-1] != os.sep:
215
conf.svn_addr += os.sep
219
logging.debug("Checking out directories in the jail")
221
svn.checkout(conf.svn_addr + login + "/stuff",
222
common.studpath.url_to_local(login + "/stuff")[1])
223
os.system("chown -R %d:%d %s" \
224
% (user.unixid, user.unixid,
225
common.studpath.url_to_local(login + "/stuff")[1]))
226
except Exception, exc:
227
logging.warning("While mkdiring stuff: %s" % str(exc))
230
svn.checkout(conf.svn_addr + login + "/info1",
231
common.studpath.url_to_local(login + "/info1")[1])
232
os.system("chown -R %d:%d %s" \
233
% (user.unixid, user.unixid,
234
common.studpath.url_to_local(login + "/info1")[1]))
235
except Exception, exc:
236
logging.warning("While mkdiring info1: %s" % str(exc))
241
return {"response": "okay"}
244
224
'create_user':create_user,
245
225
'update_user':update_user,
246
226
'activate_user':activate_user,
247
'do_checkout':do_checkout,
252
pidfile = open('/var/run/usrmgt-server.pid', 'w')
253
pidfile.write('%d\n' % os.getpid())
255
except IOError, (errno, strerror):
256
print "Couldn't write PID file. IO error(%s): %s" % (errno, strerror)
259
229
def dispatch(props):
260
230
logging.debug(repr(props))
261
231
action = props.keys()[0]
273
243
logging.basicConfig(filename="/var/log/usrmgt.log", level=logging.INFO)
274
244
logging.info("Starting usrmgt server on port %d (pid = %d)" % (port, pid))
276
common.chat.start_server(port, magic, True, dispatch, initializer)
246
common.chat.start_server(port, magic, True, dispatch)