3 # script to call a DRS GetNCChanges from the command line
4 # this is useful for plugfest testing
7 from optparse
import OptionParser
9 sys
.path
.insert(0, "bin/python")
12 import samba
.getopt
as options
13 from samba
.dcerpc
import drsuapi
, misc
14 from samba
.samdb
import SamDB
15 from samba
.auth
import system_session
18 '''make a DsBind call, returning the binding handle'''
19 bind_info
= drsuapi
.DsBindInfoCtr()
21 bind_info
.info
= drsuapi
.DsBindInfo28()
22 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_BASE
23 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION
24 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI
25 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2
26 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS
27 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1
28 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION
29 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE
30 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2
31 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION
32 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2
33 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD
34 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND
35 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO
36 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION
37 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01
38 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP
39 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY
40 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3
41 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2
42 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6
43 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS
44 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8
45 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5
46 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6
47 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3
48 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7
49 bind_info
.info
.supported_extensions |
= drsuapi
.DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT
50 (info
, handle
) = drs
.DsBind(misc
.GUID(drsuapi
.DRSUAPI_DS_BIND_GUID
), bind_info
)
54 def drs_get_rodc_partial_attribute_set(samdb
):
55 '''get a list of attributes for RODC replication'''
56 partial_attribute_set
= drsuapi
.DsPartialAttributeSet()
57 partial_attribute_set
.version
= 1
61 # the exact list of attids we send is quite critical. Note that
62 # we do ask for the secret attributes, but set set SPECIAL_SECRET_PROCESSING
64 schema_dn
= samdb
.get_schema_basedn()
65 res
= samdb
.search(base
=schema_dn
, scope
=ldb
.SCOPE_SUBTREE
,
66 expression
="objectClass=attributeSchema",
67 attrs
=["lDAPDisplayName", "systemFlags",
71 ldap_display_name
= r
["lDAPDisplayName"][0]
72 if "systemFlags" in r
:
73 system_flags
= r
["systemFlags"][0]
74 if (int(system_flags
) & (samba
.dsdb
.DS_FLAG_ATTR_NOT_REPLICATED |
75 samba
.dsdb
.DS_FLAG_ATTR_IS_CONSTRUCTED
)):
77 if "searchFlags" in r
:
78 search_flags
= r
["searchFlags"][0]
79 if (int(search_flags
) & samba
.dsdb
.SEARCH_FLAG_RODC_ATTRIBUTE
):
81 attid
= samdb
.get_attid_from_lDAPDisplayName(ldap_display_name
)
82 attids
.append(int(attid
))
84 # the attids do need to be sorted, or windows doesn't return
85 # all the attributes we need
87 partial_attribute_set
.attids
= attids
88 partial_attribute_set
.num_attids
= len(attids
)
89 return partial_attribute_set
92 ########### main code ###########
93 if __name__
== "__main__":
94 parser
= OptionParser("getncchanges [options] server")
95 sambaopts
= options
.SambaOptions(parser
)
96 parser
.add_option_group(sambaopts
)
97 credopts
= options
.CredentialsOptionsDouble(parser
)
98 parser
.add_option_group(credopts
)
100 parser
.add_option("", "--dn", dest
="dn", help="DN to replicate",)
101 parser
.add_option("", "--exop", dest
="exop", help="extended operation",)
102 parser
.add_option("", "--pas", dest
="use_pas", action
='store_true', default
=False,
103 help="send partial attribute set",)
104 parser
.add_option("", "--nb-iter", type='int', help="Number of getncchange iterations")
105 parser
.add_option("", "--dest-dsa", type='str',
106 default
='"9c637462-5b8c-4467-aef2-bdb1f57bc4ef"', help="destination DSA GUID")
107 parser
.add_option("", "--replica-flags", type='int',
108 default
=drsuapi
.DRSUAPI_DRS_INIT_SYNC |
109 drsuapi
.DRSUAPI_DRS_PER_SYNC |
110 drsuapi
.DRSUAPI_DRS_GET_ANC |
111 drsuapi
.DRSUAPI_DRS_NEVER_SYNCED
,
112 help='replica flags')
114 (opts
, args
) = parser
.parse_args()
116 lp
= sambaopts
.get_loadparm()
117 creds
= credopts
.get_credentials(lp
)
120 parser
.error("You must supply a server")
122 if creds
.is_anonymous():
123 parser
.error("You must supply credentials")
127 binding_str
= "ncacn_ip_tcp:%s[seal,print]" % server
129 drs
= drsuapi
.drsuapi(binding_str
, lp
, creds
)
130 drs_handle
= do_DsBind(drs
)
131 print "DRS Handle: %s" % drs_handle
133 req8
= drsuapi
.DsGetNCChangesRequest8()
135 samdb
= SamDB(url
="ldap://%s" % server
,
136 session_info
=system_session(),
137 credentials
=creds
, lp
=lp
)
140 local_samdb
= SamDB(url
=None, session_info
=system_session(),
141 credentials
=creds
, lp
=lp
)
144 opts
.dn
= str(samdb
.get_default_basedn())
146 if opts
.exop
is None:
147 exop
= drsuapi
.DRSUAPI_EXOP_NONE
149 exop
= int(opts
.exop
)
151 null_guid
= misc
.GUID()
152 req8
.destination_dsa_guid
= misc
.GUID(opts
.dest_dsa
)
153 req8
.source_dsa_invocation_id
= misc
.GUID(samdb
.get_invocation_id())
154 req8
.naming_context
= drsuapi
.DsReplicaObjectIdentifier()
155 req8
.naming_context
.dn
= opts
.dn
.decode("utf-8")
156 req8
.highwatermark
= drsuapi
.DsReplicaHighWaterMark()
157 req8
.highwatermark
.tmp_highest_usn
= 0
158 req8
.highwatermark
.reserved_usn
= 0
159 req8
.highwatermark
.highest_usn
= 0
160 req8
.uptodateness_vector
= None
161 req8
.replica_flags
= opts
.replica_flags
162 req8
.max_object_count
= 402
163 req8
.max_ndr_size
= 402116
164 req8
.extended_op
= exop
167 req8
.partial_attribute_set
= drs_get_rodc_partial_attribute_set(local_samdb
)
169 req8
.partial_attribute_set
= None
170 req8
.partial_attribute_set_ex
= None
171 req8
.mapping_ctr
.num_mappings
= 0
172 req8
.mapping_ctr
.mappings
= None
176 (level
, ctr
) = drs
.DsGetNCChanges(drs_handle
, 8, req8
)
178 if ctr
.more_data
== 0 or opts
.nb_iter
== nb_iter
:
180 req8
.highwatermark
.tmp_highest_usn
= ctr
.new_highwatermark
.tmp_highest_usn