summaryrefslogtreecommitdiff
path: root/source4/scripting/bin
diff options
context:
space:
mode:
Diffstat (limited to 'source4/scripting/bin')
-rwxr-xr-xsource4/scripting/bin/upgradeprovision245
1 files changed, 48 insertions, 197 deletions
diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision
index 9656141db9..c08459a2e4 100755
--- a/source4/scripting/bin/upgradeprovision
+++ b/source4/scripting/bin/upgradeprovision
@@ -37,15 +37,13 @@ import samba
import samba.getopt as options
from samba.credentials import DONT_USE_KERBEROS
from samba.auth import system_session, admin_session
-from samba import Ldb, version
-from ldb import SCOPE_ONELEVEL, SCOPE_SUBTREE, SCOPE_BASE,\
+from ldb import SCOPE_SUBTREE, SCOPE_BASE,\
FLAG_MOD_REPLACE, FLAG_MOD_ADD, FLAG_MOD_DELETE,\
MessageElement, Message, Dn
from samba import param
from samba.misc import messageEltFlagToString
from samba.provision import find_setup_dir, get_domain_descriptor,\
get_config_descriptor, secretsdb_self_join,\
- set_gpo_acl, getpolicypath,create_gpo_struct,\
ProvisioningError, getLastProvisionUSN,\
get_max_usn, updateProvisionUSN
from samba.schema import get_linked_attributes, Schema, get_schema_descriptor
@@ -54,7 +52,11 @@ from samba.ndr import ndr_unpack
from samba.dcerpc.misc import SEC_CHAN_BDC
from samba.upgradehelpers import dn_sort, get_paths, newprovision,\
find_provision_key_parameters, get_ldbs,\
- usn_in_range, identic_rename, get_diff_sddls
+ usn_in_range, identic_rename, get_diff_sddls, \
+ update_secrets, CHANGE, ERROR, SIMPLE,\
+ CHANGEALL, GUESS, CHANGESD, PROVISION,\
+ updateOEMInfo, getOEMInfo, update_gpo,\
+ delta_update_basesamdb
replace=2**FLAG_MOD_REPLACE
add=2**FLAG_MOD_ADD
@@ -66,13 +68,6 @@ never=0
# somehow ...
#Errors are always logged
-ERROR = -1
-SIMPLE = 0x00
-CHANGE = 0x01
-CHANGESD = 0x02
-GUESS = 0x04
-PROVISION = 0x08
-CHANGEALL = 0xff
__docformat__ = "restructuredText"
@@ -307,11 +302,11 @@ def handle_special_case(att, delta, new, old, usn):
newval = []
changeDelta=0
for elem in old[0][att]:
- hash[str(elem)]=1
+ hash[str(elem).lower()]=1
newval.append(str(elem))
for elem in new[0][att]:
- if not hash.has_key(str(elem)):
+ if not hash.has_key(str(elem).lower()):
changeDelta=1
newval.append(str(elem))
if changeDelta == 1:
@@ -374,86 +369,6 @@ def handle_special_case(att, delta, new, old, usn):
return False
-def update_secrets(newsecrets_ldb, secrets_ldb):
- """Update secrets.ldb
-
- :param newsecrets_ldb: An LDB object that is connected to the secrets.ldb
- of the reference provision
- :param secrets_ldb: An LDB object that is connected to the secrets.ldb
- of the updated provision"""
-
- message(SIMPLE, "update secrets.ldb")
- reference = newsecrets_ldb.search(expression="dn=@MODULES", base="",
- scope=SCOPE_SUBTREE)
- current = secrets_ldb.search(expression="dn=@MODULES", base="",
- scope=SCOPE_SUBTREE)
- delta = secrets_ldb.msg_diff(current[0], reference[0])
- delta.dn = current[0].dn
- secrets_ldb.modify(delta)
-
- reference = newsecrets_ldb.search(expression="objectClass=top", base="",
- scope=SCOPE_SUBTREE, attrs=["dn"])
- current = secrets_ldb.search(expression="objectClass=top", base="",
- scope=SCOPE_SUBTREE, attrs=["dn"])
- hash_new = {}
- hash = {}
- listMissing = []
- listPresent = []
-
- empty = Message()
- for i in range(0, len(reference)):
- hash_new[str(reference[i]["dn"]).lower()] = reference[i]["dn"]
-
- # Create a hash for speeding the search of existing object in the
- # current provision
- for i in range(0, len(current)):
- hash[str(current[i]["dn"]).lower()] = current[i]["dn"]
-
- for k in hash_new.keys():
- if not hash.has_key(k):
- listMissing.append(hash_new[k])
- else:
- listPresent.append(hash_new[k])
-
- for entry in listMissing:
- reference = newsecrets_ldb.search(expression="dn=%s"%entry,base="", scope=SCOPE_SUBTREE)
- current = secrets_ldb.search(expression="dn=%s"%entry,base="", scope=SCOPE_SUBTREE)
- delta = secrets_ldb.msg_diff(empty,reference[0])
- for att in hashAttrNotCopied.keys():
- delta.remove(att)
- message(CHANGE, "Entry %s is missing from secrets.ldb"%reference[0].dn)
- for att in delta:
- message(CHANGE, " Adding attribute %s"%att)
- delta.dn = reference[0].dn
- secrets_ldb.add(delta)
-
- for entry in listPresent:
- reference = newsecrets_ldb.search(expression="dn=%s"%entry,base="", scope=SCOPE_SUBTREE)
- current = secrets_ldb.search(expression="dn=%s"%entry,base="", scope=SCOPE_SUBTREE)
- delta = secrets_ldb.msg_diff(current[0],reference[0])
- for att in hashAttrNotCopied.keys():
- delta.remove(att)
- for att in delta:
- if att == "name":
- message(CHANGE, "Found attribute name on %s, must rename the DN "%(current[0].dn))
- identic_rename(secrets_ldb,reference[0].dn)
- else:
- delta.remove(att)
-
- for entry in listPresent:
- reference = newsecrets_ldb.search(expression="dn=%s"%entry,base="", scope=SCOPE_SUBTREE)
- current = secrets_ldb.search(expression="dn=%s"%entry,base="", scope=SCOPE_SUBTREE)
- delta = secrets_ldb.msg_diff(current[0],reference[0])
- for att in hashAttrNotCopied.keys():
- delta.remove(att)
- for att in delta:
- if att != "dn":
- message(CHANGE, " Adding/Changing attribute %s to %s"%(att,current[0].dn))
-
- delta.dn = current[0].dn
- secrets_ldb.modify(delta)
-
-
def dump_denied_change(dn, att, flagtxt, current, reference):
"""Print detailed information about why a changed is denied
@@ -491,26 +406,47 @@ def handle_special_add(samdb, dn, names):
:param names: list of key provision parameters"""
dntoremove = None
- if str(dn).lower() == ("CN=IIS_IUSRS, CN=Builtin, %s" % names.rootdn).lower():
+ objDn = Dn(samdb, "CN=IIS_IUSRS, CN=Builtin, %s" % names.rootdn)
+ if dn == objDn :
#This entry was misplaced lets remove it if it exists
dntoremove = "CN=IIS_IUSRS, CN=Users, %s" % names.rootdn
- objname = "CN=Certificate Service DCOM Access, CN=Builtin, %s" % names.rootdn
- if str(dn).lower() == objname.lower():
+ objDn = Dn(samdb,
+ "CN=Certificate Service DCOM Access, CN=Builtin, %s" % names.rootdn)
+ if dn == objDn:
#This entry was misplaced lets remove it if it exists
dntoremove = "CN=Certificate Service DCOM Access,"\
"CN=Users, %s" % names.rootdn
+ print dntoremove
- objname = "CN=Cryptographic Operators, CN=Builtin, %s" % names.rootdn
- if str(dn).lower() == objname.lower():
+ objDn = Dn(samdb, "CN=Cryptographic Operators, CN=Builtin, %s" % names.rootdn)
+ if dn == objDn:
#This entry was misplaced lets remove it if it exists
dntoremove = "CN=Cryptographic Operators, CN=Users, %s" % names.rootdn
- objname = "CN=Event Log Readers, CN=Builtin, %s" % names.rootdn
- if str(dn).lower() == objname.lower():
+ objDn = Dn(samdb, "CN=Event Log Readers, CN=Builtin, %s" % names.rootdn)
+ if dn == objDn:
#This entry was misplaced lets remove it if it exists
dntoremove = "CN=Event Log Readers, CN=Users, %s" % names.rootdn
+ objDn = Dn(samdb,"CN=System,CN=WellKnown Security Principals,"\
+ "CN=Configuration,%s" % names.rootdn)
+ if dn == objDn:
+ oldDn = Dn(samdb,"CN=Well-Known-Security-Id-System,"\
+ "CN=WellKnown Security Principals,"\
+ "CN=Configuration,%s" % names.rootdn)
+
+ res = samdb.search(expression="(dn=%s)" % oldDn,
+ base=str(names.rootdn),
+ scope=SCOPE_SUBTREE, attrs=["dn"],
+ controls=["search_options:1:2"])
+ if len(res) > 0:
+ message(CHANGE, "Existing object %s must be replaced by %s,"\
+ "Renaming old object" % (str(oldDn), str(dn)))
+ samdb.rename(oldDn, objDn)
+
+ return 1
+
if dntoremove != None:
res = samdb.search(expression="(dn=%s)" % dntoremove,
base=str(names.rootdn),
@@ -520,7 +456,7 @@ def handle_special_add(samdb, dn, names):
message(CHANGE, "Existing object %s must be replaced by %s,"\
"removing old object" % (dntoremove, str(dn)))
samdb.delete(res[0]["dn"])
-
+ return 0
def check_dn_nottobecreated(hash, index, listdn):
"""Check if one of the DN present in the list has a creation order
@@ -566,7 +502,8 @@ def add_missing_object(ref_samdb, samdb, dn, names, basedn, hash, index):
:param index: Current creation order
:return: True if the object was created False otherwise"""
- handle_special_add(samdb, dn, names)
+ if handle_special_add(samdb, dn, names):
+ return
reference = ref_samdb.search(expression="dn=%s" % (str(dn)), base=basedn,
scope=SCOPE_SUBTREE, controls=["search_options:1:2"])
empty = Message()
@@ -1140,7 +1077,7 @@ def rebuild_sd(samdb, names):
controls=["search_options:1:2"])
badsd = ndr_unpack(security.descriptor,
str(res[0]["nTSecurityDescriptor"]))
- print "bad stuff %s"%badsd.as_sddl(names.domainsid)
+ print "bad stuff %s" % badsd.as_sddl(names.domainsid)
return
def removeProvisionUSN(samdb):
@@ -1156,49 +1093,6 @@ def removeProvisionUSN(samdb):
delta.dn = entry[0].dn
samdb.modify(delta)
-def delta_update_basesamdb(refpaths, paths, creds, session, lp):
- """Update the provision container db: sam.ldb
- This function is aimed for alpha9 and newer;
-
- :param refpaths: An object holding the different importants paths for
- reference provision object
- :param paths: An object holding the different importants paths for
- upgraded provision object
- :param creds: Credential used for openning LDB files
- :param session: Session to use for openning LDB files
- :param lp: A loadparam object"""
-
- message(SIMPLE,
- "Update base samdb by searching difference with reference one")
- refsam = Ldb(refpaths.samdb, session_info=session, credentials=creds,
- lp=lp, options=["modules:"])
- sam = Ldb(paths.samdb, session_info=session, credentials=creds, lp=lp,
- options=["modules:"])
-
- empty = Message()
-
- reference = refsam.search(expression="")
-
- for refentry in reference:
- entry = sam.search(expression="dn=%s" % refentry["dn"],
- scope=SCOPE_SUBTREE)
- if not len(entry):
- message(CHANGE, "Adding %s to sam db" % str(delta.dn))
- delta = sam.msg_diff(empty, refentry)
- if str(refentry.dn) == "@PROVISION" and\
- delta.get(samba.provision.LAST_PROVISION_USN_ATTRIBUTE):
- delta.remove(samba.provision.LAST_PROVISION_USN_ATTRIBUTE)
- delta.dn = refentry.dn
- sam.add(delta)
- else:
- delta = sam.msg_diff(entry[0], refentry)
- if str(refentry.dn) == "@PROVISION" and\
- delta.get(samba.provision.LAST_PROVISION_USN_ATTRIBUTE):
- delta.remove(samba.provision.LAST_PROVISION_USN_ATTRIBUTE)
- if len(delta.items()) > 1:
- delta.dn = refentry.dn
- sam.modify(delta)
-
def simple_update_basesamdb(newpaths, paths, names):
"""Update the provision container db: sam.ldb
@@ -1313,50 +1207,6 @@ def update_machine_account_password(samdb, secrets_ldb, names):
"of type SEC_CHAN_BDC")
-def update_gpo(paths, creds, session, names):
- """Create missing GPO file object if needed
-
- Set ACL correctly also.
- """
- dir = getpolicypath(paths.sysvol, names.dnsdomain, names.policyid)
- if not os.path.isdir(dir):
- create_gpo_struct(dir)
-
- dir = getpolicypath(paths.sysvol, names.dnsdomain, names.policyid_dc)
- if not os.path.isdir(dir):
- create_gpo_struct(dir)
- samdb = Ldb(paths.samdb, session_info=session, credentials=creds, lp=lp)
- set_gpo_acl(paths.sysvol, names.dnsdomain, names.domainsid,
- names.domaindn, samdb, lp)
-
-
-def getOEMInfo(samdb, rootdn):
- """Return OEM Information on the top level
- Samba4 use to store version info in this field
-
- :param samdb: An LDB object connect to sam.ldb
- :param rootdn: Root DN of the domain
- :return: The content of the field oEMInformation (if any)"""
- res = samdb.search(expression="(objectClass=*)", base=str(rootdn),
- scope=SCOPE_BASE, attrs=["dn", "oEMInformation"])
- if len(res) > 0:
- info = res[0]["oEMInformation"]
- return info
- else:
- return ""
-
-def updateOEMInfo(samdb, names):
- res = samdb.search(expression="(objectClass=*)", base=str(names.rootdn),
- scope=SCOPE_BASE, attrs=["dn", "oEMInformation"])
- if len(res) > 0:
- info = res[0]["oEMInformation"]
- info = "%s, upgrade to %s" % (info, version)
- delta = Message()
- delta.dn = Dn(samdb, str(res[0]["dn"]))
- delta["oEMInformation"] = MessageElement(info, FLAG_MOD_REPLACE,
- "oEMInformation" )
- samdb.modify(delta)
-
def setup_path(file):
return os.path.join(setup_dir, file)
@@ -1514,8 +1364,8 @@ if __name__ == '__main__':
# 3) Guess all the needed names (variables in fact) from the current
# provision.
- names = find_provision_key_parameters(ldbs.sam, ldbs.secrets, paths,
- smbconf, lp)
+ names = find_provision_key_parameters(ldbs.sam, ldbs.secrets, ldbs.idmap,
+ paths, smbconf, lp)
# 4)
lastProvisionUSNs = getLastProvisionUSN(ldbs.sam)
if lastProvisionUSNs != None:
@@ -1563,7 +1413,7 @@ if __name__ == '__main__':
# 9)
update_privilege(newpaths.private_dir, paths.private_dir)
# 10)
- oem = getOEMInfo(ldbs.sam, names.rootdn)
+ oem = getOEMInfo(ldbs.sam, str(names.rootdn))
# Do some modification on sam.ldb
ldbs.groupedCommit()
# 11)
@@ -1572,9 +1422,9 @@ if __name__ == '__main__':
# Starting from alpha9 we can consider that the structure is quite ok
# and that we should do only dela
new_ldbs.groupedCommit()
- delta_update_basesamdb(newpaths, paths, creds, session, lp)
+ delta_update_basesamdb(newpaths.samdb, paths.samdb, creds, session, lp, message)
ldbs.startTransactions()
- minUSN = get_max_usn(ldbs.sam, str(names.rootdn)) + 1
+ minUSN = int(str(get_max_usn(ldbs.sam, str(names.rootdn)))) + 1
new_ldbs.startTransactions()
else:
# 11) B
@@ -1599,7 +1449,7 @@ if __name__ == '__main__':
shutil.rmtree(provisiondir)
sys.exit(1)
# 14)
- update_secrets(new_ldbs.secrets, ldbs.secrets)
+ update_secrets(new_ldbs.secrets, ldbs.secrets, message)
# 15)
update_machine_account_password(ldbs.sam, ldbs.secrets, names)
@@ -1639,12 +1489,13 @@ if __name__ == '__main__':
check_updated_sd(new_ldbs.sam, ldbs.sam, names)
# 20)
- updateOEMInfo(ldbs.sam, names)
+ updateOEMInfo(ldbs.sam, str(names.rootdn))
# 21)
check_for_DNS(newpaths.private_dir, paths.private_dir)
# 22)
if lastProvisionUSNs != None:
updateProvisionUSN(ldbs.sam, minUSN, maxUSN)
+ update_gpo(paths, ldbs.sam, names, lp, message)
ldbs.groupedCommit()
new_ldbs.groupedCommit()
message(SIMPLE, "Upgrade finished !")