summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2010-08-24 22:10:46 +1000
committerAndrew Tridgell <tridge@samba.org>2010-08-25 08:40:04 +1000
commite3c0409c7a22d8412a74436aa5733bc527730b5a (patch)
treeda880caaca07e1655bfeb91220340b7715b615d1
parent4ab1a489c74079644c1fce5df1ced5a0bbbc9f39 (diff)
downloadsamba-e3c0409c7a22d8412a74436aa5733bc527730b5a.tar.gz
samba-e3c0409c7a22d8412a74436aa5733bc527730b5a.tar.bz2
samba-e3c0409c7a22d8412a74436aa5733bc527730b5a.zip
s4-rodc: added REPL_SECRET exop replication of accounts
During a RODC join, we need to fetch the secrets for the machine account and krbtgt account using GetNCChanges DRSUAPI_EXOP_REPL_SECRET calls Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
-rw-r--r--source4/scripting/python/samba/join.py69
1 files changed, 58 insertions, 11 deletions
diff --git a/source4/scripting/python/samba/join.py b/source4/scripting/python/samba/join.py
index d185974faf..725458d406 100644
--- a/source4/scripting/python/samba/join.py
+++ b/source4/scripting/python/samba/join.py
@@ -119,15 +119,48 @@ def join_rodc(server=None, creds=None, lp=None, site=None, netbios_name=None,
(info, handle) = drs.DsBind(misc.GUID(drsuapi.DRSUAPI_DS_BIND_GUID), bind_info)
return handle
- def replicate_partition(ctx, dn, schema=False):
+ def get_rodc_partial_attribute_set(ctx):
+ '''get a list of attributes for RODC replication'''
+ partial_attribute_set = drsuapi.DsPartialAttributeSet()
+ partial_attribute_set.version = 1
+
+ ctx.attids = []
+
+ # the exact list of attids we send is quite critical. Note that
+ # we do ask for the secret attributes, but set set SPECIAL_SECRET_PROCESSING
+ # to zero them out
+ res = ctx.local_samdb.search(base=ctx.schema_dn, scope=ldb.SCOPE_SUBTREE,
+ expression="objectClass=attributeSchema",
+ attrs=["lDAPDisplayName", "systemFlags",
+ "searchFlags"])
+ for r in res:
+ ldap_display_name = r["lDAPDisplayName"][0]
+ if "systemFlags" in r:
+ system_flags = r["systemFlags"][0]
+ if (int(system_flags) & (samba.dsdb.DS_FLAG_ATTR_NOT_REPLICATED |
+ samba.dsdb.DS_FLAG_ATTR_IS_CONSTRUCTED)):
+ continue
+ search_flags = r["searchFlags"][0]
+ if (int(search_flags) & samba.dsdb.SEARCH_FLAG_RODC_ATTRIBUTE):
+ continue
+ attid = ctx.local_samdb.get_attid_from_lDAPDisplayName(ldap_display_name)
+ ctx.attids.append(int(attid))
+
+ # the attids do need to be sorted, or windows doesn't return
+ # all the attributes we need
+ ctx.attids.sort()
+ partial_attribute_set.attids = ctx.attids
+ partial_attribute_set.num_attids = len(ctx.attids)
+ return partial_attribute_set
+
+
+ def replicate_partition(ctx, dn, schema=False, exop=drsuapi.DRSUAPI_EXOP_NONE):
'''replicate a partition'''
# setup for a GetNCChanges call
req8 = drsuapi.DsGetNCChangesRequest8()
- exop = drsuapi.DRSUAPI_EXOP_NONE
- null_guid = misc.GUID()
- req8.destination_dsa_guid = misc.GUID("9c637462-5b8c-4467-aef2-bdb1f57bc4ef")
+ req8.destination_dsa_guid = ctx.ntds_guid
req8.source_dsa_invocation_id = misc.GUID(ctx.samdb.get_invocation_id())
req8.naming_context = drsuapi.DsReplicaObjectIdentifier()
req8.naming_context.dn = dn.decode("utf-8")
@@ -136,11 +169,14 @@ def join_rodc(server=None, creds=None, lp=None, site=None, netbios_name=None,
req8.highwatermark.reserved_usn = 0
req8.highwatermark.highest_usn = 0
req8.uptodateness_vector = None
- req8.replica_flags = 0
- req8.replica_flags |= (drsuapi.DRSUAPI_DRS_INIT_SYNC |
- drsuapi.DRSUAPI_DRS_PER_SYNC |
- drsuapi.DRSUAPI_DRS_GET_ANC |
- drsuapi.DRSUAPI_DRS_NEVER_SYNCED)
+ if exop == drsuapi.DRSUAPI_EXOP_REPL_SECRET:
+ req8.replica_flags = 0
+ else:
+ req8.replica_flags = (drsuapi.DRSUAPI_DRS_INIT_SYNC |
+ drsuapi.DRSUAPI_DRS_PER_SYNC |
+ drsuapi.DRSUAPI_DRS_GET_ANC |
+ drsuapi.DRSUAPI_DRS_NEVER_SYNCED |
+ drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING)
req8.max_object_count = 402
req8.max_ndr_size = 402116
req8.extended_op = exop
@@ -151,6 +187,8 @@ def join_rodc(server=None, creds=None, lp=None, site=None, netbios_name=None,
req8.mapping_ctr.mappings = None
while True:
+ if not schema:
+ req8.partial_attribute_set = get_rodc_partial_attribute_set(ctx)
(level, ctr) = ctx.drs.DsGetNCChanges(ctx.drs_handle, 8, req8)
net.replicate_chunk(ctx.replication_state, level, ctr, schema=schema)
if ctr.more_data == 0:
@@ -267,6 +305,10 @@ def join_rodc(server=None, creds=None, lp=None, site=None, netbios_name=None,
"msDS-HasFullReplicaNCs" : [ ctx.base_dn, ctx.config_dn, ctx.schema_dn ]}
ctx.samdb.add(rec, ["rodc_join:1:1"])
+ # find the GUID of our NTDS DN
+ res = ctx.samdb.search(base=ctx.ntds_dn, scope=ldb.SCOPE_BASE, attrs=["objectGUID"])
+ ctx.ntds_guid = misc.GUID(ctx.samdb.schema_format_value("objectGUID", res[0]["objectGUID"][0]))
+
print "Adding %s" % ctx.connection_dn
rec = {
"dn" : ctx.connection_dn,
@@ -332,7 +374,7 @@ def join_rodc(server=None, creds=None, lp=None, site=None, netbios_name=None,
ctx.acct_creds.set_username(ctx.samname)
ctx.acct_creds.set_password(ctx.acct_pass)
- ctx.drs = drsuapi.drsuapi("ncacn_ip_tcp:%s[seal,print]" % ctx.server, ctx.lp, ctx.creds)
+ ctx.drs = drsuapi.drsuapi("ncacn_ip_tcp:%s[seal,print]" % ctx.server, ctx.lp, ctx.acct_creds)
ctx.drs_handle = do_DsBind(ctx.drs)
print "DRS Handle: %s" % ctx.drs_handle
@@ -376,6 +418,11 @@ def join_rodc(server=None, creds=None, lp=None, site=None, netbios_name=None,
replicate_partition(ctx, ctx.schema_dn, schema=True)
replicate_partition(ctx, ctx.config_dn)
replicate_partition(ctx, ctx.base_dn)
+ ctx.local_samdb.transaction_commit()
+
+ ctx.local_samdb.transaction_start()
+ replicate_partition(ctx, ctx.acct_dn, exop=drsuapi.DRSUAPI_EXOP_REPL_SECRET)
+ replicate_partition(ctx, ctx.new_krbtgt_dn, exop=drsuapi.DRSUAPI_EXOP_REPL_SECRET)
- print "Committing"
+ print "Committing SAM database"
ctx.local_samdb.transaction_commit()