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