ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/ccs/admin/admin.py
Revision: 680
Committed: 2010-07-02T19:40:04-07:00 (15 years ago) by douglas
Content type: text/x-python
File size: 4829 byte(s)
Log Message:
Everything is using Python 2.6 now!

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

Properties

Name Value
svn:executable *
svn:keywords Id