63 support_entities = {'CWUser': False} |
63 support_entities = {'CWUser': False} |
64 use_cwuri_as_url = False |
64 use_cwuri_as_url = False |
65 |
65 |
66 options = ( |
66 options = ( |
67 ('auth-mode', |
67 ('auth-mode', |
68 {'type' : 'choice', |
68 {'type': 'choice', |
69 'default': 'simple', |
69 'default': 'simple', |
70 'choices': ('simple', 'digest_md5', 'gssapi'), |
70 'choices': ('simple', 'digest_md5', 'gssapi'), |
71 'help': 'authentication mode used to authenticate user to the ldap.', |
71 'help': 'authentication mode used to authenticate user to the ldap.', |
72 'group': 'ldap-source', 'level': 3, |
72 'group': 'ldap-source', 'level': 3, |
73 }), |
73 }), |
74 ('auth-realm', |
74 ('auth-realm', |
75 {'type' : 'string', |
75 {'type': 'string', |
76 'default': None, |
76 'default': None, |
77 'help': 'realm to use when using gssapi/kerberos authentication.', |
77 'help': 'realm to use when using gssapi/kerberos authentication.', |
78 'group': 'ldap-source', 'level': 3, |
78 'group': 'ldap-source', 'level': 3, |
79 }), |
79 }), |
80 |
80 |
81 ('data-cnx-dn', |
81 ('data-cnx-dn', |
82 {'type' : 'string', |
82 {'type': 'string', |
83 'default': '', |
83 'default': '', |
84 'help': 'user dn to use to open data connection to the ldap (eg used \ |
84 'help': 'user dn to use to open data connection to the ldap (eg used \ |
85 to respond to rql queries). Leave empty for anonymous bind', |
85 to respond to rql queries). Leave empty for anonymous bind', |
86 'group': 'ldap-source', 'level': 1, |
86 'group': 'ldap-source', 'level': 1, |
87 }), |
87 }), |
88 ('data-cnx-password', |
88 ('data-cnx-password', |
89 {'type' : 'string', |
89 {'type': 'string', |
90 'default': '', |
90 'default': '', |
91 'help': 'password to use to open data connection to the ldap (eg used to respond to rql queries). Leave empty for anonymous bind.', |
91 'help': 'password to use to open data connection to the ldap (eg used to respond to rql queries). Leave empty for anonymous bind.', |
92 'group': 'ldap-source', 'level': 1, |
92 'group': 'ldap-source', 'level': 1, |
93 }), |
93 }), |
94 |
94 |
95 ('user-base-dn', |
95 ('user-base-dn', |
96 {'type' : 'string', |
96 {'type': 'string', |
97 'default': '', |
97 'default': '', |
98 'help': 'base DN to lookup for users; disable user importation mechanism if unset', |
98 'help': 'base DN to lookup for users; disable user importation mechanism if unset', |
99 'group': 'ldap-source', 'level': 1, |
99 'group': 'ldap-source', 'level': 1, |
100 }), |
100 }), |
101 ('user-scope', |
101 ('user-scope', |
102 {'type' : 'choice', |
102 {'type': 'choice', |
103 'default': 'ONELEVEL', |
103 'default': 'ONELEVEL', |
104 'choices': ('BASE', 'ONELEVEL', 'SUBTREE'), |
104 'choices': ('BASE', 'ONELEVEL', 'SUBTREE'), |
105 'help': 'user search scope (valid values: "BASE", "ONELEVEL", "SUBTREE")', |
105 'help': 'user search scope (valid values: "BASE", "ONELEVEL", "SUBTREE")', |
106 'group': 'ldap-source', 'level': 1, |
106 'group': 'ldap-source', 'level': 1, |
107 }), |
107 }), |
108 ('user-classes', |
108 ('user-classes', |
109 {'type' : 'csv', |
109 {'type': 'csv', |
110 'default': ('top', 'posixAccount'), |
110 'default': ('top', 'posixAccount'), |
111 'help': 'classes of user (with Active Directory, you want to say "user" here)', |
111 'help': 'classes of user (with Active Directory, you want to say "user" here)', |
112 'group': 'ldap-source', 'level': 1, |
112 'group': 'ldap-source', 'level': 1, |
113 }), |
113 }), |
114 ('user-filter', |
114 ('user-filter', |
116 'default': '', |
116 'default': '', |
117 'help': 'additional filters to be set in the ldap query to find valid users', |
117 'help': 'additional filters to be set in the ldap query to find valid users', |
118 'group': 'ldap-source', 'level': 2, |
118 'group': 'ldap-source', 'level': 2, |
119 }), |
119 }), |
120 ('user-login-attr', |
120 ('user-login-attr', |
121 {'type' : 'string', |
121 {'type': 'string', |
122 'default': 'uid', |
122 'default': 'uid', |
123 'help': 'attribute used as login on authentication (with Active Directory, you want to use "sAMAccountName" here)', |
123 'help': 'attribute used as login on authentication (with Active Directory, you want to use "sAMAccountName" here)', |
124 'group': 'ldap-source', 'level': 1, |
124 'group': 'ldap-source', 'level': 1, |
125 }), |
125 }), |
126 ('user-default-group', |
126 ('user-default-group', |
127 {'type' : 'csv', |
127 {'type': 'csv', |
128 'default': ('users',), |
128 'default': ('users',), |
129 'help': 'name of a group in which ldap users will be by default. \ |
129 'help': 'name of a group in which ldap users will be by default. \ |
130 You can set multiple groups by separating them by a comma.', |
130 You can set multiple groups by separating them by a comma.', |
131 'group': 'ldap-source', 'level': 1, |
131 'group': 'ldap-source', 'level': 1, |
132 }), |
132 }), |
133 ('user-attrs-map', |
133 ('user-attrs-map', |
134 {'type' : 'named', |
134 {'type': 'named', |
135 'default': {'uid': 'login'}, |
135 'default': {'uid': 'login'}, |
136 'help': 'map from ldap user attributes to cubicweb attributes (with Active Directory, you want to use sAMAccountName:login,mail:email,givenName:firstname,sn:surname)', |
136 'help': 'map from ldap user attributes to cubicweb attributes (with Active Directory, you want to use sAMAccountName:login,mail:email,givenName:firstname,sn:surname)', |
137 'group': 'ldap-source', 'level': 1, |
137 'group': 'ldap-source', 'level': 1, |
138 }), |
138 }), |
139 ('group-base-dn', |
139 ('group-base-dn', |
140 {'type' : 'string', |
140 {'type': 'string', |
141 'default': '', |
141 'default': '', |
142 'help': 'base DN to lookup for groups; disable group importation mechanism if unset', |
142 'help': 'base DN to lookup for groups; disable group importation mechanism if unset', |
143 'group': 'ldap-source', 'level': 1, |
143 'group': 'ldap-source', 'level': 1, |
144 }), |
144 }), |
145 ('group-scope', |
145 ('group-scope', |
146 {'type' : 'choice', |
146 {'type': 'choice', |
147 'default': 'ONELEVEL', |
147 'default': 'ONELEVEL', |
148 'choices': ('BASE', 'ONELEVEL', 'SUBTREE'), |
148 'choices': ('BASE', 'ONELEVEL', 'SUBTREE'), |
149 'help': 'group search scope (valid values: "BASE", "ONELEVEL", "SUBTREE")', |
149 'help': 'group search scope (valid values: "BASE", "ONELEVEL", "SUBTREE")', |
150 'group': 'ldap-source', 'level': 1, |
150 'group': 'ldap-source', 'level': 1, |
151 }), |
151 }), |
152 ('group-classes', |
152 ('group-classes', |
153 {'type' : 'csv', |
153 {'type': 'csv', |
154 'default': ('top', 'posixGroup'), |
154 'default': ('top', 'posixGroup'), |
155 'help': 'classes of group', |
155 'help': 'classes of group', |
156 'group': 'ldap-source', 'level': 1, |
156 'group': 'ldap-source', 'level': 1, |
157 }), |
157 }), |
158 ('group-filter', |
158 ('group-filter', |
160 'default': '', |
160 'default': '', |
161 'help': 'additional filters to be set in the ldap query to find valid groups', |
161 'help': 'additional filters to be set in the ldap query to find valid groups', |
162 'group': 'ldap-source', 'level': 2, |
162 'group': 'ldap-source', 'level': 2, |
163 }), |
163 }), |
164 ('group-attrs-map', |
164 ('group-attrs-map', |
165 {'type' : 'named', |
165 {'type': 'named', |
166 'default': {'cn': 'name', 'memberUid': 'member'}, |
166 'default': {'cn': 'name', 'memberUid': 'member'}, |
167 'help': 'map from ldap group attributes to cubicweb attributes', |
167 'help': 'map from ldap group attributes to cubicweb attributes', |
168 'group': 'ldap-source', 'level': 1, |
168 'group': 'ldap-source', 'level': 1, |
169 }), |
169 }), |
170 ) |
170 ) |
271 def _connect(self, user=None, userpwd=None): |
271 def _connect(self, user=None, userpwd=None): |
272 protocol, host, port = self.connection_info() |
272 protocol, host, port = self.connection_info() |
273 self.info('connecting %s://%s:%s as %s', protocol, host, port, |
273 self.info('connecting %s://%s:%s as %s', protocol, host, port, |
274 user and user['dn'] or 'anonymous') |
274 user and user['dn'] or 'anonymous') |
275 server = ldap3.Server(host, port=int(port)) |
275 server = ldap3.Server(host, port=int(port)) |
276 conn = ldap3.Connection(server, user=user and user['dn'], client_strategy=ldap3.STRATEGY_SYNC_RESTARTABLE, auto_referrals=False) |
276 conn = ldap3.Connection( |
|
277 server, user=user and user['dn'], |
|
278 client_strategy=ldap3.STRATEGY_SYNC_RESTARTABLE, |
|
279 auto_referrals=False) |
277 # Now bind with the credentials given. Let exceptions propagate out. |
280 # Now bind with the credentials given. Let exceptions propagate out. |
278 if user is None: |
281 if user is None: |
279 # XXX always use simple bind for data connection |
282 # XXX always use simple bind for data connection |
280 if not self.cnx_dn: |
283 if not self.cnx_dn: |
281 conn.bind() |
284 conn.bind() |
328 |
331 |
329 def _process_ldap_item(self, dn, iterator): |
332 def _process_ldap_item(self, dn, iterator): |
330 """Turn an ldap received item into a proper dict.""" |
333 """Turn an ldap received item into a proper dict.""" |
331 itemdict = {'dn': dn} |
334 itemdict = {'dn': dn} |
332 for key, value in iterator: |
335 for key, value in iterator: |
333 if self.user_attrs.get(key) == 'upassword': # XXx better password detection |
336 if self.user_attrs.get(key) == 'upassword': # XXx better password detection |
334 value = value[0].encode('utf-8') |
337 value = value[0].encode('utf-8') |
335 # we only support ldap_salted_sha1 for ldap sources, see: server/utils.py |
338 # we only support ldap_salted_sha1 for ldap sources, see: server/utils.py |
336 if not value.startswith(b'{SSHA}'): |
339 if not value.startswith(b'{SSHA}'): |
337 value = utils.crypt_password(value) |
340 value = utils.crypt_password(value) |
338 itemdict[key] = Binary(value) |
341 itemdict[key] = Binary(value) |