Mercurial > hg > savane-forge
annotate src/savane/backend/auth_ldif_export.py @ 119:a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
author | Sylvain Beucler <beuc@beuc.net> |
---|---|
date | Sun, 02 Aug 2009 23:38:26 +0200 |
parents | cd5e4c45265b |
children | 8d4b08714c90 |
rev | line source |
---|---|
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
1 # Replicate users and groups to an OpenLDAP directory |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
2 # Copyright (C) 2009 Sylvain Beucler |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
3 # |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
4 # This file is part of Savane. |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
5 # |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
6 # Savane is free software: you can redistribute it and/or modify |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
7 # it under the terms of the GNU Affero General Public License as |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
8 # published by the Free Software Foundation, either version 3 of the |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
9 # License, or (at your option) any later version. |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
10 # |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
11 # Savane is distributed in the hope that it will be useful, |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
14 # GNU Affero General Public License for more details. |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
15 # |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
16 # You should have received a copy of the GNU Affero General Public License |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
18 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
19 # Recommended indexes: |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
20 # index uid,uidNumber,gidNumber,memberUid,shadowExpire eq |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
21 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
22 # TODO: most settings are hard-coded and need to be made configurable |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
23 # - base: dc=savannah,dc=gnu,dc=org |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
24 # - users ou: "users" |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
25 # - groups ou: "groups" |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
26 # - create 'organization' and 'organizationalUnit' objects? |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
27 # - min uid: 1000 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
28 # - min gid: 1000 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
29 # - default group: cn=svusers / gid=1000 |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
30 # - loginShell: /usr/local/bin/sv_membersh |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
31 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
32 import sys |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
33 import codecs |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
34 import base64, binascii |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
35 from django.db import connection, models |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
36 import savane.svmain.models as svmain_models |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
37 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
38 # Convert stdout to UTF-8 - if the stdout is redirected to a file |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
39 # sys.stdout.encoding is autodetected as 'None' and you get the |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
40 # obnoxious UnicodeEncodeError python error. |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
41 sys.stdout = codecs.getwriter('UTF-8')(sys.stdout) |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
42 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
43 print """dn: dc=savannah,dc=gnu,dc=org |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
44 objectClass: top |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
45 objectClass: dcObject |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
46 objectClass: organization |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
47 o: GNU |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
48 dc: savannah |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
49 structuralObjectClass: organization |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
50 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
51 dn: ou=users,dc=savannah,dc=gnu,dc=org |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
52 ou: users |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
53 objectClass: organizationalUnit |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
54 objectClass: top |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
55 structuralObjectClass: organizationalUnit |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
56 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
57 dn: ou=groups,dc=savannah,dc=gnu,dc=org |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
58 ou: groups |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
59 objectClass: organizationalUnit |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
60 objectClass: top |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
61 structuralObjectClass: organizationalUnit |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
62 """ |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
63 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
64 # Add user admin/admin |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
65 # (REMOVE WHEN TESTING IS DONE!) |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
66 print """ |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
67 dn: cn=admin,dc=savannah,dc=gnu,dc=org |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
68 objectClass: simpleSecurityObject |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
69 objectClass: organizationalRole |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
70 cn: admin |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
71 description: LDAP administrator |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
72 userPassword:: e2NyeXB0fWt0YVZ1TFNDaEg0Wi4= |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
73 structuralObjectClass: organizationalRole |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
74 """ |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
75 |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
76 import MySQLdb, settings |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
77 MySQLdb.charset = 'UTF-8' |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
78 conn = MySQLdb.connect(user=settings.DATABASE_USER, |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
79 passwd=settings.DATABASE_PASSWORD, |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
80 db=settings.DATABASE_NAME, |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
81 use_unicode=True) |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
82 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
83 # Alternatively: |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
84 #from django.db import connection |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
85 #connection.cursor() # establish connection - well looks like it does |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
86 #conn = connection.connection # MySQL-specific connection - now using mysqldb |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
87 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
88 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
89 ## |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
90 # Users |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
91 ## |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
92 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
93 max_uid = svmain_models.ExtendedUser.objects.all().aggregate(models.Max('uidNumber'))['uidNumber__max'] |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
94 if max_uid < 1000: max_uid = 1000 |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
95 |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
96 users_with_group = {} |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
97 group_users = {} |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
98 svmain_models.Membership.query_active_memberships_raw(conn, ('group_id', 'username')) |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
99 res = conn.store_result() |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
100 for row in res.fetch_row(maxrows=0, how=1): |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
101 users_with_group[row['username']] = 1 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
102 if group_users.has_key(row['group_id']): |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
103 group_users[row['group_id']].append(row['username']) |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
104 else: |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
105 group_users[row['group_id']] = [row['username'],] |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
106 |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
107 user_saves = [] |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
108 svmain_models.ExtendedUser.query_active_users_raw(conn, ('username', 'first_name', 'last_name', 'email', |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
109 'password', 'uidNumber', 'gidNumber')) |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
110 res = conn.store_result() |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
111 for row in res.fetch_row(maxrows=0): |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
112 (username, first_name, last_name, email, password, uidNumber, gidNumber) = row |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
113 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
114 #if uidNumber == 0: # either non-assigned, or mistakenly assigned to root |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
115 if uidNumber < 1000: # either non-assigned, or mistakenly assigned to privileged user |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
116 max_uid = max_uid + 1 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
117 user_saves.append((username, max_uid)) |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
118 uidNumber = max_uid |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
119 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
120 cleanup = [first_name, last_name, email] |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
121 for i in range(0, len(cleanup)): |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
122 cleanup[i] = cleanup[i].replace('\n', ' ') |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
123 cleanup[i] = cleanup[i].replace('\r', ' ') |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
124 cleanup[i] = cleanup[i].strip() |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
125 (first_name, last_name, email) = cleanup |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
126 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
127 ldap_password = '{CRYPT}!' # default = unusable password |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
128 if users_with_group.has_key(username): |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
129 if password.startswith('sha1$'): |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
130 # Django-specific algorithm: it sums 5-char-salt+pass instead |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
131 # of SSHA's pass+4-bytes-salt, so we can't store it in LDAP - |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
132 # /me curses django devs |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
133 pass |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
134 elif password.startswith('md5$$'): |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
135 # MD5 without salt |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
136 algo, empty, hash_hex = password.split('$') |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
137 if (len(hash_hex) == 32): # filter out empty or disabled passwords |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
138 ldap_password = "{MD5}" + base64.b64encode(binascii.a2b_hex(hash_hex)) |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
139 elif password.startswith('md5$'): |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
140 # md5$salt$ vs. {SMD5} is similar to sha1$salt$ vs. {SSHA} - |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
141 # cf. above |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
142 pass |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
143 elif password.startswith('crypt$'): |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
144 # glibc crypt has improved algorithms, but where salt contains |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
145 # three '$'s, which Django doesn't support (since '$' is |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
146 # already the salt field separator). So this is only weak, |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
147 # passwd-style (not shadow-style) crypt. |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
148 algo, salt_hex, hash_hex = password.split('$') |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
149 # salt_hex is 2-chars long and already prepended to hash_hex |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
150 ldap_password = "{CRYPT}" + base64.b64encode(binascii.a2b_hex(hash_hex)) |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
151 elif '$' not in password: |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
152 # MD5 without salt, alternate Django syntax |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
153 hash_hex = password |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
154 if (len(hash_hex) == 32): # filter out empty or disabled passwords |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
155 ldap_password = "{MD5}" + base64.b64encode(binascii.a2b_hex(hash_hex)) |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
156 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
157 # Object classes: |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
158 # - posixAccount: base class for libnss-ldap/pam-ldap support |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
159 # - shadowAccount: for shadowExpire |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
160 # - inetOrgPerson: for mail and givenName, and structural class |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
161 print u""" |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
162 dn: uidNumber=%(uidNumber)d,ou=users,dc=savannah,dc=gnu,dc=org |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
163 uid: %(username)s |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
164 cn:: %(full_name)s |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
165 sn:: %(last_name)s |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
166 mail: %(email)s |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
167 userPassword: %(ldap_password)s |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
168 uidNumber: %(uidNumber)d |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
169 gidNumber: %(gidNumber)d |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
170 homeDirectory: %(homedir)s |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
171 loginShell: /usr/local/bin/sv_membersh |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
172 objectClass: shadowAccount |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
173 objectClass: posixAccount |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
174 objectClass: inetOrgPerson |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
175 objectClass: top |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
176 structuralObjectClass: inetOrgPerson""" % { |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
177 'username' : username, |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
178 'full_name' : base64.b64encode((first_name + ' ' + last_name).encode('UTF-8')), |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
179 'last_name' : base64.b64encode((last_name or '-').encode('UTF-8')), |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
180 'email' : email, |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
181 'ldap_password' : ldap_password, |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
182 'uidNumber' : uidNumber, |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
183 'gidNumber' : 1000, |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
184 'homedir' : '/home/' + username[:1] + '/' + username[:2] + '/' + username, |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
185 } |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
186 # non-mandatory fields - slapadd doesn't accept empty fields apparently |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
187 if len(first_name) > 0: |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
188 print "givenName::" + base64.b64encode(first_name.encode('UTF-8')) |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
189 # disallow login for users that are not part of any group |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
190 if not users_with_group.has_key(username): |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
191 # shadowExpire is a timestamp - avoid 0 as it may be |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
192 # interpreted as 'no expiration' |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
193 print "shadowExpire: 10" |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
194 |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
195 ## |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
196 # Groups |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
197 ## |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
198 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
199 max_gid = svmain_models.ExtendedGroup.objects.all().aggregate(models.Max('gidNumber'))['gidNumber__max'] |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
200 if max_gid < 1000: max_gid = 1000 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
201 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
202 # Create base 'svusers' group |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
203 print u""" |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
204 dn: cn=svusers,ou=groups,dc=savannah,dc=gnu,dc=org |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
205 cn: svusers |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
206 gidNumber: 1000 |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
207 objectClass: posixGroup |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
208 objectClass: top |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
209 structuralObjectClass: posixGroup""" |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
210 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
211 # Dump groups |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
212 group_saves = [] |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
213 svmain_models.ExtendedGroup.query_active_groups_raw(conn, ('group_id', 'name', 'gidNumber')) |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
214 res = conn.store_result() |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
215 #for group in svmain_models.ExtendedGroup.objects.only('name'): |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
216 for row in res.fetch_row(maxrows=0): |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
217 (group_id, name, gidNumber) = row |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
218 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
219 if gidNumber < 1000: # either non-assigned, or mistakenly assigned to privileged user |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
220 max_gid = max_gid + 1 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
221 group_saves.append((group_id, max_gid)) |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
222 gidNumber = max_gid |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
223 |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
224 print u""" |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
225 dn: cn=%(name)s,ou=groups,dc=savannah,dc=gnu,dc=org |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
226 cn: %(name)s |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
227 gidNumber: %(gidNumber)s |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
228 objectClass: posixGroup |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
229 objectClass: top |
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
230 structuralObjectClass: posixGroup""" % { |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
231 'name' : name, |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
232 'gidNumber' : gidNumber, |
118
cd5e4c45265b
First draft of LDAP export / population
Sylvain Beucler <beuc@beuc.net>
parents:
diff
changeset
|
233 } |
119
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
234 if group_users.has_key(group_id): |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
235 for username in group_users[group_id]: |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
236 print "memberUid: " + username |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
237 |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
238 # TODO |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
239 # - user_saves |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
240 # - group_saves |
a34e97e27050
LDIF export: more efficient (direct MySQL access) and cleaner (queries in the models)
Sylvain Beucler <beuc@beuc.net>
parents:
118
diff
changeset
|
241 # with multi-line UPDATEs |