Make back window of first wizard pane work
[public/pyceo-broken.git] / bin / csc-chsh
1 #!/usr/bin/python2.4 --
2 """
3 chsh - change login shell
4
5 This utility imitates chsh(1) from the shadow password suite, but makes its
6 changes in the LDAP directory rather than in the passwd file.
7
8 When run from an unprivileged account, authentication will be performed
9 before the shell is changed, and the new shell must be listed in /etc/shells.
10 """
11 import os, sys, pwd, getopt, PAM
12
13 safe_environment = ['LOGNAME', 'USERNAME', 'USER', 'HOME', 'TERM', 'LANG'
14     'LC_ALL', 'LC_COLLATE', 'LC_CTYPE', 'LC_MESSAGES', 'LC_MONETARY',
15     'LC_NUMERIC', 'LC_TIME', 'UID', 'GID', 'SSH_CONNECTION', 'SSH_AUTH_SOCK',
16     'SSH_CLIENT']
17
18 for key in os.environ.keys():
19     if key not in safe_environment:
20         del os.environ[key]
21
22 os.environ['PATH'] = '/usr/sbin:/usr/bin:/sbin:/bin'
23
24 for pathent in sys.path[:]:
25     if not pathent.find('/usr') == 0:
26         sys.path.remove(pathent)
27
28 from csc.common.excep import InvalidArgument
29 from csc.adm import accounts
30
31 progname = os.path.basename(sys.argv[0])
32
33 def usage():
34     print "Usage: %s [-s shell] [username]" % progname
35     sys.exit(2)
36
37 def whoami():
38     uid = os.getuid()
39     username = os.getlogin()
40     if pwd.getpwnam(username).pw_uid != uid:
41         username = pwd.getpwuid(uid).pw_name
42     return (uid, username)
43
44 def authenticate(username):
45     auth = PAM.pam()
46     auth.start('chsh', username)
47     try:
48         auth.authenticate()
49         auth.acct_mgmt()
50     except PAM.error, resp:
51         print "%s: %s" % (progname, resp.args[0])
52         sys.exit(1)
53
54 def main():
55
56     pwuid, pwnam = whoami()
57
58     euid = os.geteuid()
59     os.setreuid(euid, euid)
60
61     try:
62         options, arguments = getopt.gnu_getopt(sys.argv[1:], 's:')
63         new_shell = None
64         for opt, val in options:
65             if opt == '-s':
66                 new_shell = val
67         if len(arguments) > 1:
68             usage()
69         elif len(arguments) == 1:
70             username = arguments[0]
71         else:
72             username = pwnam
73     except getopt.GetoptError, e:
74         usage()
75
76     try:
77         if pwuid and pwd.getpwnam(username).pw_uid != pwuid:
78             print "%s: You may not change the shell for %s." % (progname, username)
79             sys.exit(1)
80     except KeyError:
81         print "%s: unknown user %s" % (progname, username)
82         sys.exit(1)
83
84     try:
85         accounts.connect()
86         current_shell = accounts.get_shell(username)
87
88         if pwuid:
89             authenticate(username)
90
91         if not new_shell:
92             print "Changing the login shell for %s" % username
93             print "Enter the new value, or press ENTER for the default"
94             print "        Login Shell [%s]:" % current_shell,
95             new_shell = raw_input()
96             if not new_shell:
97                 new_shell = current_shell
98
99         if new_shell != current_shell:
100             accounts.update_shell(username, new_shell, pwuid != 0)
101
102     except InvalidArgument, e:
103         if e.argname == 'shell':
104             print "%s: %s: invalid shell" % (progname, new_shell)
105             sys.exit(1)
106         else:
107             raise
108
109 if __name__ == '__main__':
110     exceps = ( accounts.ConfigurationException, accounts.LDAPException,
111             accounts.KrbException, accounts.AccountException )
112     try:
113         main()
114     except KeyboardInterrupt:
115         sys.exit(130) 
116     except IOError, e:
117         print "%s: %s: %s" % (progname, e.filename, e.strerror)
118         sys.exit(1)
119     except exceps, e:
120         print "%s: %s" % (progname, e)
121         sys.exit(1)