1 # -*- coding: utf-8 -*-
3 # Unix SMB/CIFS implementation.
4 # Copyright © Jelmer Vernooij <jelmer@samba.org> 2008
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 """Tests for samba.dcerpc.sam."""
22 from samba.dcerpc import samr, security, lsa
23 from samba.dcerpc.samr import DomainGeneralInformation
24 from samba.tests import RpcInterfaceTestCase
25 from samba.tests import env_loadparm, delete_force
27 from samba.credentials import Credentials
28 from samba.auth import system_session
29 from samba.samdb import SamDB
30 from samba.dsdb import (
32 ATYPE_WORKSTATION_TRUST,
33 GTYPE_SECURITY_UNIVERSAL_GROUP,
34 GTYPE_SECURITY_GLOBAL_GROUP)
35 from samba import generate_random_password
36 from samba.ndr import ndr_unpack
40 # FIXME: Pidl should be doing this for us
41 def toArray(handle, array, num_entries):
42 return [(entry.idx, entry.name) for entry in array.entries[:num_entries]]
45 # Extract the rid from an ldb message, assumes that the message has a
49 sid = ndr_unpack(security.dom_sid, msg["objectSID"][0])
50 (_, rid) = sid.split()
54 # Calculate the request size for EnumDomainUsers and EnumDomainGroups calls
55 # to hold the specified number of entries.
56 # We use the w2k3 element size value of 54, code under test
57 # rounds this up i.e. (1+(max_size/SAMR_ENUM_USERS_MULTIPLIER))
59 def calc_max_size(num_entries):
60 return (num_entries - 1) * 54
63 class SamrTests(RpcInterfaceTestCase):
67 self.conn = samr.samr("ncalrpc:", self.get_loadparm())
69 self.open_domain_handle()
72 # Open the samba database
75 self.lp = env_loadparm()
76 self.domain = os.environ["DOMAIN"]
77 self.creds = Credentials()
78 self.creds.guess(self.lp)
79 self.session = system_session()
81 session_info=self.session, credentials=self.creds, lp=self.lp)
84 # Open a SAMR Domain handle
85 def open_domain_handle(self):
86 self.handle = self.conn.Connect2(
87 None, security.SEC_FLAG_MAXIMUM_ALLOWED)
89 self.domain_sid = self.conn.LookupDomain(
90 self.handle, lsa.String(self.domain))
92 self.domain_handle = self.conn.OpenDomain(
93 self.handle, security.SEC_FLAG_MAXIMUM_ALLOWED, self.domain_sid)
95 # Filter a list of records, removing those that are not part of the
98 def filter_domain(self, unfiltered):
100 sid = ndr_unpack(security.dom_sid, msg["objectSID"][0])
104 dom_sid = security.dom_sid(self.samdb.get_domain_sid())
105 return [x for x in unfiltered if sid(x) == dom_sid]
107 def test_connect5(self):
108 (level, info, handle) =\
109 self.conn.Connect5(None, 0, 1, samr.ConnectInfo1())
111 def test_connect2(self):
112 handle = self.conn.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED)
113 self.assertTrue(handle is not None)
115 def test_EnumDomains(self):
116 handle = self.conn.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED)
117 toArray(*self.conn.EnumDomains(handle, 0, 4294967295))
118 self.conn.Close(handle)
120 # Create groups based on the id list supplied, the id is used to
121 # form a unique name and description.
123 # returns a list of the created dn's, which can be passed to delete_dns
124 # to clean up after the test has run.
125 def create_groups(self, ids):
128 name = "SAMR_GRP%d" % i
129 dn = "cn=%s,cn=Users,%s" % (name, self.samdb.domain_dn())
130 delete_force(self.samdb, dn)
132 self.samdb.newgroup(name)
136 # Create user accounts based on the id list supplied, the id is used to
137 # form a unique name and description.
139 # returns a list of the created dn's, which can be passed to delete_dns
140 # to clean up after the test has run.
141 def create_users(self, ids):
144 name = "SAMR_USER%d" % i
145 dn = "cn=%s,CN=USERS,%s" % (name, self.samdb.domain_dn())
146 delete_force(self.samdb, dn)
148 # We only need the user to exist, we don't need a password
153 description="Description for " + name,
154 givenname="given%dname" % i,
155 surname="surname%d" % i)
159 # Create computer accounts based on the id list supplied, the id is used to
160 # form a unique name and description.
162 # returns a list of the created dn's, which can be passed to delete_dns
163 # to clean up after the test has run.
164 def create_computers(self, ids):
167 name = "SAMR_CMP%d" % i
168 dn = "cn=%s,cn=COMPUTERS,%s" % (name, self.samdb.domain_dn())
169 delete_force(self.samdb, dn)
171 self.samdb.newcomputer(name, description="Description of " + name)
175 # Delete the specified dn's.
177 # Used to clean up entries created by individual tests.
179 def delete_dns(self, dns):
181 delete_force(self.samdb, dn)
183 # Common tests for QueryDisplayInfo
185 def _test_QueryDisplayInfo(
186 self, level, check_results, select, attributes, add_elements):
188 # Get the expected results by querying the samdb database directly.
189 # We do this rather than use a list of expected results as this runs
190 # with other tests so we do not have a known fixed list of elements
191 expected = self.samdb.search(expression=select, attrs=attributes)
192 self.assertTrue(len(expected) > 0)
195 # Perform QueryDisplayInfo with max results greater than the expected
197 (ts, rs, actual) = self.conn.QueryDisplayInfo(
198 self.domain_handle, level, 0, 1024, 4294967295)
200 self.assertEqual(len(expected), ts)
201 self.assertEqual(len(expected), rs)
202 check_results(expected, actual.entries)
205 # Perform QueryDisplayInfo with max results set to the number of
206 # results returned from the first query, should return the same results
207 (ts1, rs1, actual1) = self.conn.QueryDisplayInfo(
208 self.domain_handle, level, 0, rs, 4294967295)
209 self.assertEqual(ts, ts1)
210 self.assertEqual(rs, rs1)
211 check_results(expected, actual1.entries)
214 # Perform QueryDisplayInfo and get the last two results.
215 # Note: We are assuming there are at least three entries
216 self.assertTrue(ts > 2)
217 (ts2, rs2, actual2) = self.conn.QueryDisplayInfo(
218 self.domain_handle, level, (ts - 2), 2, 4294967295)
219 self.assertEqual(ts, ts2)
220 self.assertEqual(2, rs2)
221 check_results(list(expected)[-2:], actual2.entries)
224 # Perform QueryDisplayInfo and get the first two results.
225 # Note: We are assuming there are at least three entries
226 self.assertTrue(ts > 2)
227 (ts2, rs2, actual2) = self.conn.QueryDisplayInfo(
228 self.domain_handle, level, 0, 2, 4294967295)
229 self.assertEqual(ts, ts2)
230 self.assertEqual(2, rs2)
231 check_results(list(expected)[:2], actual2.entries)
234 # Perform QueryDisplayInfo and get two results in the middle of the
235 # list i.e. not the first or the last entry.
236 # Note: We are assuming there are at least four entries
237 self.assertTrue(ts > 3)
238 (ts2, rs2, actual2) = self.conn.QueryDisplayInfo(
239 self.domain_handle, level, 1, 2, 4294967295)
240 self.assertEqual(ts, ts2)
241 self.assertEqual(2, rs2)
242 check_results(list(expected)[1:2], actual2.entries)
245 # To check that cached values are being returned rather than the
246 # results being re-read from disk we add elements, and request all
247 # but the first result.
249 dns = add_elements([1000, 1002, 1003, 1004])
252 # Perform QueryDisplayInfo and get all but the first result.
253 # We should be using the cached results so the entries we just added
254 # should not be present
255 (ts3, rs3, actual3) = self.conn.QueryDisplayInfo(
256 self.domain_handle, level, 1, 1024, 4294967295)
257 self.assertEqual(ts, ts3)
258 self.assertEqual(len(expected) - 1, rs3)
259 check_results(list(expected)[1:], actual3.entries)
262 # Perform QueryDisplayInfo and get all the results.
263 # As the start index is zero we should reread the data from disk and
264 # the added entries should be there
265 new = self.samdb.search(expression=select, attrs=attributes)
266 (ts4, rs4, actual4) = self.conn.QueryDisplayInfo(
267 self.domain_handle, level, 0, 1024, 4294967295)
268 self.assertEqual(len(expected) + len(dns), ts4)
269 self.assertEqual(len(expected) + len(dns), rs4)
270 check_results(new, actual4.entries)
272 # Delete the added DN's and query all but the first entry.
273 # This should ensure the cached results are used and that the
274 # missing entry code is triggered.
276 (ts5, rs5, actual5) = self.conn.QueryDisplayInfo(
277 self.domain_handle, level, 1, 1024, 4294967295)
278 self.assertEqual(len(expected) + len(dns), ts5)
279 # The deleted results will be filtered from the result set so should
280 # be missing from the returned results.
281 # Note: depending on the GUID order, the first result in the cache may
282 # be a deleted entry, in which case the results will contain all
283 # the expected elements, otherwise the first expected result will
285 if rs5 == len(expected):
286 check_results(expected, actual5.entries)
287 elif rs5 == (len(expected) - 1):
288 check_results(list(expected)[1:], actual5.entries)
290 self.fail("Incorrect number of entries {0}".format(rs5))
293 # Perform QueryDisplayInfo specifying an index past the end of the
295 # Should return no data.
296 (ts6, rs6, actual6) = self.conn.QueryDisplayInfo(
297 self.domain_handle, level, ts5, 1, 4294967295)
298 self.assertEqual(ts5, ts6)
299 self.assertEqual(0, rs6)
301 self.conn.Close(self.handle)
303 # Test for QueryDisplayInfo, Level 1
304 # Returns the sAMAccountName, displayName and description for all
307 def test_QueryDisplayInfo_level_1(self):
308 def check_results(expected, actual):
309 # Assume the QueryDisplayInfo and ldb.search return their results
311 for (e, a) in zip(expected, actual):
312 self.assertTrue(isinstance(a, samr.DispEntryGeneral))
313 self.assertEqual(str(e["sAMAccountName"]),
316 # The displayName and description are optional.
317 # In the expected results they will be missing, in
318 # samr.DispEntryGeneral the corresponding attribute will have a
321 if a.full_name.length == 0:
322 self.assertFalse("displayName" in e)
324 self.assertEqual(str(e["displayName"]), str(a.full_name))
326 if a.description.length == 0:
327 self.assertFalse("description" in e)
329 self.assertEqual(str(e["description"]),
331 # Create four user accounts
332 # to ensure that we have the minimum needed for the tests.
333 dns = self.create_users([1, 2, 3, 4])
335 select = "(&(objectclass=user)(sAMAccountType={0}))".format(
336 ATYPE_NORMAL_ACCOUNT)
337 attributes = ["sAMAccountName", "displayName", "description"]
338 self._test_QueryDisplayInfo(
339 1, check_results, select, attributes, self.create_users)
343 # Test for QueryDisplayInfo, Level 2
344 # Returns the sAMAccountName and description for all
345 # the computer accounts.
347 def test_QueryDisplayInfo_level_2(self):
348 def check_results(expected, actual):
349 # Assume the QueryDisplayInfo and ldb.search return their results
351 for (e, a) in zip(expected, actual):
352 self.assertTrue(isinstance(a, samr.DispEntryFull))
353 self.assertEqual(str(e["sAMAccountName"]),
356 # The description is optional.
357 # In the expected results they will be missing, in
358 # samr.DispEntryGeneral the corresponding attribute will have a
361 if a.description.length == 0:
362 self.assertFalse("description" in e)
364 self.assertEqual(str(e["description"]),
367 # Create four computer accounts
368 # to ensure that we have the minimum needed for the tests.
369 dns = self.create_computers([1, 2, 3, 4])
371 select = "(&(objectclass=user)(sAMAccountType={0}))".format(
372 ATYPE_WORKSTATION_TRUST)
373 attributes = ["sAMAccountName", "description"]
374 self._test_QueryDisplayInfo(
375 2, check_results, select, attributes, self.create_computers)
379 # Test for QueryDisplayInfo, Level 3
380 # Returns the sAMAccountName and description for all
383 def test_QueryDisplayInfo_level_3(self):
384 def check_results(expected, actual):
385 # Assume the QueryDisplayInfo and ldb.search return their results
387 for (e, a) in zip(expected, actual):
388 self.assertTrue(isinstance(a, samr.DispEntryFullGroup))
389 self.assertEqual(str(e["sAMAccountName"]),
392 # The description is optional.
393 # In the expected results they will be missing, in
394 # samr.DispEntryGeneral the corresponding attribute will have a
397 if a.description.length == 0:
398 self.assertFalse("description" in e)
400 self.assertEqual(str(e["description"]),
404 # to ensure that we have the minimum needed for the tests.
405 dns = self.create_groups([1, 2, 3, 4])
407 select = "(&(|(groupType=%d)(groupType=%d))(objectClass=group))" % (
408 GTYPE_SECURITY_UNIVERSAL_GROUP,
409 GTYPE_SECURITY_GLOBAL_GROUP)
410 attributes = ["sAMAccountName", "description"]
411 self._test_QueryDisplayInfo(
412 3, check_results, select, attributes, self.create_groups)
416 # Test for QueryDisplayInfo, Level 4
417 # Returns the sAMAccountName (as an ASCII string)
418 # for all the user accounts.
420 def test_QueryDisplayInfo_level_4(self):
421 def check_results(expected, actual):
422 # Assume the QueryDisplayInfo and ldb.search return their results
424 for (e, a) in zip(expected, actual):
425 self.assertTrue(isinstance(a, samr.DispEntryAscii))
427 isinstance(a.account_name, lsa.AsciiStringLarge))
429 str(e["sAMAccountName"]), str(a.account_name.string))
431 # Create four user accounts
432 # to ensure that we have the minimum needed for the tests.
433 dns = self.create_users([1, 2, 3, 4])
435 select = "(&(objectclass=user)(sAMAccountType={0}))".format(
436 ATYPE_NORMAL_ACCOUNT)
437 attributes = ["sAMAccountName", "displayName", "description"]
438 self._test_QueryDisplayInfo(
439 4, check_results, select, attributes, self.create_users)
443 # Test for QueryDisplayInfo, Level 5
444 # Returns the sAMAccountName (as an ASCII string)
445 # for all the groups.
447 def test_QueryDisplayInfo_level_5(self):
448 def check_results(expected, actual):
449 # Assume the QueryDisplayInfo and ldb.search return their results
451 for (e, a) in zip(expected, actual):
452 self.assertTrue(isinstance(a, samr.DispEntryAscii))
454 isinstance(a.account_name, lsa.AsciiStringLarge))
456 str(e["sAMAccountName"]), str(a.account_name.string))
459 # to ensure that we have the minimum needed for the tests.
460 dns = self.create_groups([1, 2, 3, 4])
462 select = "(&(|(groupType=%d)(groupType=%d))(objectClass=group))" % (
463 GTYPE_SECURITY_UNIVERSAL_GROUP,
464 GTYPE_SECURITY_GLOBAL_GROUP)
465 attributes = ["sAMAccountName", "description"]
466 self._test_QueryDisplayInfo(
467 5, check_results, select, attributes, self.create_groups)
471 def test_EnumDomainGroups(self):
472 def check_results(expected, actual):
473 for (e, a) in zip(expected, actual):
474 self.assertTrue(isinstance(a, samr.SamEntry))
476 str(e["sAMAccountName"]), str(a.name.string))
479 # to ensure that we have the minimum needed for the tests.
480 dns = self.create_groups([1, 2, 3, 4])
483 # Get the expected results by querying the samdb database directly.
484 # We do this rather than use a list of expected results as this runs
485 # with other tests so we do not have a known fixed list of elements
486 select = "(&(|(groupType=%d)(groupType=%d))(objectClass=group))" % (
487 GTYPE_SECURITY_UNIVERSAL_GROUP,
488 GTYPE_SECURITY_GLOBAL_GROUP)
489 attributes = ["sAMAccountName", "objectSID"]
490 unfiltered = self.samdb.search(expression=select, attrs=attributes)
491 filtered = self.filter_domain(unfiltered)
492 self.assertTrue(len(filtered) > 4)
494 # Sort the expected results by rid
495 expected = sorted(list(filtered), key=rid)
498 # Perform EnumDomainGroups with max size greater than the expected
499 # number of results. Allow for an extra 10 entries
501 max_size = calc_max_size(len(expected) + 10)
502 (resume_handle, actual, num_entries) = self.conn.EnumDomainGroups(
503 self.domain_handle, 0, max_size)
504 self.assertEqual(len(expected), num_entries)
505 check_results(expected, actual.entries)
508 # Perform EnumDomainGroups with size set to so that it contains
511 max_size = calc_max_size(4)
512 (resume_handle, actual, num_entries) = self.conn.EnumDomainGroups(
513 self.domain_handle, 0, max_size)
514 self.assertEqual(4, num_entries)
515 check_results(expected[:4], actual.entries)
518 # Try calling with resume_handle greater than number of entries
519 # Should return no results and a resume handle of 0
520 max_size = calc_max_size(1)
522 self.conn.Close(self.handle)
523 (resume_handle, a, num_entries) = self.conn.EnumDomainGroups(
524 self.domain_handle, rh, max_size)
526 self.assertEqual(0, num_entries)
527 self.assertEqual(0, resume_handle)
530 # Enumerate through the domain groups one element at a time.
532 max_size = calc_max_size(1)
534 (resume_handle, a, num_entries) = self.conn.EnumDomainGroups(
535 self.domain_handle, 0, max_size)
537 self.assertEqual(1, num_entries)
538 actual.append(a.entries[0])
539 (resume_handle, a, num_entries) = self.conn.EnumDomainGroups(
540 self.domain_handle, resume_handle, max_size)
542 actual.append(a.entries[0])
545 # Check that the cached results are being returned.
546 # Obtain a new resume_handle and insert new entries into the
550 max_size = calc_max_size(1)
551 (resume_handle, a, num_entries) = self.conn.EnumDomainGroups(
552 self.domain_handle, 0, max_size)
553 extra_dns = self.create_groups([1000, 1002, 1003, 1004])
555 self.assertEqual(1, num_entries)
556 actual.append(a.entries[0])
557 (resume_handle, a, num_entries) = self.conn.EnumDomainGroups(
558 self.domain_handle, resume_handle, max_size)
560 actual.append(a.entries[0])
562 self.assertEqual(len(expected), len(actual))
563 check_results(expected, actual)
566 # Perform EnumDomainGroups, we should read the newly added domains
568 max_size = calc_max_size(len(expected) + len(extra_dns) + 10)
569 (resume_handle, actual, num_entries) = self.conn.EnumDomainGroups(
570 self.domain_handle, 0, max_size)
571 self.assertEqual(len(expected) + len(extra_dns), num_entries)
574 # Get a new expected result set by querying the database directly
575 unfiltered01 = self.samdb.search(expression=select, attrs=attributes)
576 filtered01 = self.filter_domain(unfiltered01)
577 self.assertTrue(len(filtered01) > len(expected))
579 # Sort the expected results by rid
580 expected01 = sorted(list(filtered01), key=rid)
583 # Now check that we read the new entries.
585 check_results(expected01, actual.entries)
588 # Check that deleted results are handled correctly.
589 # Obtain a new resume_handle and delete entries from the DB.
592 max_size = calc_max_size(1)
593 (resume_handle, a, num_entries) = self.conn.EnumDomainGroups(
594 self.domain_handle, 0, max_size)
595 self.delete_dns(extra_dns)
596 while resume_handle and num_entries:
597 self.assertEqual(1, num_entries)
598 actual.append(a.entries[0])
599 (resume_handle, a, num_entries) = self.conn.EnumDomainGroups(
600 self.domain_handle, resume_handle, max_size)
602 actual.append(a.entries[0])
604 self.assertEqual(len(expected), len(actual))
605 check_results(expected, actual)
609 def test_EnumDomainUsers(self):
610 def check_results(expected, actual):
611 for (e, a) in zip(expected, actual):
612 self.assertTrue(isinstance(a, samr.SamEntry))
614 str(e["sAMAccountName"]), str(a.name.string))
617 # to ensure that we have the minimum needed for the tests.
618 dns = self.create_users([1, 2, 3, 4])
621 # Get the expected results by querying the samdb database directly.
622 # We do this rather than use a list of expected results as this runs
623 # with other tests so we do not have a known fixed list of elements
624 select = "(objectClass=user)"
625 attributes = ["sAMAccountName", "objectSID", "userAccountConrol"]
626 unfiltered = self.samdb.search(expression=select, attrs=attributes)
627 filtered = self.filter_domain(unfiltered)
628 self.assertTrue(len(filtered) > 4)
630 # Sort the expected results by rid
631 expected = sorted(list(filtered), key=rid)
634 # Perform EnumDomainUsers with max_size greater than required for the
635 # expected number of results. We should get all the results.
637 max_size = calc_max_size(len(expected) + 10)
638 (resume_handle, actual, num_entries) = self.conn.EnumDomainUsers(
639 self.domain_handle, 0, 0, max_size)
640 self.assertEqual(len(expected), num_entries)
641 check_results(expected, actual.entries)
644 # Perform EnumDomainUsers with size set to so that it contains
646 max_size = calc_max_size(4)
647 (resume_handle, actual, num_entries) = self.conn.EnumDomainUsers(
648 self.domain_handle, 0, 0, max_size)
649 self.assertEqual(4, num_entries)
650 check_results(expected[:4], actual.entries)
653 # Try calling with resume_handle greater than number of entries
654 # Should return no results and a resume handle of 0
656 max_size = calc_max_size(1)
657 self.conn.Close(self.handle)
658 (resume_handle, a, num_entries) = self.conn.EnumDomainUsers(
659 self.domain_handle, rh, 0, max_size)
661 self.assertEqual(0, num_entries)
662 self.assertEqual(0, resume_handle)
665 # Enumerate through the domain users one element at a time.
666 # We should get all the results.
669 max_size = calc_max_size(1)
670 (resume_handle, a, num_entries) = self.conn.EnumDomainUsers(
671 self.domain_handle, 0, 0, max_size)
673 self.assertEqual(1, num_entries)
674 actual.append(a.entries[0])
675 (resume_handle, a, num_entries) = self.conn.EnumDomainUsers(
676 self.domain_handle, resume_handle, 0, max_size)
678 actual.append(a.entries[0])
680 self.assertEqual(len(expected), len(actual))
681 check_results(expected, actual)
684 # Check that the cached results are being returned.
685 # Obtain a new resume_handle and insert new entries into the
686 # into the DB. As the entries were added after the results were cached
687 # they should not show up in the returned results.
690 max_size = calc_max_size(1)
691 (resume_handle, a, num_entries) = self.conn.EnumDomainUsers(
692 self.domain_handle, 0, 0, max_size)
693 extra_dns = self.create_users([1000, 1002, 1003, 1004])
695 self.assertEqual(1, num_entries)
696 actual.append(a.entries[0])
697 (resume_handle, a, num_entries) = self.conn.EnumDomainUsers(
698 self.domain_handle, resume_handle, 0, max_size)
700 actual.append(a.entries[0])
702 self.assertEqual(len(expected), len(actual))
703 check_results(expected, actual)
706 # Perform EnumDomainUsers, we should read the newly added groups
707 # As resume_handle is zero, the results will be read from disk.
709 max_size = calc_max_size(len(expected) + len(extra_dns) + 10)
710 (resume_handle, actual, num_entries) = self.conn.EnumDomainUsers(
711 self.domain_handle, 0, 0, max_size)
712 self.assertEqual(len(expected) + len(extra_dns), num_entries)
715 # Get a new expected result set by querying the database directly
716 unfiltered01 = self.samdb.search(expression=select, attrs=attributes)
717 filtered01 = self.filter_domain(unfiltered01)
718 self.assertTrue(len(filtered01) > len(expected))
720 # Sort the expected results by rid
721 expected01 = sorted(list(filtered01), key=rid)
724 # Now check that we read the new entries.
726 self.assertEqual(len(expected01), num_entries)
727 check_results(expected01, actual.entries)
729 self.delete_dns(dns + extra_dns)
731 def test_DomGeneralInformation_num_users(self):
732 info = self.conn.QueryDomainInfo(
733 self.domain_handle, DomainGeneralInformation)
735 # Enumerate through all the domain users and compare the number
736 # returned against QueryDomainInfo they should be the same
737 max_size = calc_max_size(1)
738 (resume_handle, a, num_entries) = self.conn.EnumDomainUsers(
739 self.domain_handle, 0, 0, max_size)
742 self.assertEqual(1, num_entries)
743 (resume_handle, a, num_entries) = self.conn.EnumDomainUsers(
744 self.domain_handle, resume_handle, 0, max_size)
747 self.assertEqual(count, info.num_users)
749 def test_DomGeneralInformation_num_groups(self):
750 info = self.conn.QueryDomainInfo(
751 self.domain_handle, DomainGeneralInformation)
753 # Enumerate through all the domain groups and compare the number
754 # returned against QueryDomainInfo they should be the same
755 max_size = calc_max_size(1)
756 (resume_handle, a, num_entries) = self.conn.EnumDomainGroups(
757 self.domain_handle, 0, max_size)
760 self.assertEqual(1, num_entries)
761 (resume_handle, a, num_entries) = self.conn.EnumDomainGroups(
762 self.domain_handle, resume_handle, max_size)
765 self.assertEqual(count, info.num_groups)
767 def test_DomGeneralInformation_num_aliases(self):
768 info = self.conn.QueryDomainInfo(
769 self.domain_handle, DomainGeneralInformation)
771 # Enumerate through all the domain aliases and compare the number
772 # returned against QueryDomainInfo they should be the same
773 max_size = calc_max_size(1)
774 (resume_handle, a, num_entries) = self.conn.EnumDomainAliases(
775 self.domain_handle, 0, max_size)
778 self.assertEqual(1, num_entries)
779 (resume_handle, a, num_entries) = self.conn.EnumDomainAliases(
780 self.domain_handle, resume_handle, max_size)
783 self.assertEqual(count, info.num_aliases)