ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/ccs/admin/admin.py
Revision: 600
Committed: 2009-10-15T23:42:17-07:00 (15 years, 8 months ago) by douglas
Content type: text/x-python
File size: 4883 byte(s)
Log Message:
Improving the build system...

File Contents

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

Properties

Name Value
svn:executable *
svn:keywords Id