1 | #!/usr/bin/python
|
---|
2 |
|
---|
3 |
|
---|
4 | import optparse
|
---|
5 | import sys
|
---|
6 | import base64
|
---|
7 |
|
---|
8 | sys.path.insert(0, "bin/python")
|
---|
9 |
|
---|
10 | import samba.getopt as options
|
---|
11 | from samba.dcerpc import drsblobs, misc
|
---|
12 | from samba.ndr import ndr_pack, ndr_unpack
|
---|
13 | from samba import Ldb
|
---|
14 |
|
---|
15 | parser = optparse.OptionParser("get-descriptor [options]")
|
---|
16 | sambaopts = options.SambaOptions(parser)
|
---|
17 | credopts = options.CredentialsOptions(parser)
|
---|
18 | parser.add_option_group(credopts)
|
---|
19 |
|
---|
20 | parser.add_option("-b", type="string", metavar="BASE",
|
---|
21 | help="set base DN for the search")
|
---|
22 | parser.add_option("--host", type="string", metavar="HOST",
|
---|
23 | help="Ip of the host")
|
---|
24 |
|
---|
25 | lp = sambaopts.get_loadparm()
|
---|
26 | creds = credopts.get_credentials(lp)
|
---|
27 |
|
---|
28 | opts = parser.parse_args()[0]
|
---|
29 |
|
---|
30 | def printdirsync(ctl):
|
---|
31 | arr = ctl.split(':')
|
---|
32 | if arr[0] == 'dirsync':
|
---|
33 | print "Need to continue: %s" % arr[1]
|
---|
34 | cookie = ndr_unpack(drsblobs.ldapControlDirSyncCookie, base64.b64decode(arr[3]))
|
---|
35 | print "DC's NTDS guid: %s " % cookie.blob.guid1
|
---|
36 | print "highest usn %s" % cookie.blob.highwatermark.highest_usn
|
---|
37 | print "tmp higest usn %s" % cookie.blob.highwatermark.tmp_highest_usn
|
---|
38 | print "reserved usn %s" % cookie.blob.highwatermark.reserved_usn
|
---|
39 | if cookie.blob.extra_length >0:
|
---|
40 | print "highest usn in extra %s" % cookie.blob.extra.ctr.cursors[0].highest_usn
|
---|
41 | return cookie
|
---|
42 |
|
---|
43 | remote_ldb= Ldb("ldap://" + opts.host + ":389", credentials=creds, lp=lp)
|
---|
44 | tab = []
|
---|
45 | if opts.b:
|
---|
46 | base = opts.b
|
---|
47 | else:
|
---|
48 | base = None
|
---|
49 |
|
---|
50 | guid = None
|
---|
51 | (msgs, ctrls) = remote_ldb.search(expression="(samaccountname=administrator)", base=base, attrs=["objectClass"], controls=["dirsync:1:1:50"])
|
---|
52 | if (len(ctrls)):
|
---|
53 | for ctl in ctrls:
|
---|
54 | arr = ctl.split(':')
|
---|
55 | if arr[0] == 'dirsync':
|
---|
56 | cookie = ndr_unpack(drsblobs.ldapControlDirSyncCookie, base64.b64decode(arr[3]))
|
---|
57 | guid = cookie.blob.guid1
|
---|
58 | pass
|
---|
59 | if not guid:
|
---|
60 | print "No dirsync control ... strange"
|
---|
61 | sys.exit(1)
|
---|
62 |
|
---|
63 | print ""
|
---|
64 | print "Getting first guest without any cookie"
|
---|
65 | (msgs, ctrls) = remote_ldb.searchex(expression="(samaccountname=guest)", base=base, attrs=["objectClass"], controls=["dirsync:1:1:50"])
|
---|
66 | cookie = None
|
---|
67 | if (len(ctrls)):
|
---|
68 | for ctl in ctrls:
|
---|
69 | cookie = printdirsync(ctl)
|
---|
70 | print "Returned %d entries" % len(msgs)
|
---|
71 |
|
---|
72 | savedcookie = cookie
|
---|
73 |
|
---|
74 | print ""
|
---|
75 | print "Getting allusers with cookie"
|
---|
76 | controls=["dirsync:1:1:50:%s" % base64.b64encode(ndr_pack(cookie))]
|
---|
77 | (msgs, ctrls) = remote_ldb.searchex(expression="(samaccountname=*)", base=base, attrs=["objectClass"], controls=controls)
|
---|
78 | if (len(ctrls)):
|
---|
79 | for ctl in ctrls:
|
---|
80 | cookie = printdirsync(ctl)
|
---|
81 | print "Returned %d entries" % len(msgs)
|
---|
82 |
|
---|
83 | cookie = savedcookie
|
---|
84 | cookie.blob.guid1 = misc.GUID("128a99bf-e2df-4832-ac0a-1fb625e530db")
|
---|
85 | if cookie.blob.extra_length > 0:
|
---|
86 | cookie.blob.extra.ctr.cursors[0].source_dsa_invocation_id = misc.GUID("128a99bf-e2df-4832-ac0a-1fb625e530db")
|
---|
87 |
|
---|
88 | print ""
|
---|
89 | print "Getting all the entries"
|
---|
90 | controls=["dirsync:1:1:50:%s" % base64.b64encode(ndr_pack(cookie))]
|
---|
91 | (msgs, ctrls) = remote_ldb.searchex(expression="(objectclass=*)", base=base, controls=controls)
|
---|
92 | cont = 0
|
---|
93 | if (len(ctrls)):
|
---|
94 | for ctl in ctrls:
|
---|
95 | cookie = printdirsync(ctl)
|
---|
96 | if cookie != None:
|
---|
97 | cont = (ctl.split(':'))[1]
|
---|
98 | print "Returned %d entries" % len(msgs)
|
---|
99 |
|
---|
100 | usn = cookie.blob.highwatermark.tmp_highest_usn
|
---|
101 | if cookie.blob.extra_length > 0:
|
---|
102 | bigusn = cookie.blob.extra.ctr.cursors[0].highest_usn
|
---|
103 | else:
|
---|
104 | bigusn = usn + 1000
|
---|
105 | while (cont == "1"):
|
---|
106 | print ""
|
---|
107 | controls=["dirsync:1:1:50:%s" % base64.b64encode(ndr_pack(cookie))]
|
---|
108 | (msgs, ctrls) = remote_ldb.searchex(expression="(objectclass=*)", base=base, controls=controls)
|
---|
109 | if (len(ctrls)):
|
---|
110 | for ctl in ctrls:
|
---|
111 | cookie = printdirsync(ctl)
|
---|
112 | if cookie != None:
|
---|
113 | cont = (ctl.split(':'))[1]
|
---|
114 | print "Returned %d entries" % len(msgs)
|
---|
115 |
|
---|
116 | print ""
|
---|
117 | print "Getting with cookie but usn changed to %d we should use the one in extra" % (bigusn - 1)
|
---|
118 | cookie.blob.highwatermark.highest_usn = 0
|
---|
119 | cookie.blob.highwatermark.tmp_highest_usn = usn - 2
|
---|
120 | if cookie.blob.extra_length > 0:
|
---|
121 | print "here"
|
---|
122 | cookie.blob.extra.ctr.cursors[0].highest_usn = bigusn - 1
|
---|
123 | controls=["dirsync:1:1:50:%s" % base64.b64encode(ndr_pack(cookie))]
|
---|
124 | (msgs, ctrls) = remote_ldb.searchex(expression="(objectclass=*)", base=base, controls=controls)
|
---|
125 | if (len(ctrls)):
|
---|
126 | for ctl in ctrls:
|
---|
127 | cookie = printdirsync(ctl)
|
---|
128 | print "Returned %d entries" % len(msgs)
|
---|
129 |
|
---|
130 | print ""
|
---|
131 | print "Getting with cookie but usn %d changed and extra/cursor GUID too" % (usn - 2)
|
---|
132 | print " so that it's (tmp)highest_usn that drives the limit"
|
---|
133 | cookie.blob.highwatermark.highest_usn = 0
|
---|
134 | cookie.blob.highwatermark.tmp_highest_usn = usn - 2
|
---|
135 | if cookie.blob.extra_length > 0:
|
---|
136 | cookie.blob.extra.ctr.cursors[0].source_dsa_invocation_id = misc.GUID("128a99bf-e2df-4832-ac0a-1fb625e530db")
|
---|
137 | cookie.blob.extra.ctr.cursors[0].highest_usn = bigusn - 1
|
---|
138 | controls=["dirsync:1:1:50:%s" % base64.b64encode(ndr_pack(cookie))]
|
---|
139 | (msgs, ctrls) = remote_ldb.searchex(expression="(objectclass=*)", base=base, controls=controls)
|
---|
140 | if (len(ctrls)):
|
---|
141 | for ctl in ctrls:
|
---|
142 | cookie = printdirsync(ctl)
|
---|
143 | print "Returned %d entries" % len(msgs)
|
---|
144 |
|
---|
145 | print ""
|
---|
146 | print "Getting with cookie but usn changed to %d" % (usn - 2)
|
---|
147 | cookie.blob.highwatermark.highest_usn = 0
|
---|
148 | cookie.blob.highwatermark.tmp_highest_usn = (usn - 2)
|
---|
149 | if cookie.blob.extra_length > 0:
|
---|
150 | cookie.blob.extra.ctr.cursors[0].highest_usn = (usn - 2)
|
---|
151 | controls=["dirsync:1:1:50:%s" % base64.b64encode(ndr_pack(cookie))]
|
---|
152 | (msgs, ctrls) = remote_ldb.searchex(expression="(objectclass=*)", base=base, controls=controls)
|
---|
153 | if (len(ctrls)):
|
---|
154 | for ctl in ctrls:
|
---|
155 | cookie = printdirsync(ctl)
|
---|
156 | print "Returned %d entries" % len(msgs)
|
---|