[PATCH 5/8] s4:upgradeprovision Rework script, and reset machine account pw

Andrew Bartlett abartlet at samba.org
Wed Nov 25 21:32:49 MST 2009


The rework corrects some duplication and errors in the original
script, found when preparing an automated test of the script.

The code to reset the machine account password avoids issues with AES
keys and salting, which may not otherwise be solved by the upgrade.

Andrew Bartlett
---
 source4/scripting/bin/upgradeprovision |   82 +++++++++++++++++++++----------
 1 files changed, 55 insertions(+), 27 deletions(-)

diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision
index 2051a64..7ac8bcb 100755
--- a/source4/scripting/bin/upgradeprovision
+++ b/source4/scripting/bin/upgradeprovision
@@ -173,8 +173,7 @@ def guess_names_from_current_provision(credentials,session_info,paths):
 	# NT domain, kerberos realm, root dn, domain dn, domain dns name
 	names.domain = string.upper(lp.get("workgroup"))
 	names.realm = lp.get("realm")
-	rootdn = "DC=" + names.realm.replace(".",",DC=")
-	names.domaindn = rootdn
+	basedn = "DC=" + names.realm.replace(".",",DC=")
 	names.dnsdomain = names.realm
 	names.realm = string.upper(names.realm)
 	# netbiosname
@@ -190,16 +189,17 @@ def guess_names_from_current_provision(credentials,session_info,paths):
 		    credentials=credentials, lp=lp, options=["modules:samba_dsdb"])
 	
 	# That's a bit simplistic but it's ok as long as we have only 3 partitions 
-	attrs2 = ["schemaNamingContext","configurationNamingContext","rootDomainNamingContext"]
+	attrs2 = ["defaultNamingContext", "schemaNamingContext","configurationNamingContext","rootDomainNamingContext"]
 	res2 = samdb.search(expression="(objectClass=*)",base="", scope=SCOPE_BASE, attrs=attrs2)
 
 	names.configdn = res2[0]["configurationNamingContext"]
 	configdn = str(names.configdn)
 	names.schemadn = res2[0]["schemaNamingContext"]
-	if not (rootdn == str(res2[0]["rootDomainNamingContext"])):
-		message(ERROR, "rootdn in sam.ldb and smb.conf is not the same ...")
-	else:
-		names.rootdn=res2[0]["rootDomainNamingContext"]
+	if not (ldb.Dn(samdb, basedn) == (ldb.Dn(samdb, res2[0]["defaultNamingContext"][0]))):
+		raise ProvisioningError(("basedn in %s (%s) and from %s (%s) is not the same ..." % (paths.samdb, str(res2[0]["defaultNamingContext"][0]), paths.smbconf, basedn)))
+
+	names.domaindn=res2[0]["defaultNamingContext"]
+	names.rootdn=res2[0]["rootDomainNamingContext"]
 	# default site name
 	attrs3 = ["cn"]
 	res3= samdb.search(expression="(objectClass=*)",base="CN=Sites,"+configdn, scope=SCOPE_ONELEVEL, attrs=attrs3)
@@ -207,43 +207,37 @@ def guess_names_from_current_provision(credentials,session_info,paths):
 	
 	# dns hostname and server dn 
 	attrs4 = ["dNSHostName"]
-	res4= samdb.search(expression="(CN=%s)"%names.netbiosname,base="OU=Domain Controllers,"+rootdn, \
+	res4= samdb.search(expression="(CN=%s)"%names.netbiosname,base="OU=Domain Controllers,"+basedn, \
 						scope=SCOPE_ONELEVEL, attrs=attrs4)
 	names.hostname = str(res4[0]["dNSHostName"]).replace("."+names.dnsdomain,"")
 
-	names.serverdn = "CN=%s,CN=Servers,CN=%s,CN=Sites,%s" % (names.netbiosname, names.sitename, configdn)
+	server_res = samdb.search(expression="serverReference=%s"%res4[0].dn, attrs=[], base=configdn)
+	names.serverdn = server_res[0].dn
 	
-	# invocation id
-	attrs5 = ["invocationId"]
-	res5 = samdb.search(expression="(objectClass=*)",base="CN=Sites,"+configdn, scope=SCOPE_SUBTREE, attrs=attrs5)
-	for i in range(0,len(res5)):
-		if ( len(res5[i]) > 0):
-			names.invocation = str(ndr_unpack( misc.GUID,res5[i]["invocationId"][0]))
-			break
+	# invocation id/objectguid
+	res5 = samdb.search(expression="(objectClass=*)",base="CN=NTDS Settings,%s" % str(names.serverdn), scope=SCOPE_BASE, attrs=["invocationID","objectGUID"])
+	names.invocation = str(ndr_unpack( misc.GUID,res5[0]["invocationId"][0]))
+	names.ntdsguid = str(ndr_unpack( misc.GUID,res5[0]["objectGUID"][0]))
+
 	# domain guid/sid
 	attrs6 = ["objectGUID", "objectSid", ]
-	res6 = samdb.search(expression="(objectClass=*)",base=rootdn, scope=SCOPE_BASE, attrs=attrs6)
+	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]))
 
 	# policy guid
 	attrs7 = ["cn","displayName"]
