2007-12-13 02:48:05 -05:00
|
|
|
#!/usr/bin/python
|
2007-02-04 07:04:38 -05:00
|
|
|
"""
|
|
|
|
chfn - change real user name and information
|
|
|
|
|
|
|
|
This utility imitates chfn(1) from the shadow password suite, but makes its
|
|
|
|
changes in the LDAP directory rather than in the passwd file.
|
|
|
|
|
|
|
|
When run from an unprivileged account, authentication will be performed
|
|
|
|
before the account information is changed.
|
|
|
|
"""
|
|
|
|
import os, sys, pwd, getopt, PAM
|
2007-12-13 03:39:05 -05:00
|
|
|
from ceo import accounts
|
|
|
|
from ceo.excep import InvalidArgument
|
2007-02-04 07:04:38 -05:00
|
|
|
|
|
|
|
progname = os.path.basename(sys.argv[0])
|
|
|
|
|
|
|
|
OPTION_MAP = {
|
|
|
|
'-f': 'fullname',
|
|
|
|
'-r': 'roomnumber',
|
|
|
|
'-w': 'workphone',
|
|
|
|
'-h': 'homephone',
|
|
|
|
'-o': 'other'
|
|
|
|
}
|
|
|
|
LONG_NAMES = [
|
|
|
|
('fullname', 'Full Name'),
|
|
|
|
('roomnumber', 'Room Number'),
|
|
|
|
('workphone', 'Work Phone'),
|
|
|
|
('homephone', 'Home Phone'),
|
|
|
|
('other', 'Other')
|
|
|
|
]
|
|
|
|
READONLY_FIELDS = [ 'fullname', 'other' ]
|
|
|
|
|
|
|
|
def usage():
|
|
|
|
umesg = "Usage: %s [-f full name] [-r room no] [-w work ph] " + \
|
|
|
|
"[-h home ph] [-o other] [user]"
|
|
|
|
print umesg % progname
|
|
|
|
sys.exit(2)
|
|
|
|
|
|
|
|
|
|
|
|
def whoami():
|
|
|
|
uid = os.getuid()
|
|
|
|
username = os.getlogin()
|
|
|
|
if pwd.getpwnam(username).pw_uid != uid:
|
|
|
|
username = pwd.getpwuid(uid).pw_name
|
|
|
|
return (uid, username)
|
|
|
|
|
|
|
|
def authenticate(username):
|
|
|
|
auth = PAM.pam()
|
|
|
|
auth.start('chsh', username)
|
|
|
|
try:
|
|
|
|
auth.authenticate()
|
|
|
|
auth.acct_mgmt()
|
|
|
|
except PAM.error, resp:
|
|
|
|
print "%s: %s" % (progname, resp.args[0])
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
|
|
|
pwuid, pwnam = whoami()
|
|
|
|
|
2007-05-05 01:32:16 -04:00
|
|
|
euid = os.geteuid()
|
|
|
|
os.setreuid(euid, euid)
|
|
|
|
|
2007-02-04 07:04:38 -05:00
|
|
|
gecos_params = {}
|
|
|
|
|
|
|
|
try:
|
|
|
|
options, arguments = getopt.gnu_getopt(sys.argv[1:], 'f:r:w:h:o:')
|
|
|
|
for opt, val in options:
|
|
|
|
gecos_params[OPTION_MAP[opt]] = val
|
|
|
|
if len(arguments) > 1:
|
|
|
|
usage()
|
|
|
|
elif len(arguments) == 1:
|
|
|
|
username = arguments[0]
|
|
|
|
else:
|
|
|
|
username = pwnam
|
|
|
|
except getopt.GetoptError, e:
|
|
|
|
usage()
|
|
|
|
|
|
|
|
for field in READONLY_FIELDS:
|
|
|
|
if field in gecos_params and pwuid:
|
|
|
|
print "%s: Permission denied." % progname
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
try:
|
|
|
|
if pwuid and pwd.getpwnam(username).pw_uid != pwuid:
|
|
|
|
print "%s: Permission denied." % progname
|
|
|
|
sys.exit(1)
|
|
|
|
except KeyError:
|
|
|
|
print "%s: unknown user %s" % (progname, username)
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
try:
|
|
|
|
accounts.connect()
|
|
|
|
gecos_raw = accounts.get_gecos(username)
|
|
|
|
gecos = accounts.parse_gecos(gecos_raw)
|
|
|
|
|
|
|
|
if pwuid:
|
|
|
|
authenticate(username)
|
|
|
|
|
|
|
|
if not gecos_params:
|
|
|
|
print "Changing the user information for %s" % username
|
|
|
|
print "Enter the new value, or press ENTER for the default"
|
|
|
|
for field, longname in LONG_NAMES:
|
|
|
|
if pwuid and field == 'other' and 'other' in READONLY_FIELDS:
|
|
|
|
continue
|
|
|
|
if gecos[field] is None:
|
|
|
|
gecos[field] = ""
|
|
|
|
if field in READONLY_FIELDS and pwuid:
|
|
|
|
print " %s: %s" % (longname, gecos[field])
|
|
|
|
else:
|
|
|
|
print " %s: [%s]:" % (longname, gecos[field]),
|
|
|
|
new_value = raw_input()
|
|
|
|
if new_value:
|
|
|
|
gecos[field] = new_value.strip()
|
|
|
|
else:
|
|
|
|
gecos.update(gecos_params)
|
|
|
|
|
|
|
|
gecos_raw_new = accounts.build_gecos(**gecos)
|
|
|
|
if gecos_raw != gecos_raw_new:
|
|
|
|
accounts.update_gecos(username, gecos_raw_new)
|
|
|
|
|
|
|
|
except InvalidArgument, e:
|
|
|
|
longnames = dict(LONG_NAMES)
|
|
|
|
longname = longnames.get(e.argname, e.argname).lower()
|
|
|
|
print "%s: invalid %s: %s" % (progname, longname, e.argval)
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
exceps = ( accounts.ConfigurationException, accounts.LDAPException,
|
|
|
|
accounts.KrbException, accounts.AccountException )
|
|
|
|
try:
|
|
|
|
main()
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
sys.exit(130)
|
|
|
|
except IOError, e:
|
|
|
|
print "%s: %s: %s" % (progname, e.filename, e.strerror)
|
|
|
|
sys.exit(1)
|
|
|
|
except exceps, e:
|
|
|
|
print "%s: %s" % (progname, e)
|
|
|
|
sys.exit(1)
|