64
65
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
77
68
common.makeuser.make_user_db(**props)
79
return int(props['unixid'])
69
user = common.db.get_user(props["login"])
81
72
def update_user(props):
82
73
"""Create the database record for the given user.
97
88
db.update_user(**update)
100
def get_login(login, passwd, _realm, _login, _may_save):
91
def get_login(login, passwd, realm, existing_login, _may_save):
101
92
"""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
return (True, login, passwd, False)
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)
106
114
def activate_user(props):
107
115
"""Create the on-disk stuff for the given user.
162
172
logging.debug("Creating jail")
163
common.makeuser.make_jail(login, details.unixid)
167
tcf_path = os.path.join(conf.jail_base, 'template/opt/ivle/lib/conf/conf.py')
168
cf_path = os.path.join(conf.jail_base, login, 'opt/ivle/lib/conf/conf.py')
171
cf = open(cf_path, "w")
172
cf.write(open(tcf_path, "r").read())
173
cf.write("# The login name for the owner of the jail\n")
174
cf.write("login = %s\n" % repr(login))
176
cf.write("# The subversion-only password for the owner of the jail\n")
177
cf.write("svn_pass = %s\n" % repr(passwd))
182
logging.debug("Checking out directories in the jail")
184
svn.checkout(conf.svn_addr + login + "/stuff",
185
common.studpath.url_to_local(login + "/stuff")[1])
186
except Exception, exc:
187
logging.warning("While mkdiring stuff: %s" % str(exc))
190
svn.checkout(conf.svn_addr + login + "/info1",
191
common.studpath.url_to_local(login + "/info1")[1])
192
except Exception, exc:
193
logging.warning("While mkdiring info1: %s" % str(exc))
173
common.makeuser.make_jail(login, details.unixid, svn_pass=passwd)
175
common.makeuser.mount_jail(login)
177
do_checkout(props, svn_pass=passwd)
196
179
# FIXME: should this be nicer?
197
180
os.system("chown -R %d:%d %s" \
198
181
% (details.unixid, details.unixid,
199
182
common.studpath.url_to_local(login)[1]))
202
184
logging.info("Enabling user")
203
185
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"}
211
244
'create_user':create_user,
212
245
'update_user':update_user,
213
246
'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)
216
259
def dispatch(props):
217
260
logging.debug(repr(props))
218
261
action = props.keys()[0]
230
273
logging.basicConfig(filename="/var/log/usrmgt.log", level=logging.INFO)
231
274
logging.info("Starting usrmgt server on port %d (pid = %d)" % (port, pid))
233
common.chat.start_server(port, magic, True, dispatch)
276
common.chat.start_server(port, magic, True, dispatch, initializer)