c64d85a0e552a08d6a75003fd0d0d6360355543c
[abartlet/samba.git/.git] / source4 / lib / ldb / tests / python / ldap.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 # This is a port of the original in testprogs/ejs/ldap.js
4
5 import getopt
6 import optparse
7 import sys
8 import time
9
10 sys.path.append("bin/python")
11 sys.path.append("../lib/subunit/python")
12
13 import samba.getopt as options
14
15 from samba.auth import system_session
16 from ldb import (SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError,
17                  LDB_ERR_NO_SUCH_OBJECT, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS,
18                  LDB_ERR_ENTRY_ALREADY_EXISTS, LDB_ERR_UNWILLING_TO_PERFORM,
19                  LDB_ERR_NOT_ALLOWED_ON_NON_LEAF, LDB_ERR_OTHER, LDB_ERR_INVALID_DN_SYNTAX)
20 from samba import Ldb
21 from subunit import SubunitTestRunner
22 from samba import param
23 import unittest
24
25 parser = optparse.OptionParser("ldap [options] <host>")
26 sambaopts = options.SambaOptions(parser)
27 parser.add_option_group(sambaopts)
28 parser.add_option_group(options.VersionOptions(parser))
29 # use command line creds if available
30 credopts = options.CredentialsOptions(parser)
31 parser.add_option_group(credopts)
32 opts, args = parser.parse_args()
33
34 if len(args) < 1:
35     parser.print_usage()
36     sys.exit(1)
37
38 host = args[0]
39
40 lp = sambaopts.get_loadparm()
41 creds = credopts.get_credentials(lp)
42
43 class BasicTests(unittest.TestCase):
44     def delete_force(self, ldb, dn):
45         try:
46             ldb.delete(dn)
47         except LdbError, (num, _): 
48             self.assertEquals(num, LDB_ERR_NO_SUCH_OBJECT)
49
50     def find_basedn(self, ldb):
51         res = ldb.search(base="", expression="", scope=SCOPE_BASE, 
52                          attrs=["defaultNamingContext"])
53         self.assertEquals(len(res), 1)
54         return res[0]["defaultNamingContext"][0]
55
56     def find_configurationdn(self, ldb):
57         res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["configurationNamingContext"])
58         self.assertEquals(len(res), 1)
59         return res[0]["configurationNamingContext"][0]
60
61     def find_schemadn(self, ldb):
62         res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
63         self.assertEquals(len(res), 1)
64         return res[0]["schemaNamingContext"][0]
65
66     def setUp(self):
67         self.ldb = ldb
68         self.gc_ldb = gc_ldb
69         self.base_dn = self.find_basedn(ldb)
70         self.configuration_dn = self.find_configurationdn(ldb)
71         self.schema_dn = self.find_schemadn(ldb)
72
73         print "baseDN: %s\n" % self.base_dn
74
75         self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
76         self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
77         self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
78         self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
79         self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà ,cn=users," + self.base_dn)
80         self.delete_force(self.ldb, "cn=ldaptestutf8user2  èùéìòà ,cn=users," + self.base_dn)
81   
82     def test_group_add_invalid_member(self):
83         """Testing group add with invalid member"""
84         try:
85             self.ldb.add({
86                 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
87                 "objectclass": "group",
88                 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
89             self.fail()
90         except LdbError, (num, _): 
91             self.assertEquals(num, LDB_ERR_NO_SUCH_OBJECT)
92
93     def test_all(self):
94         """Basic tests"""
95
96         self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
97
98         print "Testing user add"
99         ldb.add({
100         "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
101         "objectclass": ["user", "person"],
102         "cN": "LDAPtestUSER",
103         "givenname": "ldap",
104         "sn": "testy"})
105
106         ldb.add({
107             "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
108             "objectclass": "group",
109             "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
110
111         self.delete_force(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
112         ldb.add({
113             "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
114             "objectclass": "computer",
115             "cN": "LDAPtestCOMPUTER"})
116
117         self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
118         ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
119             "objectClass": "computer",
120             "cn": "LDAPtest2COMPUTER",
121             "userAccountControl": "4096",
122             "displayname": "ldap testy"})
123
124         self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
125         try:
126             ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
127                      "objectClass": "computer",
128                      "cn": "LDAPtest2COMPUTER"
129                      })
130             self.fail()
131         except LdbError, (num, _): 
132             self.assertEquals(num, LDB_ERR_INVALID_DN_SYNTAX)
133             
134         self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
135         try:
136             ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
137                      "objectClass": "computer",
138                      "cn": "ldaptestcomputer3",
139                      "sAMAccountType": "805306368"
140                 })
141             self.fail()
142         except LdbError, (num, _): 
143             self.assertEquals(num, LDB_ERR_UNWILLING_TO_PERFORM)
144             
145         self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
146         try:
147             ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
148                      "objectClass": "computer",
149                      "cn": "ldaptestcomputer3",
150                      "userAccountControl": "0"
151                 })
152             self.fail()
153         except LdbError, (num, _): 
154             self.assertEquals(num, LDB_ERR_UNWILLING_TO_PERFORM)
155             
156         self.delete_force(self.ldb, "cn=ldaptestuser7,cn=users," + self.base_dn)
157         try:
158             ldb.add({"dn": "cn=ldaptestuser7,cn=users," + self.base_dn,
159                      "objectClass": "user",
160                      "cn": "LDAPtestuser7",
161                      "userAccountControl": "0"
162                 })
163             self.fail()
164         except LdbError, (num, _): 
165             self.assertEquals(num, LDB_ERR_UNWILLING_TO_PERFORM)
166             
167         self.delete_force(self.ldb, "cn=ldaptestuser7,cn=users," + self.base_dn)
168
169         ldb.add({"dn": "cn=ldaptestuser7,cn=users," + self.base_dn,
170                  "objectClass": "user",
171                  "cn": "LDAPtestuser7",
172                  "userAccountControl": "2"
173                  })
174             
175         self.delete_force(self.ldb, "cn=ldaptestuser7,cn=users," + self.base_dn)
176
177         self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
178         ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
179                  "objectClass": "computer",
180                  "cn": "LDAPtestCOMPUTER3"
181                  })
182             
183         print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
184         res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
185         self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
186
187         self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
188         self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
189         self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
190         self.assertEquals(res[0]["objectClass"][0], "top");
191         self.assertEquals(res[0]["objectClass"][1], "person");
192         self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
193         self.assertEquals(res[0]["objectClass"][3], "user");
194         self.assertEquals(res[0]["objectClass"][4], "computer");
195         self.assertTrue("objectGUID" in res[0])
196         self.assertTrue("whenCreated" in res[0])
197         self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn));
198         self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
199         self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306368);
200         self.assertEquals(int(res[0]["userAccountControl"][0]), 546);
201
202         self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
203
204         print "Testing attribute or value exists behaviour"
205         try:
206             ldb.modify_ldif("""
207 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
208 changetype: modify
209 replace: servicePrincipalName
210 servicePrincipalName: host/ldaptest2computer
211 servicePrincipalName: host/ldaptest2computer
212 servicePrincipalName: cifs/ldaptest2computer
213 """)
214             self.fail()
215         except LdbError, (num, msg):
216             self.assertEquals(num, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS)
217
218         ldb.modify_ldif("""
219 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
220 changetype: modify
221 replace: servicePrincipalName
222 servicePrincipalName: host/ldaptest2computer
223 servicePrincipalName: cifs/ldaptest2computer
224 """)
225         try:
226             ldb.modify_ldif("""
227 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
228 changetype: modify
229 add: servicePrincipalName
230 servicePrincipalName: host/ldaptest2computer
231 """)
232             self.fail()
233         except LdbError, (num, msg):
234             self.assertEquals(num, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS)
235
236         print "Testing ranged results"
237         ldb.modify_ldif("""
238 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
239 changetype: modify
240 replace: servicePrincipalName
241 """)
242             
243         ldb.modify_ldif("""
244 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
245 changetype: modify
246 add: servicePrincipalName
247 servicePrincipalName: host/ldaptest2computer0
248 servicePrincipalName: host/ldaptest2computer1
249 servicePrincipalName: host/ldaptest2computer2
250 servicePrincipalName: host/ldaptest2computer3
251 servicePrincipalName: host/ldaptest2computer4
252 servicePrincipalName: host/ldaptest2computer5
253 servicePrincipalName: host/ldaptest2computer6
254 servicePrincipalName: host/ldaptest2computer7
255 servicePrincipalName: host/ldaptest2computer8
256 servicePrincipalName: host/ldaptest2computer9
257 servicePrincipalName: host/ldaptest2computer10
258 servicePrincipalName: host/ldaptest2computer11
259 servicePrincipalName: host/ldaptest2computer12
260 servicePrincipalName: host/ldaptest2computer13
261 servicePrincipalName: host/ldaptest2computer14
262 servicePrincipalName: host/ldaptest2computer15
263 servicePrincipalName: host/ldaptest2computer16
264 servicePrincipalName: host/ldaptest2computer17
265 servicePrincipalName: host/ldaptest2computer18
266 servicePrincipalName: host/ldaptest2computer19
267 servicePrincipalName: host/ldaptest2computer20
268 servicePrincipalName: host/ldaptest2computer21
269 servicePrincipalName: host/ldaptest2computer22
270 servicePrincipalName: host/ldaptest2computer23
271 servicePrincipalName: host/ldaptest2computer24
272 servicePrincipalName: host/ldaptest2computer25
273 servicePrincipalName: host/ldaptest2computer26
274 servicePrincipalName: host/ldaptest2computer27
275 servicePrincipalName: host/ldaptest2computer28
276 servicePrincipalName: host/ldaptest2computer29
277 """)
278
279         res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, 
280                          attrs=["servicePrincipalName;range=0-*"])
281         self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
282         #print len(res[0]["servicePrincipalName;range=0-*"])
283         self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
284
285         res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
286         self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
287             # print res[0]["servicePrincipalName;range=0-19"].length
288         self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
289
290             
291         res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
292         self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
293         self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
294
295         res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
296         self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
297         self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
298
299         res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
300         self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
301         self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
302
303             
304         res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
305         self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
306         self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
307         # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
308
309         res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
310         self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
311         self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
312             # print res[0]["servicePrincipalName;range=11-*"][18]
313             # print pos_11
314             # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
315
316         res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
317         self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
318         self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
319             # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
320
321         res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
322         self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
323             # print res[0]["servicePrincipalName"][18]
324             # print pos_11
325         self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
326             # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
327
328         self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
329         ldb.add({
330             "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
331             "objectClass": ["person", "user"],
332             "cn": "LDAPtestUSER2",
333             "givenname": "testy",
334             "sn": "ldap user2"})
335
336         print "Testing Ambigious Name Resolution"
337         # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
338         res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
339         self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
340
341         # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
342         res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
343         self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
344
345         # Testing ldb.search for (&(anr=ldap)(objectClass=user))
346         res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
347         self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
348
349         # Testing ldb.search for (&(anr==ldap)(objectClass=user))
350         res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
351         self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
352
353         self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
354         self.assertEquals(res[0]["cn"][0], "ldaptestuser")
355         self.assertEquals(res[0]["name"], "ldaptestuser")
356
357         # Testing ldb.search for (&(anr=testy)(objectClass=user))
358         res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
359         self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
360
361         # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
362         res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
363         self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
364
365         # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
366 # this test disabled for the moment, as anr with == tests are not understood
367 #        res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
368 #        self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
369
370         self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
371         self.assertEquals(res[0]["cn"][0], "ldaptestuser")
372         self.assertEquals(res[0]["name"][0], "ldaptestuser")
373
374         # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
375 #        res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
376 #        self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
377
378         self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
379         self.assertEquals(res[0]["cn"][0], "ldaptestuser")
380         self.assertEquals(res[0]["name"][0], "ldaptestuser")
381
382         # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
383         res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
384         self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
385
386         self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
387         self.assertEquals(res[0]["cn"], "ldaptestuser2")
388         self.assertEquals(res[0]["name"], "ldaptestuser2")
389
390         # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
391 #        res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
392 #        self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
393
394         self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
395         self.assertEquals(res[0]["cn"], "ldaptestuser2")
396         self.assertEquals(res[0]["name"], "ldaptestuser2")
397
398         # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
399 #        res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
400 #        self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
401
402         self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
403         self.assertEquals(res[0]["cn"], "ldaptestuser2")
404         self.assertEquals(res[0]["name"], "ldaptestuser2")
405
406         # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
407 #        res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
408 #        self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
409
410         # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
411         res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
412         self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
413
414         # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
415 #        res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
416 #        self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
417
418         print "Testing Group Modifies"
419         ldb.modify_ldif("""
420 dn: cn=ldaptestgroup,cn=users,""" + self.base_dn + """
421 changetype: modify
422 add: member
423 member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
424 member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
425 """)
426
427         self.delete_force(ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
428
429         print "Testing adding non-existent user to a group"
430         try:
431             ldb.modify_ldif("""
432 dn: cn=ldaptestgroup,cn=users,""" + self.base_dn + """
433 changetype: modify
434 add: member
435 member: cn=ldaptestuser3,cn=users,""" + self.base_dn + """
436 """)
437             self.fail()
438         except LdbError, (num, _):
439             self.assertEquals(num, LDB_ERR_NO_SUCH_OBJECT)
440
441         print "Testing Renames"
442
443         attrs = ["objectGUID", "objectSid"]
444         print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
445         res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
446         self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
447
448         #Check rename works with extended/alternate DN forms 
449         ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestuser3,cn=users," + self.base_dn)
450
451         ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
452
453         ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
454
455         print "Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))"
456         res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
457         self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
458
459         self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
460         self.assertEquals(res[0]["cn"], "ldaptestUSER3")
461         self.assertEquals(res[0]["name"], "ldaptestUSER3")
462
463         #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
464         res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
465         self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
466
467         self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
468         self.assertEquals(res[0]["cn"], "ldaptestUSER3")
469         self.assertEquals(res[0]["name"], "ldaptestUSER3")
470
471         #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
472         res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
473         self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
474
475         self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
476         self.assertEquals(res[0]["cn"], "ldaptestUSER3")
477         self.assertEquals(res[0]["name"], "ldaptestUSER3")
478
479         #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
480         res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
481         self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
482
483         # This is a Samba special, and does not exist in real AD
484         #    print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
485         #    res = ldb.search("(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
486         #    if (res.error != 0 || len(res) != 1) {
487         #        print "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
488         #        self.assertEquals(len(res), 1)
489         #    }
490         #    self.assertEquals(res[0].dn, ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
491         #    self.assertEquals(res[0].cn, "ldaptestUSER3")
492         #    self.assertEquals(res[0].name, "ldaptestUSER3")
493
494         print "Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
495         res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
496         self.assertEquals(len(res), 1, "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
497         self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
498         self.assertEquals(res[0]["cn"], "ldaptestUSER3")
499         self.assertEquals(res[0]["name"], "ldaptestUSER3")
500
501         # ensure we cannot add it again
502         try:
503             ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
504                       "objectClass": ["person", "user"],
505                       "cn": "LDAPtestUSER3"})
506             self.fail()
507         except LdbError, (num, _):
508             self.assertEquals(num, LDB_ERR_ENTRY_ALREADY_EXISTS)
509
510         # rename back
511         ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
512
513         # ensure we cannnot rename it twice
514         try:
515             ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, 
516                        "cn=ldaptestuser2,cn=users," + self.base_dn)
517             self.fail()
518         except LdbError, (num, _): 
519             self.assertEquals(num, LDB_ERR_NO_SUCH_OBJECT)
520
521         # ensure can now use that name
522         ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
523                       "objectClass": ["person", "user"],
524                       "cn": "LDAPtestUSER3"})
525         
526         # ensure we now cannnot rename
527         try:
528             ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
529             self.fail()
530         except LdbError, (num, _):
531             self.assertEquals(num, LDB_ERR_ENTRY_ALREADY_EXISTS)
532         try:
533             ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=configuration," + self.base_dn)
534             self.fail()
535         except LdbError, (num, _):
536             self.assertTrue(num in (71, 64))
537
538         ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
539
540         ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
541
542         self.delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
543
544         ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
545
546         print "Testing subtree Renames"
547
548         ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn, 
549                  "objectClass": "container"})
550         
551         self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
552         ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn, 
553                  "objectClass": ["person", "user"],
554                  "cn": "LDAPtestUSER4"})
555
556         ldb.modify_ldif("""
557 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
558 changetype: modify
559 add: member
560 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
561 """)
562         
563         print "Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
564         ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
565
566         print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))"
567         res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
568         self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
569
570         print "Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
571         try:
572             ldb.search("cn=ldaptestcontainer," + self.base_dn, 
573                     expression="(&(cn=ldaptestuser4)(objectClass=user))", 
574                     scope=SCOPE_SUBTREE)
575             self.fail()
576         except LdbError, (num, _):
577             self.assertEquals(num, LDB_ERR_NO_SUCH_OBJECT)
578
579         print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
580         try:
581             res = ldb.search("cn=ldaptestcontainer," + self.base_dn, 
582                     expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
583             self.fail()
584         except LdbError, (num, _):
585             self.assertEquals(num, LDB_ERR_NO_SUCH_OBJECT)
586
587         print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
588         res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
589         self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
590
591         self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
592         self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
593
594         time.sleep(4)
595
596         print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
597         res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
598         self.assertEquals(len(res), 1, "Could not find (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)), perhaps linked attributes are not consistant with subtree renames?")
599
600         print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
601         try:
602             ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
603             self.fail()
604         except LdbError, (num, _):
605             self.assertEquals(num, LDB_ERR_UNWILLING_TO_PERFORM)
606
607         print "Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
608         try:
609             ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
610             self.fail()
611         except LdbError, (num, _):
612             self.assertTrue(num in (LDB_ERR_UNWILLING_TO_PERFORM, LDB_ERR_OTHER))
613
614         print "Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
615         try:
616             ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
617             self.fail()
618         except LdbError, (num, _):
619             self.assertEquals(num, LDB_ERR_NOT_ALLOWED_ON_NON_LEAF)
620
621         print "Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
622         res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
623         self.assertEquals(len(res), 1)
624         res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
625         self.assertEquals(len(res), 0)
626
627         print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
628         res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
629         # FIXME: self.assertEquals(len(res), 0)
630
631         print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
632         res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
633         # FIXME: self.assertEquals(len(res), 0)
634
635         print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
636         ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
637         print "Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
638         ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
639         
640         self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà ,cn=users," + self.base_dn)
641         ldb.add({"dn": "cn=ldaptestutf8user èùéìòà ,cn=users," + self.base_dn, "objectClass": "user"})
642
643         self.delete_force(self.ldb, "cn=ldaptestutf8user2  èùéìòà ,cn=users," + self.base_dn)
644         ldb.add({"dn": "cn=ldaptestutf8user2  èùéìòà ,cn=users," + self.base_dn, "objectClass": "user"})
645
646         print "Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
647         res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
648         self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
649
650         self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
651         self.assertEquals(res[0]["cn"], "ldaptestuser")
652         self.assertEquals(res[0]["name"], "ldaptestuser")
653         self.assertEquals(res[0]["objectClass"], ["top", "person", "organizationalPerson", "user"])
654         self.assertTrue("objectGUID" in res[0])
655         self.assertTrue("whenCreated" in res[0])
656         self.assertEquals(res[0]["objectCategory"], ("CN=Person,CN=Schema,CN=Configuration," + self.base_dn))
657         self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306368)
658         self.assertEquals(int(res[0]["userAccountControl"][0]), 546)
659         self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
660         self.assertEquals(len(res[0]["memberOf"]), 1)
661      
662         print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))"
663         res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
664         self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
665
666         self.assertEquals(res[0].dn, res2[0].dn)
667
668         print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
669         res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
670         self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
671
672         self.assertEquals(res[0].dn, res3[0].dn)
673
674         if gc_ldb is not None:
675             print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
676             res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
677             self.assertEquals(len(res3gc), 1)
678         
679             self.assertEquals(res[0].dn, res3gc[0].dn)
680
681         print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
682         
683         res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
684         self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
685         
686         self.assertEquals(res[0].dn, res3control[0].dn)
687
688         ldb.delete(res[0].dn)
689
690         print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
691         res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
692         self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
693
694         self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
695         self.assertEquals(res[0]["cn"], "ldaptestcomputer")
696         self.assertEquals(res[0]["name"], "ldaptestcomputer")
697         self.assertEquals(res[0]["objectClass"], ["top", "person", "organizationalPerson", "user", "computer"])
698         self.assertTrue("objectGUID" in res[0])
699         self.assertTrue("whenCreated" in res[0])
700         self.assertEquals(res[0]["objectCategory"], ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn))
701         self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
702         self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306368)
703         self.assertEquals(int(res[0]["userAccountControl"][0]), 546)
704         self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
705         self.assertEquals(len(res[0]["memberOf"]), 1)
706
707         print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))"
708         res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
709         self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
710
711         self.assertEquals(res[0].dn, res2[0].dn)
712
713         if gc_ldb is not None:
714             print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog"
715             res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
716             self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog")
717
718             self.assertEquals(res[0].dn, res2gc[0].dn)
719
720         print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
721         res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
722         self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
723
724         self.assertEquals(res[0].dn, res3[0].dn)
725
726         if gc_ldb is not None:
727             print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
728             res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
729             self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
730
731             self.assertEquals(res[0].dn, res3gc[0].dn)
732
733         print "Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
734         res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
735         self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
736
737         self.assertEquals(res[0].dn, res4[0].dn)
738
739         print "Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
740         res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
741         self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
742
743         self.assertEquals(res[0].dn, res5[0].dn)
744
745         print "Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
746         res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
747         self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
748
749         self.assertEquals(res[0].dn, res6[0].dn)
750         
751         ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
752
753         print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
754         res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
755         self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
756
757         self.assertEquals(res[0].dn, ("CN=ldaptest2computer,CN=Computers," + self.base_dn))
758         self.assertEquals(res[0]["cn"], "ldaptest2computer")
759         self.assertEquals(res[0]["name"], "ldaptest2computer")
760         self.assertEquals(res[0]["objectClass"], ["top", "person", "organizationalPerson", "user", "computer"])
761         self.assertTrue("objectGUID" in res[0])
762         self.assertTrue("whenCreated" in res[0])
763         self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,CN=Schema,CN=Configuration," + self.base_dn)
764         self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306369)
765         self.assertEquals(int(res[0]["userAccountControl"][0]), 4096)
766
767         ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
768
769         attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
770         print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
771         res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
772         self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
773
774         self.assertEquals(res_user[0].dn, ("CN=ldaptestuser2,CN=Users," + self.base_dn))
775         self.assertEquals(res_user[0]["cn"], "ldaptestuser2")
776         self.assertEquals(res_user[0]["name"], "ldaptestuser2")
777         self.assertEquals(res_user[0]["objectClass"], ["top", "person", "organizationalPerson", "user"])
778         self.assertTrue("objectSid" in res_user[0])
779         self.assertTrue("objectGUID" in res_user[0])
780         self.assertTrue("whenCreated" in res_user[0])
781         self.assertTrue("nTSecurityDescriptor" in res_user[0])
782         self.assertTrue("allowedAttributes" in res_user[0])
783         self.assertTrue("allowedAttributesEffective" in res_user[0])
784         self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
785
786         ldaptestuser2_sid = res_user[0]["objectSid"][0]
787         ldaptestuser2_guid = res_user[0]["objectGUID"][0]
788
789         attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
790         print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
791         res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
792         self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
793
794         self.assertEquals(res[0].dn, ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
795         self.assertEquals(res[0]["cn"], "ldaptestgroup2")
796         self.assertEquals(res[0]["name"], "ldaptestgroup2")
797         self.assertEquals(res[0]["objectClass"], ["top", "group"])
798         self.assertTrue("objectGUID" in res[0])
799         self.assertTrue("objectSid" in res[0])
800         self.assertTrue("whenCreated" in res[0])
801         self.assertTrue("nTSecurityDescriptor" in res[0])
802         self.assertTrue("allowedAttributes" in res[0])
803         self.assertTrue("allowedAttributesEffective" in res[0])
804         memberUP = []
805         for m in res[0]["member"]:
806             memberUP.append(m.upper())
807         self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
808
809         res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
810         self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
811
812         print res[0]["member"]
813         memberUP = []
814         for m in res[0]["member"]:
815             memberUP.append(m.upper())
816         print ("<GUID=" + ldb.schema_format_value("objectGUID", ldaptestuser2_guid) + ">;<SID=" + ldb.schema_format_value("objectSid", ldaptestuser2_sid) + ">;CN=ldaptestuser2,CN=Users," + self.base_dn).upper()
817
818         self.assertTrue(("<GUID=" + ldb.schema_format_value("objectGUID", ldaptestuser2_guid) + ">;<SID=" + ldb.schema_format_value("objectSid", ldaptestuser2_sid) + ">;CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
819
820         print "Testing Linked attribute behaviours"
821         ldb.modify_ldif("""
822 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
823 changetype: modify
824 replace: member
825 member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
826 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
827 """)
828         
829         ldb.modify_ldif("""
830 dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
831 changetype: modify
832 replace: member
833 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
834 """)
835         
836         ldb.modify_ldif("""
837 dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
838 changetype: modify
839 delete: member
840 """)
841
842         ldb.modify_ldif("""
843 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
844 changetype: modify
845 add: member
846 member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
847 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
848 """)
849         
850         ldb.modify_ldif("""
851 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
852 changetype: modify
853 replace: member
854 """)
855         
856         ldb.modify_ldif("""
857 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
858 changetype: modify
859 add: member
860 member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
861 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
862 """)
863         
864         ldb.modify_ldif("""
865 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
866 changetype: modify
867 delete: member
868 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
869 """)
870         
871         res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
872         self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
873
874         self.assertEquals(res[0].dn, ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
875         self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
876         self.assertEquals(len(res[0]["member"]), 1)
877
878         ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
879
880         time.sleep(4)
881
882         attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
883         print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
884         res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
885         self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
886
887         self.assertEquals(res[0].dn, ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
888         self.assertTrue("member" not in res[0])
889
890         print "Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
891         res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
892         self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
893
894         self.assertEquals(res[0].dn, ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
895         self.assertEquals(res[0]["cn"], "ldaptestutf8user èùéìòà")
896         self.assertEquals(res[0]["name"], "ldaptestutf8user èùéìòà")
897         self.assertEquals(res[0]["objectClass"], ["top", "person", "organizationalPerson", "user"])
898         self.assertTrue("objectGUID" in res[0])
899         self.assertTrue("whenCreated" in res[0])
900
901         ldb.delete(res[0].dn)
902
903         print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
904         res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
905         self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
906
907         ldb.delete(res[0].dn)
908
909         ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
910
911         print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
912         res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
913
914         #FIXME: self.assert len(res) == 1, "Could not find (expect space collapse, win2k3 fails) (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
915
916         print "Testing that we can't get at the configuration DN from the main search base"
917         res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
918         self.assertEquals(len(res), 0)
919
920         print "Testing that we can get at the configuration DN from the main search base on the LDAP port with the 'phantom root' search_options control"
921         res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
922         self.assertTrue(len(res) > 0)
923
924         if gc_ldb is not None:
925             print "Testing that we can get at the configuration DN from the main search base on the GC port with the search_options control == 0"
926             
927             res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
928             self.assertTrue(len(res) > 0)
929
930             print "Testing that we do find configuration elements in the global catlog"
931             res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
932             self.assertTrue(len(res) > 0)
933         
934             print "Testing that we do find configuration elements and user elements at the same time"
935             res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
936             self.assertTrue(len(res) > 0)
937
938             print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
939             res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
940             self.assertTrue(len(res) > 0)
941
942         print "Testing that we can get at the configuration DN on the main LDAP port"
943         res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
944         self.assertTrue(len(res) > 0)
945
946         print "Testing objectCategory canonacolisation"
947         res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
948         self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
949         self.assertTrue(len(res) != 0)
950         
951         res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
952         self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
953         self.assertTrue(len(res) != 0)
954         
955         print "Testing objectClass attribute order on "+ self.base_dn
956         res = ldb.search(expression="objectClass=domain", base=self.base_dn, 
957                          scope=SCOPE_BASE, attrs=["objectClass"])
958         self.assertEquals(len(res), 1)
959
960         self.assertEquals(res[0]["objectClass"], ["top", "domain", "domainDNS"])
961
962     #  check enumeration
963
964         print "Testing ldb.search for objectCategory=person"
965         res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
966         self.assertTrue(len(res) > 0)
967
968         print "Testing ldb.search for objectCategory=person with domain scope control"
969         res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
970         self.assertTrue(len(res) > 0)
971      
972         print "Testing ldb.search for objectCategory=user"
973         res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
974         self.assertTrue(len(res) > 0)
975         
976         print "Testing ldb.search for objectCategory=user with domain scope control"
977         res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
978         self.assertTrue(len(res) > 0)
979         
980         print "Testing ldb.search for objectCategory=group"
981         res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
982         self.assertTrue(len(res) > 0)
983
984         print "Testing ldb.search for objectCategory=group with domain scope control"
985         res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
986         self.assertTrue(len(res) > 0)
987
988
989 class BaseDnTests(unittest.TestCase):
990     def setUp(self):
991         self.ldb = ldb
992
993     def test_rootdse_attrs(self):
994         """Testing for all rootDSE attributes"""
995         res = self.ldb.search(scope=SCOPE_BASE, attrs=[])
996         self.assertEquals(len(res), 1)
997
998     def test_highestcommittedusn(self):
999         """Testing for highestCommittedUSN"""
1000         res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
1001         self.assertEquals(len(res), 1)
1002         self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
1003
1004     def test_netlogon(self):
1005         """Testing for netlogon via LDAP"""
1006         res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
1007         self.assertEquals(len(res), 0)
1008
1009     def test_netlogon_highestcommitted_usn(self):
1010         """Testing for netlogon and highestCommittedUSN via LDAP"""
1011         res = self.ldb.search("", scope=SCOPE_BASE, 
1012                 attrs=["netlogon", "highestCommittedUSN"])
1013         self.assertEquals(len(res), 0)
1014
1015 class SchemaTests(unittest.TestCase):
1016     def find_schemadn(self, ldb):
1017         res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
1018         self.assertEquals(len(res), 1)
1019         return res[0]["schemaNamingContext"][0]
1020
1021     def setUp(self):
1022         self.ldb = ldb
1023         self.schema_dn = self.find_schemadn(ldb)
1024
1025     def test_generated_schema(self):
1026         """Testing we can read the generated schema via LDAP"""
1027         res = self.ldb.search("cn=aggregate,"+self.schema_dn, scope=SCOPE_BASE, 
1028                 attrs=["objectClasses", "attributeTypes", "dITContentRules"])
1029         self.assertEquals(len(res), 1)
1030         self.assertTrue("dITContentRules" in res[0])
1031         self.assertTrue("objectClasses" in res[0])
1032         self.assertTrue("attributeTypes" in res[0])
1033
1034     def test_generated_schema_is_operational(self):
1035         """Testing we don't get the generated schema via LDAP by default"""
1036         res = self.ldb.search("cn=aggregate,"+self.schema_dn, scope=SCOPE_BASE, 
1037                 attrs=["*"])
1038         self.assertEquals(len(res), 1)
1039         self.assertFalse("dITContentRules" in res[0])
1040         self.assertFalse("objectClasses" in res[0])
1041         self.assertFalse("attributeTypes" in res[0])
1042  
1043 if not "://" in host:
1044     host = "ldap://%s" % host
1045
1046 ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
1047 gc_ldb = Ldb("%s:3268" % host, credentials=creds, 
1048              session_info=system_session(), lp=lp)
1049
1050 runner = SubunitTestRunner()
1051 rc = 0
1052 if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
1053     rc = 1
1054 if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():
1055     rc = 1
1056 if not runner.run(unittest.makeSuite(SchemaTests)).wasSuccessful():
1057     rc = 1
1058 sys.exit(rc)