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