[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Fri Nov 27 17:16:24 MST 2009


The branch, master has been updated
       via  db41a0a... s4: fix SD update and password change in upgrade script
      from  f7c28db... s4:WINREG RPC server - add another "talloc_unlink" in "DeleteKey"

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit db41a0afc6412934e166b8a3ed428ce549ba7c66
Author: Matthieu Patou <mat+Informatique.Samba at matws.net>
Date:   Fri Nov 27 17:37:14 2009 +0300

    s4: fix SD update and password change in upgrade script
    
    - reserve a new Samba OID for recalculate SD control
    - fix the update SD function
    - fix handling of kvno in the update_machine_account_password function
    - fix handling of handles in RPC winreg server
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source4/dsdb/samdb/ldb_modules/descriptor.c |   15 ++-
 source4/lib/ldb/common/ldb_controls.c       |   27 ++++
 source4/lib/ldb/include/ldb.h               |    6 +
 source4/libcli/ldap/ldap_controls.c         |   20 +++
 source4/scripting/bin/upgradeprovision      |  172 ++++++++++++++-------------
 source4/scripting/python/samba/provision.py |    8 +-
 source4/scripting/python/samba/schema.py    |    4 +-
 source4/setup/schema_samba4.ldif            |    2 +-
 8 files changed, 161 insertions(+), 93 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c
index f9992e3..da80ee5 100644
--- a/source4/dsdb/samdb/ldb_modules/descriptor.c
+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c
@@ -594,13 +594,13 @@ static int descriptor_do_mod(struct descriptor_context *ac)
 	const struct dsdb_class *objectclass;
 	struct ldb_message *msg;
 	struct ldb_control *sd_control;
+	struct ldb_control *sd_control2;
 	struct ldb_control **saved_controls;
 	int flags = 0;
 	uint32_t sd_flags = 0;
 
 	ldb = ldb_module_get_ctx(ac->module);
 	schema = dsdb_get_schema(ldb);
-
 	msg = ldb_msg_copy_shallow(ac, ac->req->op.mod.message);
 	objectclass_element = ldb_msg_find_element(ac->search_oc_res->message, "objectClass");
 	objectclass = get_last_structural_class(schema, objectclass_element);
@@ -611,6 +611,7 @@ static int descriptor_do_mod(struct descriptor_context *ac)
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 	sd_control = ldb_request_get_control(ac->req, LDB_CONTROL_SD_FLAGS_OID);
+	sd_control2 = ldb_request_get_control(ac->req, LDB_CONTROL_RECALCULATE_SD_OID);
 	if (sd_control) {
 		struct ldb_sd_flags_control *sdctr = (struct ldb_sd_flags_control *)sd_control->data;
 		sd_flags = sdctr->secinfo_flags;
@@ -637,7 +638,11 @@ static int descriptor_do_mod(struct descriptor_context *ac)
 			return ret;
 		}
 		tmp_element = ldb_msg_find_element(msg, "ntSecurityDescriptor");
-		tmp_element->flags = flags;
+		if (sd_control2) {
+			tmp_element->flags = LDB_FLAG_MOD_REPLACE;
+		} else {
+			tmp_element->flags = flags;
+		}
 	}
 	ret = ldb_build_mod_req(&mod_req, ldb, ac,
 				msg,
@@ -679,7 +684,6 @@ static int descriptor_do_add(struct descriptor_context *ac)
 	if (mem_ctx == NULL) {
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
-
 	switch (ac->req->operation) {
 	case LDB_ADD:
 		msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
@@ -768,6 +772,7 @@ static int descriptor_do_add(struct descriptor_context *ac)
 static int descriptor_change(struct ldb_module *module, struct ldb_request *req)
 {
 	struct ldb_context *ldb;
+	struct ldb_control *sd_control;
 	struct ldb_request *search_req;
 	struct descriptor_context *ac;
 	struct ldb_dn *parent_dn, *dn;
@@ -784,7 +789,9 @@ static int descriptor_change(struct ldb_module *module, struct ldb_request *req)
 	case LDB_MODIFY:
 		dn = req->op.mod.message->dn;
 		sd_element = ldb_msg_find_element(req->op.mod.message, "nTSecurityDescriptor");
-		if (!sd_element) {
+		/* This control allow forcing the recalculation of the SD */
+		sd_control = ldb_request_get_control(req, LDB_CONTROL_RECALCULATE_SD_OID);
+		if (!sd_element && !sd_control) {
 			return ldb_next_request(module, req);
 		}
 		break;
diff --git a/source4/lib/ldb/common/ldb_controls.c b/source4/lib/ldb/common/ldb_controls.c
index 82bd34b..f2ab61b 100644
--- a/source4/lib/ldb/common/ldb_controls.c
+++ b/source4/lib/ldb/common/ldb_controls.c
@@ -513,6 +513,33 @@ struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, void *me
 			continue;
 		}
 
+		if (strncmp(control_strings[i], "recalculate_sd:", 15) == 0) {
+			const char *p;
+			int crit, ret;
+
+			p = &(control_strings[i][15]);
+			ret = sscanf(p, "%d", &crit);
+			if ((ret != 1) || (crit < 0) || (crit > 1)) {
+				error_string = talloc_asprintf(mem_ctx, "invalid recalculate_sd control syntax\n");
+				error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
+				error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
+				ldb_set_errstring(ldb, error_string);
+				talloc_free(error_string);
+				return NULL;
+			}
+
+			ctrl[i] = talloc(ctrl, struct ldb_control);
+			if (!ctrl[i]) {
+				ldb_oom(ldb);
+				return NULL;
+			}
+			ctrl[i]->oid = LDB_CONTROL_RECALCULATE_SD_OID;
+			ctrl[i]->critical = crit;
+			ctrl[i]->data = NULL;
+
+			continue;
+		}
+
 		if (strncmp(control_strings[i], "domain_scope:", 13) == 0) {
 			const char *p;
 			int crit, ret;
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h
index 62cd2b8..f2b4a48 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -463,7 +463,13 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
    \sa <a href="http://opends.dev.java.net/public/standards/draft-zeilenga-ldap-managedit.txt">draft managedit</a>.
 */
 #define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12"
+/**
+  OID for recalculate SD control. This control force the
+  dsdb code to recalculate the SD of the object as if the
+  object was just created.
 
+*/
+#define LDB_CONTROL_RECALCULATE_SD_OID "1.3.6.1.4.1.7165.4.3.5"
 /**
    OID for the paged results control. This control is included in the
    searchRequest and searchResultDone messages as part of the controls
diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c
index 7a7da30..0ea80a6 100644
--- a/source4/libcli/ldap/ldap_controls.c
+++ b/source4/libcli/ldap/ldap_controls.c
@@ -1270,6 +1270,25 @@ static bool decode_relax_request(void *mem_ctx, DATA_BLOB in, void *_out)
 	return true;
 }
 
+static bool encode_recalculate_sd_request(void *mem_ctx, void *in, DATA_BLOB *out)
+{
+	if (in) {
+		return false;
+	}
+
+	*out = data_blob(NULL, 0);
+	return true;
+}
+
+static bool decode_recalculate_sd_request(void *mem_ctx, DATA_BLOB in, void *_out)
+{
+	if (in.length != 0) {
+		return false;
+	}
+
+	return true;
+}
+
 static const struct ldap_control_handler ldap_known_controls[] = {
 	{ "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request },
 	{ "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request },
@@ -1292,6 +1311,7 @@ static const struct ldap_control_handler ldap_known_controls[] = {
 	{ "1.3.6.1.4.1.7165.4.3.2", NULL, NULL },
 /* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */
 	{ "1.3.6.1.4.1.7165.4.4.1", NULL, NULL },
+	{ LDB_CONTROL_RECALCULATE_SD_OID,  decode_recalculate_sd_request, encode_recalculate_sd_request},
 	{ DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference},
 	{ LDB_CONTROL_RELAX_OID, decode_relax_request, encode_relax_request },
 	{ NULL, NULL, NULL }
diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision
index 9298c02..2f0ce84 100755
--- a/source4/scripting/bin/upgradeprovision
+++ b/source4/scripting/bin/upgradeprovision
@@ -45,9 +45,10 @@ import ldb
 import samba.getopt as options
 from samba.samdb import SamDB
 from samba import param
-from samba.provision import  ProvisionNames,provision_paths_from_lp,find_setup_dir,FILL_FULL,provision
+from samba import glue
+from samba.provision import  ProvisionNames,provision_paths_from_lp,find_setup_dir,FILL_FULL,provision, get_domain_descriptor, get_config_descriptor, secretsdb_self_join
 from samba.provisionexceptions import ProvisioningError
-from samba.schema import get_dnsyntax_attributes, get_linked_attributes, Schema
+from samba.schema import get_dnsyntax_attributes, get_linked_attributes, Schema, get_schema_descriptor
 from samba.dcerpc import misc, security
 from samba.ndr import ndr_pack, ndr_unpack
 from samba.dcerpc.misc import SEC_CHAN_BDC
@@ -72,7 +73,7 @@ hashAttrNotCopied = { 	"dn": 1,"whenCreated": 1,"whenChanged": 1,"objectGUID": 1
 						"showInAdvancedViewOnly": 1,"instanceType": 1, "cn": 1, "msDS-Behavior-Version":1, "nextRid":1,\
 						"nTMixedDomain": 1,"versionNumber":1, "lmPwdHistory":1, "pwdLastSet": 1, "ntPwdHistory":1, "unicodePwd":1,\
 						"dBCSPwd":1,"supplementalCredentials":1,"gPCUserExtensionNames":1, "gPCMachineExtensionNames":1,\
-						"maxPwdAge":1, "mail":1, "secret":1}
+						"maxPwdAge":1, "mail":1, "secret":1,"possibleInferiors":1}
 
 # Usually for an object that already exists we do not overwrite attributes as they might have been changed for good
 # reasons. Anyway for a few of thems it's mandatory to replace them otherwise the provision will be broken somehow.
@@ -224,7 +225,7 @@ def guess_names_from_current_provision(credentials,session_info,paths):
 	attrs6 = ["objectGUID", "objectSid", ]
 	res6 = samdb.search(expression="(objectClass=*)",base=basedn, scope=SCOPE_BASE, attrs=attrs6)
 	names.domainguid = str(ndr_unpack( misc.GUID,res6[0]["objectGUID"][0]))
-	names.domainsid = str(ndr_unpack( security.dom_sid,res6[0]["objectSid"][0]))
+	names.domainsid = ndr_unpack( security.dom_sid,res6[0]["objectSid"][0])
 
 	# policy guid
 	attrs7 = ["cn","displayName"]
@@ -258,7 +259,7 @@ def print_names(names):
 	message(GUESS, "invocationid:"+names.invocation)
 	message(GUESS, "policyguid  :"+names.policyid)
 	message(GUESS, "policyguiddc:"+str(names.policyid_dc))
-	message(GUESS, "domainsid   :"+names.domainsid)
+	message(GUESS, "domainsid   :"+str(names.domainsid))
 	message(GUESS, "domainguid  :"+names.domainguid)
 	message(GUESS, "ntdsguid    :"+names.ntdsguid)
 
@@ -281,7 +282,7 @@ def newprovision(names,setup_dir,creds,session,smbconf):
 	provision(setup_dir, messageprovision,
 		session, creds, smbconf=smbconf, targetdir=provdir,
 		samdb_fill=FILL_FULL, realm=names.realm, domain=names.domain,
-		domainguid=names.domainguid, domainsid=names.domainsid,ntdsguid=names.ntdsguid,
+		domainguid=names.domainguid, domainsid=str(names.domainsid),ntdsguid=names.ntdsguid,
 		policyguid=names.policyid,policyguid_dc=names.policyid_dc,hostname=names.netbiosname,
 		hostip=None, hostip6=None,
 		invocationid=names.invocation, adminpass=None,
@@ -503,7 +504,7 @@ def check_diff_name(newpaths,paths,creds,session,basedn,names,ischema):
 		# The double ldb open and schema validation is taken from the initial provision script
 		# it's not certain that it is really needed ....
 		sam_ldb = Ldb(session_info=session, credentials=creds, lp=lp)
-		schema = Schema(setup_path, security.dom_sid(names.domainsid), schemadn=basedn, serverdn=str(names.serverdn))
+		schema = Schema(setup_path, names.domainsid, schemadn=basedn, serverdn=str(names.serverdn))
 		# Load the schema from the one we computed earlier
 		sam_ldb.set_schema_from_ldb(schema.ldb)
 		# And now we can connect to the DB - the schema won't be loaded from the DB
@@ -566,75 +567,76 @@ def check_diff_name(newpaths,paths,creds,session,basedn,names,ischema):
 	message(SIMPLE,"There are %d changed objects"%(changed))
 	return hashallSD
 
-
-# This function updates SD for AD objects.
-# As SD in the upgraded provision can be different for various reasons
-# this function check if an automatic update can be performed and do it
-# or if it can't be done.
-def update_sds(diffDefSD,diffSD,paths,creds,session,rootdn,domSIDTxt):
+# Check that SD are correct
+def check_updated_sd(newpaths,paths,creds,session,names):
+	newsam_ldb = Ldb(newpaths.samdb, session_info=session, credentials=creds,lp=lp)
 	sam_ldb = Ldb(paths.samdb, session_info=session, credentials=creds,lp=lp)
-	sam_ldb.transaction_start()
-	domSID = security.dom_sid(domSIDTxt)
-	hashClassSD = {}
-	admin_session_info = admin_session(lp, str(domSID))
-	system_session_info = system_session()
-	upgrade = 0
-	for dn in diffSD.keys():
-		newSD = diffSD[dn]["newSD"].as_sddl(domSID)
-		oldSD = diffSD[dn]["oldSD"].as_sddl(domSID)
-		message(CHANGESD, "ntsecuritydescriptor for %s has changed old %s new %s"%(dn,oldSD,diffSD[dn]["newSD"].as_sddl(domSID)))
-		# First let's find the defaultSD for the object which SD is different from the reference one.
-		res = sam_ldb.search(expression="dn=%s"%(dn),base=rootdn, scope=SCOPE_SUBTREE,attrs=["objectClass"],controls=["search_options:1:2"])
-		classObj = res[0]["objectClass"][-1]
-		defSD = ""
-		if hashClassSD.has_key(classObj):
-			defSD = hashClassSD[classObj]
-		else:
-			res2 = sam_ldb.search(expression="lDAPDisplayName=%s"%(classObj),base=rootdn, scope=SCOPE_SUBTREE,attrs=["defaultSecurityDescriptor"],controls=["search_options:1:2"])
-			if len(res2) > 0:
-				defSD = str(res2[0]["defaultSecurityDescriptor"])
-				hashClassSD[classObj] = defSD
-		# Because somewhere between alpha8 and alpha9 samba4 changed the owner of ACLs in the AD so
-		# we check if it's the case and if so use the "old" owner to see if the ACL is a direct calculation
-		# from the defaultSecurityDescriptor
-		session = admin_session_info
-		if oldSD.startswith("O:SYG:BA"):
-			session = system_session_info
-		descr = security.descriptor.ntsd_from_defaultsd(defSD, domSID,session)
-		if descr.as_sddl(domSID) != oldSD:
-			message(SIMPLE, "nTSecurity Descriptor for %s do not directly inherit from the defaultSecurityDescriptor and is different from the one of the reference provision, therefor I can't upgrade i")
-			message(SIMPLE,"Old Descriptor: %s"%(oldSD))
-			message(SIMPLE,"New Descriptor: %s"%(newSD))
-			if diffDefSD.has_key(classObj):
-				# We have a pending modification for the defaultSecurityDescriptor of the class Object of the currently inspected object
-				# and we have a conflict so write down that we won't upgrade this defaultSD for this class object
-				diffDefSD[classObj]["noupgrade"]=1
-		else:
-			# At this point we know that the SD was directly generated from the defaultSecurityDescriptor
-			# so we can take the new SD and replace the old one
-			upgrade = upgrade +1
-			delta = ldb.Message()
-			delta.dn = ldb.Dn(sam_ldb,dn)
-			delta["nTSecurityDescriptor"] = ldb.MessageElement( ndr_pack(diffSD[dn]["newSD"]),ldb.FLAG_MOD_REPLACE,"nTSecurityDescriptor" )
-		sam_ldb.modify(delta)
+	res = newsam_ldb.search(expression="objectClass=*",base=str(names.rootdn), scope=SCOPE_SUBTREE,attrs=["dn","nTSecurityDescriptor"],controls=["search_options:1:2"])
+	res2 = sam_ldb.search(expression="objectClass=*",base=str(names.rootdn), scope=SCOPE_SUBTREE,attrs=["dn","nTSecurityDescriptor"],controls=["search_options:1:2"])
+	hash_new = {}
+	for i in range(0,len(res)):
+		hash_new[str(res[i]["dn"]).lower()] = ndr_unpack(security.descriptor,str(res[i]["nTSecurityDescriptor"])).as_sddl(names.domainsid)
 
-	sam_ldb.transaction_commit()
-	message(SIMPLE,"%d nTSecurityDescriptor attribute(s) have been updated"%(upgrade))
+	for i in range(0,len(res2)):
+		key = str(res2[i]["dn"]).lower()
+		if hash_new.has_key(key):
+			sddl = ndr_unpack(security.descriptor,str(res2[i]["nTSecurityDescriptor"])).as_sddl(names.domainsid)
+			if sddl != hash_new[key]:
+				print "%s new sddl/sddl in ref"%key
+				print "%s\n%s"%(sddl,hash_new[key])
+
+# Simple update method for updating the SD that rely on the fact that nobody should have modified the SD
+# This assumption is safe right now (alpha9) but should be removed asap
+def update_sd(newpaths,paths,creds,session,names):
+	sam_ldb = Ldb(paths.samdb, session_info=session, credentials=creds,lp=lp)
 	sam_ldb.transaction_start()
-	upgrade = 0
-	for dn in diffDefSD:
-		message(CHANGESD, "DefaultSecurityDescriptor for class object %s has changed"%(dn))
-		if not diffDefSD[dn].has_key("noupgrade"):
-			upgrade = upgrade +1
+	# First update the SD for the rootdn
+	sam_ldb.set_session_info(session)
+	res = sam_ldb.search(expression="objectClass=*",base=str(names.rootdn), scope=SCOPE_BASE,attrs=["dn","whenCreated"],controls=["search_options:1:2"])
+	delta = ldb.Message()
+	delta.dn = ldb.Dn(sam_ldb,str(res[0]["dn"]))
+	descr = get_domain_descriptor(names.domainsid)
+	delta["nTSecurityDescriptor"] = ldb.MessageElement( descr,ldb.FLAG_MOD_REPLACE,"nTSecurityDescriptor" )
+	sam_ldb.modify(delta,["recalculate_sd:0"])
+	# Then the config dn
+	res = sam_ldb.search(expression="objectClass=*",base=str(names.configdn), scope=SCOPE_BASE,attrs=["dn","whenCreated"],controls=["search_options:1:2"])
+	delta = ldb.Message()
+	delta.dn = ldb.Dn(sam_ldb,str(res[0]["dn"]))
+	descr = get_config_descriptor(names.domainsid)
+	delta["nTSecurityDescriptor"] = ldb.MessageElement( descr,ldb.FLAG_MOD_REPLACE,"nTSecurityDescriptor" )
+	sam_ldb.modify(delta,["recalculate_sd:0"])
+	# Then the schema dn
+	res = sam_ldb.search(expression="objectClass=*",base=str(names.schemadn), scope=SCOPE_BASE,attrs=["dn","whenCreated"],controls=["search_options:1:2"])
+	delta = ldb.Message()
+	delta.dn = ldb.Dn(sam_ldb,str(res[0]["dn"]))
+	descr = get_schema_descriptor(names.domainsid)
+	delta["nTSecurityDescriptor"] = ldb.MessageElement( descr,ldb.FLAG_MOD_REPLACE,"nTSecurityDescriptor" )
+	sam_ldb.modify(delta,["recalculate_sd:0"])
+
+	# Then the rest
+	hash = {}
+	res = sam_ldb.search(expression="objectClass=*",base=str(names.rootdn), scope=SCOPE_SUBTREE,attrs=["dn","whenCreated"],controls=["search_options:1:2"])
+	for obj in res:
+		if not (str(obj["dn"]) == str(names.rootdn) or
+			str(obj["dn"]) == str(names.configdn) or \
+			str(obj["dn"]) == str(names.schemadn)):
+			hash[str(obj["dn"])] = obj["whenCreated"]
+
+	listkeys = hash.keys()
+	listkeys.sort(dn_sort)
+
+	for key in listkeys:
+		try:
 			delta = ldb.Message()
-			delta.dn = ldb.Dn(sam_ldb,dn)
-			delta["defaultSecurityDescriptor"] = ldb.MessageElement(diffDefSD[dn]["newSD"],ldb.FLAG_MOD_REPLACE,"defaultSecurityDescriptor" )
-			sam_ldb.modify(delta)
-		else:
-			message(CHANGESD,"Not updating the defaultSecurityDescriptor for class object %s as one or more dependant object hasn't been upgraded"%(dn))
-
+			delta.dn = ldb.Dn(sam_ldb,key)
+			delta["whenCreated"] = ldb.MessageElement( hash[key],ldb.FLAG_MOD_REPLACE,"whenCreated" )
+			sam_ldb.modify(delta,["recalculate_sd:0"])
+		except:
+			sam_ldb.transaction_cancel()
+			res = sam_ldb.search(expression="objectClass=*",base=str(names.rootdn), scope=SCOPE_SUBTREE,attrs=["dn","nTSecurityDescriptor"],controls=["search_options:1:2"])
+			print "bad stuff" +ndr_unpack(security.descriptor,str(res[0]["nTSecurityDescriptor"])).as_sddl(names.domainsid)
+			return
 	sam_ldb.transaction_commit()
-	message(SIMPLE,"%d defaultSecurityDescriptor attribute(s) have been updated"%(upgrade))
 
 def rmall(topdir):
 	for root, dirs, files in os.walk(topdir, topdown=False):
@@ -681,37 +683,36 @@ def update_samdb(newpaths,paths,creds,session,names):
 	message(SIMPLE,"Scanning whole provision for updates and additions")
 	hashSD = check_diff_name(newpaths,paths,creds,session,str(names.rootdn),names,0)
 	message(SIMPLE,"Done with scanning")
-#	update_sds(hashdef,hashSD,paths,creds,session,str(names.rootdn),names.domainsid)
 
-def update_machine_account_password(newpaths,paths,creds,session,names):
+def update_machine_account_password(paths,creds,session,names):
 
-	secrets_ldb = Ldb(newpaths.secrets, session_info=session, credentials=creds,lp=lp)
+	secrets_ldb = Ldb(paths.secrets, session_info=session, credentials=creds,lp=lp)
 	secrets_ldb.transaction_start()
 	secrets_msg = secrets_ldb.search(expression=("samAccountName=%s$" % names.netbiosname), attrs=["secureChannelType"])
 	sam_ldb = Ldb(paths.samdb, session_info=session, credentials=creds,lp=lp)
-	if secrets_msg[0]["secureChannelType"][0] == SEC_CHAN_BDC:
-		sam_ldb.transaction_start()
+	sam_ldb.transaction_start()
+	if int(secrets_msg[0]["secureChannelType"][0]) == SEC_CHAN_BDC:
 		res = sam_ldb.search(expression=("samAccountName=%s$" % names.netbiosname), attrs=[])
 		assert(len(res) == 1)
 
 		msg = ldb.Message(res[0].dn)
-		machinepass = msg["userPassword"] = glue.generate_random_str(12)
-		for el in msg:
-			el.set_flags(ldb.FLAG_MOD_REPLACE)
+		machinepass = glue.generate_random_str(12)
+		msg["userPassword"] = ldb.MessageElement(machinepass, ldb.FLAG_MOD_REPLACE, "userPassword")
 		sam_ldb.modify(msg)
 
 		res = sam_ldb.search(expression=("samAccountName=%s$" % names.netbiosname),
 				     attrs=["msDs-keyVersionNumber"])
 		assert(len(res) == 1)
-		kvno = res[0]["msDs-keyVersionNumber"]
+		kvno = int(str(res[0]["msDs-keyVersionNumber"]))
 
 		secretsdb_self_join(secrets_ldb, domain=names.domain,
 				    realm=names.realm,
+					domainsid=names.domainsid,
 				    dnsdomain=names.dnsdomain,
 				    netbiosname=names.netbiosname,
 				    machinepass=machinepass,
 				    key_version_number=kvno,
-				    secure_channel_type=secrets_msg[0]["secureChannelType"])
+				    secure_channel_type=int(secrets_msg[0]["secureChannelType"][0]))
 		sam_ldb.transaction_prepare_commit()
 		secrets_ldb.transaction_prepare_commit()
 		sam_ldb.transaction_commit()
@@ -739,9 +740,16 @@ populate_backlink(newpaths,creds,session,names.schemadn)
 update_basesamdb(newpaths,paths,names)
 update_secrets(newpaths,paths,creds,session)
 update_privilege(newpaths,paths)
-update_machine_account_password(newpaths,paths,creds,session,names)
+update_machine_account_password(paths,creds,session,names)
+
 if opts.full:
 	update_samdb(newpaths,paths,creds,session,names)
+# SD should be created with admin but as some previous acl were so wrong that admin can't modify them we have first
+# to recreate them with the good form but with system account and then give the ownership to admin ...
+admin_session_info = admin_session(lp, str(names.domainsid))
+update_sd(newpaths,paths,creds,session,names)
+update_sd(newpaths,paths,creds,admin_session_info,names)
+check_updated_sd(newpaths,paths,creds,session,names)
 message(SIMPLE,"Upgrade finished !")
 # remove reference provision now that everything is done !
 rmall(provisiondir)
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index af95657..f9f7ec9 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -95,7 +95,7 @@ def get_config_descriptor(domain_sid):
            "S:(AU;SA;WPWOWD;;;WD)(AU;SA;CR;;;BA)(AU;SA;CR;;;DU)" \
            "(OU;SA;CR;45ec5156-db7e-47bb-b53f-dbeb2d03c40f;;WD)"
     sec = security.descriptor.from_sddl(sddl, domain_sid)
-    return b64encode(ndr_pack(sec))
+    return ndr_pack(sec)
 
 def get_domain_descriptor(domain_sid):
     sddl= "O:BAG:BAD:AI(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
@@ -148,7 +148,7 @@ def get_domain_descriptor(domain_sid):
     "(OU;CISA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" \
     "(AU;SA;CR;;;DU)(AU;SA;CR;;;BA)(AU;SA;WPWOWD;;;WD)"
     sec = security.descriptor.from_sddl(sddl, domain_sid)
-    return b64encode(ndr_pack(sec))
+    return ndr_pack(sec)
 
 DEFAULTSITE = "Default-First-Site-Name"
 
@@ -897,7 +897,7 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp,
         else:
             domainguid_line = ""
 
-        descr = get_domain_descriptor(domainsid)
+        descr = b64encode(get_domain_descriptor(domainsid))
         setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), {
                 "DOMAINDN": names.domaindn,
                 "DOMAINGUID": domainguid_line,
@@ -920,7 +920,7 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp,
             })
 
         message("Adding configuration container")
-        descr = get_config_descriptor(domainsid);
+        descr = b64encode(get_config_descriptor(domainsid))
         setup_add_ldif(samdb, setup_path("provision_configuration_basedn.ldif"), {
             "CONFIGDN": names.configdn, 
             "DESCRIPTOR": descr,
diff --git a/source4/scripting/python/samba/schema.py b/source4/scripting/python/samba/schema.py
index 6f45859..8913e53 100644
--- a/source4/scripting/python/samba/schema.py
+++ b/source4/scripting/python/samba/schema.py
@@ -46,7 +46,7 @@ def get_schema_descriptor(domain_sid):
            "(AU;SA;CR;;;DU)(OU;SA;CR;e12b56b6-0a95-11d1-adbb-00c04fd8d5cd;;WD)" \
            "(OU;SA;CR;45ec5156-db7e-47bb-b53f-dbeb2d03c40f;;WD)"
     sec = security.descriptor.from_sddl(sddl, domain_sid)
-    return b64encode(ndr_pack(sec))
+    return ndr_pack(sec)
 
    
 class Schema(object):
@@ -79,7 +79,7 @@ class Schema(object):
                                                    "SERVERDN": serverdn,
                                                    })
 
-        descr = get_schema_descriptor(domain_sid)
+        descr = b64encode(get_schema_descriptor(domain_sid))
         self.schema_dn_add = read_and_sub_file(setup_path("provision_schema_basedn.ldif"),
                                                {"SCHEMADN": schemadn,
                                                 "DESCRIPTOR": descr
diff --git a/source4/setup/schema_samba4.ldif b/source4/setup/schema_samba4.ldif
index fd663fd..3216f4f 100644
--- a/source4/setup/schema_samba4.ldif
+++ b/source4/setup/schema_samba4.ldif
@@ -177,7 +177,7 @@
 #Allocated: DSDB_CONTROL_CURRENT_PARTITION_OID 1.3.6.1.4.1.7165.4.3.2
 
 #Allocated: DSDB_CONTROL_REPLICATED_UPDATE_OID 1.3.6.1.4.1.7165.4.3.3
-


-- 
Samba Shared Repository


More information about the samba-cvs mailing list