-	res7 = samdb.search(expression="(displayName=Default Domain Policy)",base="CN=Policies,CN=System,"+rootdn, \
+	res7 = samdb.search(expression="(displayName=Default Domain Policy)",base="CN=Policies,CN=System,"+basedn, \
 							scope=SCOPE_ONELEVEL, attrs=attrs7)
 	names.policyid = str(res7[0]["cn"]).replace("{","").replace("}","")
 	# dc policy guid
 	attrs8 = ["cn","displayName"]
-	res8 = samdb.search(expression="(displayName=Default Domain Controllers Policy)",base="CN=Policies,CN=System,"+rootdn, \
+	res8 = samdb.search(expression="(displayName=Default Domain Controllers Policy)",base="CN=Policies,CN=System,"+basedn, \
 							scope=SCOPE_ONELEVEL, attrs=attrs7)
 	if len(res8) == 1:
 		names.policyid_dc = str(res8[0]["cn"]).replace("{","").replace("}","")
 	else:
 		names.policyid_dc = None
-	# ntds guid
-	attrs9 = ["objectGUID" ]
-	exp = "(dn=CN=NTDS Settings,%s)"%(names.serverdn)
-	res9 = samdb.search(expression="(dn=CN=NTDS Settings,%s)"%(names.serverdn),base=str(names.configdn), scope=SCOPE_SUBTREE, attrs=attrs9)
-	names.ntdsguid = str(ndr_unpack( misc.GUID,res9[0]["objectGUID"][0]))
 
 
 	return names
@@ -253,7 +247,7 @@ def print_names(names):
 	message(GUESS, "rootdn      :"+str(names.rootdn))
 	message(GUESS, "configdn    :"+str(names.configdn))
 	message(GUESS, "schemadn    :"+str(names.schemadn))
-	message(GUESS, "serverdn    :"+names.serverdn)
+	message(GUESS, "serverdn    :"+str(names.serverdn))
 	message(GUESS, "netbiosname :"+names.netbiosname)
 	message(GUESS, "defaultsite :"+names.sitename)
 	message(GUESS, "dnsdomain   :"+names.dnsdomain)
@@ -287,7 +281,7 @@ def newprovision(names,setup_dir,creds,session,smbconf):
 		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,
-		policyguid=names.policyid,policyguid_dc=names.policyid_dc,hostname=names.hostname,
+		policyguid=names.policyid,policyguid_dc=names.policyid_dc,hostname=names.netbiosname,
 		hostip=None, hostip6=None,
 		invocationid=names.invocation, adminpass=None,
 		krbtgtpass=None, machinepass=None,
@@ -508,7 +502,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=names.serverdn)
+		schema = Schema(setup_path, security.dom_sid(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
@@ -698,6 +692,40 @@ def update_samdb(newpaths,paths,creds,session,names):
 	hashSD = check_diff_name(newpaths,paths,creds,session,str(names.rootdn),names,0)
 	message(SIMPLE,"Done with scanning")
 
+def update_machine_account_password(newpaths,paths,creds,session,names):
+	
+	secrets_ldb = Ldb(newpaths.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()
+		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)
+		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"]
+
+		secretsdb_self_join(secrets_ldb, domain=names.domain,
+				    realm=names.realm,
+				    dnsdomain=names.dnsdomain,
+				    netbiosname=names.netbiosname,
+				    machinepass=machinepass,
+				    key_version_number=kvno,
+				    secure_channel_type=secrets_msg[0]["secureChannelType"])
+	sam_ldb.transaction_prepare_commit()
+	secrets_ldb.transaction_prepare_commit()
+	sam_ldb.transaction_commit()
+	secrets_ldb.transaction_commit()
+
 # From here start the big steps of the program
 # First get files paths
 paths=get_paths(targetdir=opts.targetdir,smbconf=smbconf)
-- 
1.6.3.3


--------------040904030402080707020200--


More information about the samba-technical mailing list