ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/ccs/admin/admin.py
Revision: 598
Committed: 2009-10-15T06:23:31-07:00 (15 years, 8 months ago) by douglas
Content type: text/x-python
File size: 4594 byte(s)
Log Message:
adduser!

File Contents

# User Rev Content
1 douglas 585 # CCS Computer Science
2 douglas 590 # Admin
3 douglas 585 #
4     # Douglas Thrift
5     #
6     # $Id$
7    
8 douglas 591 from __future__ import with_statement
9     import common
10 douglas 585 import ldap
11 douglas 598 import os
12     import psycopg2
13     import shutil
14 douglas 592 import sys
15 douglas 585
16 douglas 598 if sys.hexversion >= 0x2060000:
17     import warnings
18    
19     with warnings.catch_warnings():
20     warnings.filterwarnings('ignore', 'the sets module is deprecated', DeprecationWarning)
21    
22     import MySQLdb
23     else:
24     import MySQLdb
25    
26 douglas 585 MASTER = 'zweihander.ccs.ucsb.edu'
27     BASE = 'dc=ccs,dc=ucsb,dc=edu'
28 douglas 598 PEOPLE = 'ou=People,' + BASE
29     GROUP = 'ou=Group,' + BASE
30 douglas 592 SHELLS = map(lambda system: 'ucsbCcs' + system.capitalize(), common.SYSTEMS)
31 douglas 598 SAMBA_SID = 'S-1-5-21-3739982181-3886045993-82308153-%u'
32 douglas 585
33     ldap.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
34     ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, '/ccs/ssl/ccscert.pem')
35     ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
36    
37     def _user(user):
38 douglas 598 return 'uid=%s,%s' % (user, PEOPLE)
39 douglas 585
40 douglas 598 def _group(group):
41     return 'cn=%s,%s' % (group, GROUP)
42    
43 douglas 585 def ldap_connection():
44     connection = ldap.initialize('ldaps://' + MASTER)
45    
46     with open('/ccs/etc/secret', 'rb') as secret:
47     connection.simple_bind_s(_user('root'), secret.read())
48    
49     return connection
50    
51 douglas 591 def master():
52 douglas 592 return common.HOST == MASTER
53 douglas 591
54 douglas 593 def run(errors):
55     if errors:
56     for host, error in errors.iteritems():
57     sys.stderr.write('%s: %s\n' % (host, error))
58 douglas 592
59     sys.exit(1)
60    
61 douglas 593 def error(error):
62     sys.exit('%s: %s' % (sys.argv[0], error))
63    
64 douglas 592 def eof():
65     print
66    
67     sys.exit(130)
68    
69 douglas 598 def adduser(user, name, password):
70     connection = ldap_connection()
71     uid = max(map(lambda user: int(user[1]['uidNumber'][0]), connection.search_s(PEOPLE, ldap.SCOPE_ONELEVEL, '(&(uid=*)(!(uid=root)))', ('uidNumber',)))) + 1
72     gid = uid
73     samba_gid = gid + 1000
74     home = os.path.join('/home', user)
75    
76     connection.add_s(_user(user), [
77     ('objectclass', ['top', 'account', 'posixAccount', 'shadowAccount', 'ucsbCcsLoginShells', 'sambaSamAccount']),
78     ('cn', name),
79     ('uid', user),
80     ('uidNumber', str(uid)),
81     ('gidNumber', str(gid)),
82     ('homeDirectory', home),
83     ('loginShell', 'bash'),
84     ] + zip(SHELLS, dict(common.SHELLS)['bash']) + [
85     ('sambaAcctFlags', '[U ]'),
86     ('sambaSID', SAMBA_SID % uid),
87     ('sambaPrimaryGroupSID', SAMBA_SID % samba_gid),
88     ])
89     connection.add_s(_group(user), [
90     ('objectclass', ['top', 'posixGroup', 'sambaGroupMapping']),
91     ('cn', user),
92     ('gidNumber', str(gid)),
93     ('sambaSID', SAMBA_SID % samba_gid),
94     ('sambaGroupType', '4'),
95     ])
96    
97     for group in ('wheel', 'fuse', 'operator'):
98     connection.modify_s(_group(group), [(ldap.MOD_ADD, 'memberUid', user)])
99    
100     connection.unbind_s()
101     os.umask(0022)
102     os.mkdir(home)
103     os.chown(home, uid, gid)
104    
105     for skel in ('/usr/share/skel', '/ccs/skel'):
106     for source, directories, files in os.walk(skel):
107     destination = os.path.join(home, source[len(skel):])
108    
109     for directory in directories:
110     target = os.path.join(destination, directory[3:] if directory.startswith('dot') else directory)
111    
112     os.mkdir(target)
113     shutil.copymode(os.path.join(source, directory), target)
114     os.chown(target, uid, gid)
115    
116     for file in files:
117     target = os.path.join(destination, file[3:] if file.startswith('dot') else file)
118    
119     shutil.copy(os.path.join(source, file), target)
120     os.chown(target, uid, gid)
121    
122     db = psycopg2.connect(database = 'postgres')
123     cursor = db.cursor()
124    
125     cursor.execute('create user %s with createdb' % user)
126     db.commit()
127    
128     passwd(user, None, password)
129    
130 douglas 592 def chfn(user, name):
131     connection = ldap_connection()
132    
133     connection.modify_s(_user(user), [(ldap.MOD_REPLACE, 'cn', name)])
134     connection.unbind_s()
135    
136 douglas 591 def chsh(user, shell, shells):
137     if shell != 'custom':
138     shells = dict(common.SHELLS)[shell]
139     else:
140     for _shell, _shells in common.SHELLS[:-1]:
141     if shells == _shells:
142     shell = _shell
143    
144     connection = ldap_connection()
145    
146     connection.modify_s(_user(user), map(lambda (key, value): (ldap.MOD_REPLACE, key, value), [('loginShell', shell)] + zip(SHELLS, shells)))
147     connection.unbind_s()
148    
149 douglas 585 def passwd(user, old_password, new_password):
150     connection = ldap_connection()
151    
152     connection.passwd_s(_user(user), old_password, new_password)
153     connection.unbind_s()
154    
155     with open('/ccs/etc/secret', 'rb') as secret:
156     db = MySQLdb.connect(passwd = secret.read(), db = 'mysql')
157    
158     cursor = db.cursor()
159    
160     cursor.execute('select count(User) from user where User = %s', (user,))
161    
162     if cursor.fetchone()[0]:
163     cursor.execute('update user set Password = PASSWORD(%s) where User = %s', (new_password, user))
164     cursor.execute('flush privileges');
165     else:
166     cursor.executemany('grant all on `' + db.escape_string(user) + r'\_%%`.* to %s@%s identified by %s', map(lambda host: (user, host, new_password), ('localhost', '%')))

Properties

Name Value
svn:keywords Id