2011-02-07 09:55:26 +03:00
#!/usr/bin/python
import optparse
import sys
import base64
sys . path . insert ( 0 , " bin/python " )
import samba . getopt as options
from samba . dcerpc import drsblobs , misc
from samba . ndr import ndr_pack , ndr_unpack
from samba import Ldb
2021-05-11 11:21:21 +12:00
parser = optparse . OptionParser ( " demodirsync [options] " )
2011-02-07 09:55:26 +03:00
sambaopts = options . SambaOptions ( parser )
credopts = options . CredentialsOptions ( parser )
parser . add_option_group ( credopts )
parser . add_option ( " -b " , type = " string " , metavar = " BASE " ,
help = " set base DN for the search " )
parser . add_option ( " --host " , type = " string " , metavar = " HOST " ,
help = " Ip of the host " )
lp = sambaopts . get_loadparm ( )
creds = credopts . get_credentials ( lp )
opts = parser . parse_args ( ) [ 0 ]
2019-06-27 16:57:21 +12:00
if opts . host is None :
print ( " Usage: demodirsync.py --host HOST [-b BASE] " )
sys . exit ( 1 )
2018-07-30 18:20:39 +12:00
2011-02-07 09:55:26 +03:00
def printdirsync ( ctl ) :
arr = ctl . split ( ' : ' )
if arr [ 0 ] == ' dirsync ' :
2018-03-09 14:01:17 +00:00
print ( " Need to continue: %s " % arr [ 1 ] )
2011-02-07 09:55:26 +03:00
cookie = ndr_unpack ( drsblobs . ldapControlDirSyncCookie , base64 . b64decode ( arr [ 3 ] ) )
2018-03-09 14:01:17 +00:00
print ( " DC ' s NTDS guid: %s " % cookie . blob . guid1 )
print ( " highest usn %s " % cookie . blob . highwatermark . highest_usn )
2023-08-03 14:45:16 +02:00
print ( " tmp highest usn %s " % cookie . blob . highwatermark . tmp_highest_usn )
2018-03-09 14:01:17 +00:00
print ( " reserved usn %s " % cookie . blob . highwatermark . reserved_usn )
2018-07-30 18:18:03 +12:00
if cookie . blob . extra_length > 0 :
2018-03-09 14:01:17 +00:00
print ( " highest usn in extra %s " % cookie . blob . extra . ctr . cursors [ 0 ] . highest_usn )
2011-02-07 09:55:26 +03:00
return cookie
2018-07-30 18:21:29 +12:00
2018-07-30 18:18:03 +12:00
remote_ldb = Ldb ( " ldap:// " + opts . host + " :389 " , credentials = creds , lp = lp )
2011-02-07 09:55:26 +03:00
tab = [ ]
if opts . b :
base = opts . b
else :
base = None
guid = None
( msgs , ctrls ) = remote_ldb . search ( expression = " (samaccountname=administrator) " , base = base , attrs = [ " objectClass " ] , controls = [ " dirsync:1:1:50 " ] )
if ( len ( ctrls ) ) :
for ctl in ctrls :
arr = ctl . split ( ' : ' )
if arr [ 0 ] == ' dirsync ' :
cookie = ndr_unpack ( drsblobs . ldapControlDirSyncCookie , base64 . b64decode ( arr [ 3 ] ) )
guid = cookie . blob . guid1
if not guid :
2018-03-09 14:01:17 +00:00
print ( " No dirsync control ... strange " )
2011-02-07 09:55:26 +03:00
sys . exit ( 1 )
2018-03-09 14:01:17 +00:00
print ( " " )
print ( " Getting first guest without any cookie " )
2011-02-07 09:55:26 +03:00
( msgs , ctrls ) = remote_ldb . searchex ( expression = " (samaccountname=guest) " , base = base , attrs = [ " objectClass " ] , controls = [ " dirsync:1:1:50 " ] )
cookie = None
if ( len ( ctrls ) ) :
for ctl in ctrls :
cookie = printdirsync ( ctl )
2018-03-09 14:01:17 +00:00
print ( " Returned %d entries " % len ( msgs ) )
2011-02-07 09:55:26 +03:00
savedcookie = cookie
2018-03-09 14:01:17 +00:00
print ( " " )
print ( " Getting allusers with cookie " )
2018-07-30 18:18:03 +12:00
controls = [ " dirsync:1:1:50: %s " % base64 . b64encode ( ndr_pack ( cookie ) ) . decode ( ' utf8 ' ) ]
2011-02-07 09:55:26 +03:00
( msgs , ctrls ) = remote_ldb . searchex ( expression = " (samaccountname=*) " , base = base , attrs = [ " objectClass " ] , controls = controls )
if ( len ( ctrls ) ) :
for ctl in ctrls :
2022-05-05 21:32:13 +12:00
printdirsync ( ctl )
2018-03-09 14:01:17 +00:00
print ( " Returned %d entries " % len ( msgs ) )
2011-02-07 09:55:26 +03:00
cookie = savedcookie
cookie . blob . guid1 = misc . GUID ( " 128a99bf-e2df-4832-ac0a-1fb625e530db " )
if cookie . blob . extra_length > 0 :
cookie . blob . extra . ctr . cursors [ 0 ] . source_dsa_invocation_id = misc . GUID ( " 128a99bf-e2df-4832-ac0a-1fb625e530db " )
2018-03-09 14:01:17 +00:00
print ( " " )
print ( " Getting all the entries " )
2018-07-30 18:18:03 +12:00
controls = [ " dirsync:1:1:50: %s " % base64 . b64encode ( ndr_pack ( cookie ) ) . decode ( ' utf8 ' ) ]
2011-02-07 09:55:26 +03:00
( msgs , ctrls ) = remote_ldb . searchex ( expression = " (objectclass=*) " , base = base , controls = controls )
cont = 0
if ( len ( ctrls ) ) :
for ctl in ctrls :
cookie = printdirsync ( ctl )
2018-07-30 18:22:15 +12:00
if cookie is not None :
2011-02-07 09:55:26 +03:00
cont = ( ctl . split ( ' : ' ) ) [ 1 ]
2018-03-09 14:01:17 +00:00
print ( " Returned %d entries " % len ( msgs ) )
2011-02-07 09:55:26 +03:00
usn = cookie . blob . highwatermark . tmp_highest_usn
if cookie . blob . extra_length > 0 :
bigusn = cookie . blob . extra . ctr . cursors [ 0 ] . highest_usn
else :
bigusn = usn + 1000
while ( cont == " 1 " ) :
2018-03-09 14:01:17 +00:00
print ( " " )
2018-07-30 18:18:03 +12:00
controls = [ " dirsync:1:1:50: %s " % base64 . b64encode ( ndr_pack ( cookie ) ) . decode ( ' utf8 ' ) ]
2011-02-07 09:55:26 +03:00
( msgs , ctrls ) = remote_ldb . searchex ( expression = " (objectclass=*) " , base = base , controls = controls )
if ( len ( ctrls ) ) :
for ctl in ctrls :
cookie = printdirsync ( ctl )
2018-07-30 18:22:15 +12:00
if cookie is not None :
2011-02-07 09:55:26 +03:00
cont = ( ctl . split ( ' : ' ) ) [ 1 ]
2018-03-09 14:01:17 +00:00
print ( " Returned %d entries " % len ( msgs ) )
2011-02-07 09:55:26 +03:00
2018-03-09 14:01:17 +00:00
print ( " " )
print ( " Getting with cookie but usn changed to %d we should use the one in extra " % ( bigusn - 1 ) )
2011-02-07 09:55:26 +03:00
cookie . blob . highwatermark . highest_usn = 0
cookie . blob . highwatermark . tmp_highest_usn = usn - 2
if cookie . blob . extra_length > 0 :
2018-03-09 14:01:17 +00:00
print ( " here " )
2011-02-07 09:55:26 +03:00
cookie . blob . extra . ctr . cursors [ 0 ] . highest_usn = bigusn - 1
2018-07-30 18:18:03 +12:00
controls = [ " dirsync:1:1:50: %s " % base64 . b64encode ( ndr_pack ( cookie ) ) . decode ( ' utf8 ' ) ]
2011-02-07 09:55:26 +03:00
( msgs , ctrls ) = remote_ldb . searchex ( expression = " (objectclass=*) " , base = base , controls = controls )
if ( len ( ctrls ) ) :
for ctl in ctrls :
cookie = printdirsync ( ctl )
2018-03-09 14:01:17 +00:00
print ( " Returned %d entries " % len ( msgs ) )
2011-02-07 09:55:26 +03:00
2018-03-09 14:01:17 +00:00
print ( " " )
print ( " Getting with cookie but usn %d changed and extra/cursor GUID too " % ( usn - 2 ) )
print ( " so that it ' s (tmp)highest_usn that drives the limit " )
2011-02-07 09:55:26 +03:00
cookie . blob . highwatermark . highest_usn = 0
cookie . blob . highwatermark . tmp_highest_usn = usn - 2
if cookie . blob . extra_length > 0 :
cookie . blob . extra . ctr . cursors [ 0 ] . source_dsa_invocation_id = misc . GUID ( " 128a99bf-e2df-4832-ac0a-1fb625e530db " )
cookie . blob . extra . ctr . cursors [ 0 ] . highest_usn = bigusn - 1
2018-10-11 18:33:48 +13:00
controls = [ " dirsync:1:1:50: %s " % base64 . b64encode ( ndr_pack ( cookie ) ) . decode ( ' utf8 ' ) ]
2011-02-07 09:55:26 +03:00
( msgs , ctrls ) = remote_ldb . searchex ( expression = " (objectclass=*) " , base = base , controls = controls )
if ( len ( ctrls ) ) :
for ctl in ctrls :
cookie = printdirsync ( ctl )
2018-03-09 14:01:17 +00:00
print ( " Returned %d entries " % len ( msgs ) )
2011-02-07 09:55:26 +03:00
2018-03-09 14:01:17 +00:00
print ( " " )
print ( " Getting with cookie but usn changed to %d " % ( usn - 2 ) )
2011-02-07 09:55:26 +03:00
cookie . blob . highwatermark . highest_usn = 0
cookie . blob . highwatermark . tmp_highest_usn = ( usn - 2 )
if cookie . blob . extra_length > 0 :
cookie . blob . extra . ctr . cursors [ 0 ] . highest_usn = ( usn - 2 )
2018-07-30 18:18:03 +12:00
controls = [ " dirsync:1:1:50: %s " % base64 . b64encode ( ndr_pack ( cookie ) ) . decode ( ' utf8 ' ) ]
2011-02-07 09:55:26 +03:00
( msgs , ctrls ) = remote_ldb . searchex ( expression = " (objectclass=*) " , base = base , controls = controls )
if ( len ( ctrls ) ) :
for ctl in ctrls :
cookie = printdirsync ( ctl )
2018-03-09 14:01:17 +00:00
print ( " Returned %d entries " % len ( msgs ) )