7 sys
.path
.insert(0, "bin/python")
9 import samba
.getopt
as options
10 from samba
.dcerpc
import drsblobs
, misc
11 from samba
.ndr
import ndr_pack
, ndr_unpack
14 parser
= optparse
.OptionParser("demodirsync [options]")
15 sambaopts
= options
.SambaOptions(parser
)
16 credopts
= options
.CredentialsOptions(parser
)
17 parser
.add_option_group(credopts
)
19 parser
.add_option("-b", type="string", metavar
="BASE",
20 help="set base DN for the search")
21 parser
.add_option("--host", type="string", metavar
="HOST",
22 help="Ip of the host")
24 lp
= sambaopts
.get_loadparm()
25 creds
= credopts
.get_credentials(lp
)
27 opts
= parser
.parse_args()[0]
30 print("Usage: demodirsync.py --host HOST [-b BASE]")
33 def printdirsync(ctl
):
35 if arr
[0] == 'dirsync':
36 print("Need to continue: %s" % arr
[1])
37 cookie
= ndr_unpack(drsblobs
.ldapControlDirSyncCookie
, base64
.b64decode(arr
[3]))
38 print("DC's NTDS guid: %s " % cookie
.blob
.guid1
)
39 print("highest usn %s" % cookie
.blob
.highwatermark
.highest_usn
)
40 print("tmp highest usn %s" % cookie
.blob
.highwatermark
.tmp_highest_usn
)
41 print("reserved usn %s" % cookie
.blob
.highwatermark
.reserved_usn
)
42 if cookie
.blob
.extra_length
> 0:
43 print("highest usn in extra %s" % cookie
.blob
.extra
.ctr
.cursors
[0].highest_usn
)
47 remote_ldb
= Ldb("ldap://" + opts
.host
+ ":389", credentials
=creds
, lp
=lp
)
55 (msgs
, ctrls
) = remote_ldb
.search(expression
="(samaccountname=administrator)", base
=base
, attrs
=["objectClass"], controls
=["dirsync:1:1:50"])
59 if arr
[0] == 'dirsync':
60 cookie
= ndr_unpack(drsblobs
.ldapControlDirSyncCookie
, base64
.b64decode(arr
[3]))
61 guid
= cookie
.blob
.guid1
63 print("No dirsync control ... strange")
67 print("Getting first guest without any cookie")
68 (msgs
, ctrls
) = remote_ldb
.searchex(expression
="(samaccountname=guest)", base
=base
, attrs
=["objectClass"], controls
=["dirsync:1:1:50"])
72 cookie
= printdirsync(ctl
)
73 print("Returned %d entries" % len(msgs
))
78 print("Getting allusers with cookie")
79 controls
= ["dirsync:1:1:50:%s" % base64
.b64encode(ndr_pack(cookie
)).decode('utf8')]
80 (msgs
, ctrls
) = remote_ldb
.searchex(expression
="(samaccountname=*)", base
=base
, attrs
=["objectClass"], controls
=controls
)
84 print("Returned %d entries" % len(msgs
))
87 cookie
.blob
.guid1
= misc
.GUID("128a99bf-e2df-4832-ac0a-1fb625e530db")
88 if cookie
.blob
.extra_length
> 0:
89 cookie
.blob
.extra
.ctr
.cursors
[0].source_dsa_invocation_id
= misc
.GUID("128a99bf-e2df-4832-ac0a-1fb625e530db")
92 print("Getting all the entries")
93 controls
= ["dirsync:1:1:50:%s" % base64
.b64encode(ndr_pack(cookie
)).decode('utf8')]
94 (msgs
, ctrls
) = remote_ldb
.searchex(expression
="(objectclass=*)", base
=base
, controls
=controls
)
98 cookie
= printdirsync(ctl
)
99 if cookie
is not None:
100 cont
= (ctl
.split(':'))[1]
101 print("Returned %d entries" % len(msgs
))
103 usn
= cookie
.blob
.highwatermark
.tmp_highest_usn
104 if cookie
.blob
.extra_length
> 0:
105 bigusn
= cookie
.blob
.extra
.ctr
.cursors
[0].highest_usn
110 controls
= ["dirsync:1:1:50:%s" % base64
.b64encode(ndr_pack(cookie
)).decode('utf8')]
111 (msgs
, ctrls
) = remote_ldb
.searchex(expression
="(objectclass=*)", base
=base
, controls
=controls
)
114 cookie
= printdirsync(ctl
)
115 if cookie
is not None:
116 cont
= (ctl
.split(':'))[1]
117 print("Returned %d entries" % len(msgs
))
120 print("Getting with cookie but usn changed to %d we should use the one in extra" % (bigusn
- 1))
121 cookie
.blob
.highwatermark
.highest_usn
= 0
122 cookie
.blob
.highwatermark
.tmp_highest_usn
= usn
- 2
123 if cookie
.blob
.extra_length
> 0:
125 cookie
.blob
.extra
.ctr
.cursors
[0].highest_usn
= bigusn
- 1
126 controls
= ["dirsync:1:1:50:%s" % base64
.b64encode(ndr_pack(cookie
)).decode('utf8')]
127 (msgs
, ctrls
) = remote_ldb
.searchex(expression
="(objectclass=*)", base
=base
, controls
=controls
)
130 cookie
= printdirsync(ctl
)
131 print("Returned %d entries" % len(msgs
))
134 print("Getting with cookie but usn %d changed and extra/cursor GUID too" % (usn
- 2))
135 print(" so that it's (tmp)highest_usn that drives the limit")
136 cookie
.blob
.highwatermark
.highest_usn
= 0
137 cookie
.blob
.highwatermark
.tmp_highest_usn
= usn
- 2
138 if cookie
.blob
.extra_length
> 0:
139 cookie
.blob
.extra
.ctr
.cursors
[0].source_dsa_invocation_id
= misc
.GUID("128a99bf-e2df-4832-ac0a-1fb625e530db")
140 cookie
.blob
.extra
.ctr
.cursors
[0].highest_usn
= bigusn
- 1
141 controls
= ["dirsync:1:1:50:%s" % base64
.b64encode(ndr_pack(cookie
)).decode('utf8')]
142 (msgs
, ctrls
) = remote_ldb
.searchex(expression
="(objectclass=*)", base
=base
, controls
=controls
)
145 cookie
= printdirsync(ctl
)
146 print("Returned %d entries" % len(msgs
))
149 print("Getting with cookie but usn changed to %d" % (usn
- 2))
150 cookie
.blob
.highwatermark
.highest_usn
= 0
151 cookie
.blob
.highwatermark
.tmp_highest_usn
= (usn
- 2)
152 if cookie
.blob
.extra_length
> 0:
153 cookie
.blob
.extra
.ctr
.cursors
[0].highest_usn
= (usn
- 2)
154 controls
= ["dirsync:1:1:50:%s" % base64
.b64encode(ndr_pack(cookie
)).decode('utf8')]
155 (msgs
, ctrls
) = remote_ldb
.searchex(expression
="(objectclass=*)", base
=base
, controls
=controls
)
158 cookie
= printdirsync(ctl
)
159 print("Returned %d entries" % len(msgs
))