From d24a22fe9a414bf37859967848c45f2a7494193d Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Sun, 15 May 2011 16:06:18 +0400 Subject: s4-python: add an option for just fixing gpo folders --- source4/scripting/bin/upgradeprovision | 385 +++++++++++++++++---------------- 1 file changed, 196 insertions(+), 189 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 8c79917d5e..4e48a48b45 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -151,6 +151,8 @@ parser.add_option("--debugall", action="store_true", help="Print all available information (very verbose)") parser.add_option("--resetfileacl", action="store_true", help="Force a reset on filesystem acls in sysvol / netlogon share") +parser.add_option("--fixntacl", action="store_true", + help="Only fix NT ACLs in sysvol / netlogon share") parser.add_option("--full", action="store_true", help="Perform full upgrade of the samdb (schema, configuration, new objects, ...") @@ -1609,80 +1611,81 @@ if __name__ == '__main__': adm_session = admin_session(lp, str(names.domainsid)) # So we reget handle on objects # ldbs = get_ldbs(paths, creds, adm_session, lp) + if not opts.fixntacl: + if not sanitychecks(ldbs.sam, names): + message(SIMPLE, "Sanity checks for the upgrade have failed. " + "Check the messages and correct the errors " + "before rerunning upgradeprovision") + ldbs.groupedRollback() + sys.exit(1) - if not sanitychecks(ldbs.sam, names): - message(SIMPLE, "Sanity checks for the upgrade have failed. " - "Check the messages and correct the errors " - "before rerunning upgradeprovision") - sys.exit(1) - - # Let's see provision parameters - print_provision_key_parameters(names) - - # 5) With all this information let's create a fresh new provision used as - # reference - message(SIMPLE, "Creating a reference provision") - provisiondir = tempfile.mkdtemp(dir=paths.private_dir, - prefix="referenceprovision") - newprovision(names, creds, session, smbconf, provisiondir, - provision_logger) - - # TODO - # 6) and 7) - # We need to get a list of object which SD is directly computed from - # defaultSecurityDescriptor. - # This will allow us to know which object we can rebuild the SD in case - # of change of the parent's SD or of the defaultSD. - # Get file paths of this new provision - newpaths = get_paths(param, targetdir=provisiondir) - new_ldbs = get_ldbs(newpaths, creds, session, lp) - new_ldbs.startTransactions() - - # 8) Populate some associative array to ease the update process - # List of attribute which are link and backlink - populate_links(new_ldbs.sam, names.schemadn) - # List of attribute with ASN DN synthax) - populate_dnsyntax(new_ldbs.sam, names.schemadn) - # 9) - update_privilege(newpaths.private_dir, paths.private_dir) - # 10) - oem = getOEMInfo(ldbs.sam, str(names.rootdn)) - # Do some modification on sam.ldb - ldbs.groupedCommit() - new_ldbs.groupedCommit() - deltaattr = None -# 11) - if re.match(".*alpha((9)|(\d\d+)).*", str(oem)): - # 11) A - # Starting from alpha9 we can consider that the structure is quite ok - # and that we should do only dela - deltaattr = delta_update_basesamdb(newpaths.samdb, - paths.samdb, - creds, - session, - lp, - message) - else: - # 11) B - simple_update_basesamdb(newpaths, paths, names) - ldbs = get_ldbs(paths, creds, session, lp) - removeProvisionUSN(ldbs.sam) - - ldbs.startTransactions() - minUSN = int(str(get_max_usn(ldbs.sam, str(names.rootdn)))) + 1 - new_ldbs.startTransactions() - - # 12) - schema = Schema(names.domainsid, schemadn=str(names.schemadn)) - # We create a closure that will be invoked just before schema reload - def schemareloadclosure(): - basesam = Ldb(paths.samdb, session_info=session, credentials=creds, lp=lp, - options=["modules:"]) - doit = False - if deltaattr is not None and len(deltaattr) > 1: - doit = True - if doit: - deltaattr.remove("dn") + # Let's see provision parameters + print_provision_key_parameters(names) + + # 5) With all this information let's create a fresh new provision used as + # reference + message(SIMPLE, "Creating a reference provision") + provisiondir = tempfile.mkdtemp(dir=paths.private_dir, + prefix="referenceprovision") + newprovision(names, creds, session, smbconf, provisiondir, + provision_logger) + + # TODO + # 6) and 7) + # We need to get a list of object which SD is directly computed from + # defaultSecurityDescriptor. + # This will allow us to know which object we can rebuild the SD in case + # of change of the parent's SD or of the defaultSD. + # Get file paths of this new provision + newpaths = get_paths(param, targetdir=provisiondir) + new_ldbs = get_ldbs(newpaths, creds, session, lp) + new_ldbs.startTransactions() + + # 8) Populate some associative array to ease the update process + # List of attribute which are link and backlink + populate_links(new_ldbs.sam, names.schemadn) + # List of attribute with ASN DN synthax) + populate_dnsyntax(new_ldbs.sam, names.schemadn) + # 9) + update_privilege(newpaths.private_dir, paths.private_dir) + # 10) + oem = getOEMInfo(ldbs.sam, str(names.rootdn)) + # Do some modification on sam.ldb + ldbs.groupedCommit() + new_ldbs.groupedCommit() + deltaattr = None + # 11) + if re.match(".*alpha((9)|(\d\d+)).*", str(oem)): + # 11) A + # Starting from alpha9 we can consider that the structure is quite ok + # and that we should do only dela + deltaattr = delta_update_basesamdb(newpaths.samdb, + paths.samdb, + creds, + session, + lp, + message) + else: + # 11) B + simple_update_basesamdb(newpaths, paths, names) + ldbs = get_ldbs(paths, creds, session, lp) + removeProvisionUSN(ldbs.sam) + + ldbs.startTransactions() + minUSN = int(str(get_max_usn(ldbs.sam, str(names.rootdn)))) + 1 + new_ldbs.startTransactions() + + # 12) + schema = Schema(names.domainsid, schemadn=str(names.schemadn)) + # We create a closure that will be invoked just before schema reload + def schemareloadclosure(): + basesam = Ldb(paths.samdb, session_info=session, credentials=creds, lp=lp, + options=["modules:"]) + doit = False + if deltaattr is not None and len(deltaattr) > 1: + doit = True + if doit: + deltaattr.remove("dn") for att in deltaattr: if att.lower() == "dn": continue @@ -1691,112 +1694,112 @@ if __name__ == '__main__': doit = False elif deltaattr.get(att) is None: doit = False - if doit: - message(CHANGE, "Applying delta to @ATTRIBUTES") - deltaattr.dn = ldb.Dn(basesam, "@ATTRIBUTES") - basesam.modify(deltaattr) + if doit: + message(CHANGE, "Applying delta to @ATTRIBUTES") + deltaattr.dn = ldb.Dn(basesam, "@ATTRIBUTES") + basesam.modify(deltaattr) + else: + message(CHANGE, "Not applying delta to @ATTRIBUTES because " + "there is not only add") + # 13) + if opts.full: + if not update_samdb(new_ldbs.sam, ldbs.sam, names, lastProvisionUSNs, + schema, schemareloadclosure): + message(SIMPLE, "Rolling back all changes. Check the cause" + " of the problem") + message(SIMPLE, "Your system is as it was before the upgrade") + ldbs.groupedRollback() + new_ldbs.groupedRollback() + shutil.rmtree(provisiondir) + sys.exit(1) else: - message(CHANGE, "Not applying delta to @ATTRIBUTES because " - "there is not only add") - # 13) - if opts.full: - if not update_samdb(new_ldbs.sam, ldbs.sam, names, lastProvisionUSNs, - schema, schemareloadclosure): - message(SIMPLE, "Rolling back all changes. Check the cause" - " of the problem") - message(SIMPLE, "Your system is as it was before the upgrade") - ldbs.groupedRollback() - new_ldbs.groupedRollback() - shutil.rmtree(provisiondir) - sys.exit(1) - else: - # Try to reapply the change also when we do not change the sam - # as the delta_upgrade - schemareloadclosure() - sync_calculated_attributes(ldbs.sam, names) + # Try to reapply the change also when we do not change the sam + # as the delta_upgrade + schemareloadclosure() + sync_calculated_attributes(ldbs.sam, names) + res = ldbs.sam.search(expression="(samaccountname=dns)", + scope=SCOPE_SUBTREE, attrs=["dn"], + controls=["search_options:1:2"]) + if len(res) > 0: + message(SIMPLE, "You still have the old DNS object for managing " + "dynamic DNS, but you didn't supply --full so " + "a correct update can't be done") + ldbs.groupedRollback() + new_ldbs.groupedRollback() + shutil.rmtree(provisiondir) + sys.exit(1) + # 14) + update_secrets(new_ldbs.secrets, ldbs.secrets, message) + # 14bis) res = ldbs.sam.search(expression="(samaccountname=dns)", - scope=SCOPE_SUBTREE, attrs=["dn"], - controls=["search_options:1:2"]) - if len(res) > 0: - message(SIMPLE, "You still have the old DNS object for managing " - "dynamic DNS, but you didn't supply --full so " - "a correct update can't be done") - ldbs.groupedRollback() - new_ldbs.groupedRollback() - shutil.rmtree(provisiondir) - sys.exit(1) - # 14) - update_secrets(new_ldbs.secrets, ldbs.secrets, message) - # 14bis) - res = ldbs.sam.search(expression="(samaccountname=dns)", - scope=SCOPE_SUBTREE, attrs=["dn"], - controls=["search_options:1:2"]) - - if (len(res) == 1): - ldbs.sam.delete(res[0]["dn"]) - res2 = ldbs.secrets.search(expression="(samaccountname=dns)", - scope=SCOPE_SUBTREE, attrs=["dn"]) - update_dns_account_password(ldbs.sam, ldbs.secrets, names) - message(SIMPLE, "IMPORTANT!!! " - "If you were using Dynamic DNS before you need " - "to update your configuration, so that the " - "tkey-gssapi-credential has the following value: " - "DNS/%s.%s" % (names.netbiosname.lower(), - names.realm.lower())) - # 15) - message(SIMPLE, "Update machine account") - update_machine_account_password(ldbs.sam, ldbs.secrets, names) - - # 16) 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 ... - if not re.match(r'.*alpha(9|\d\d+)', str(oem)): - message(SIMPLE, "Fixing old povision SD") - fix_partition_sd(ldbs.sam, names) - rebuild_sd(ldbs.sam, names) - - # We calculate the max USN before recalculating the SD because we might - # touch object that have been modified after a provision and we do not - # want that the next upgradeprovision thinks that it has a green light - # to modify them - - # 17) - maxUSN = get_max_usn(ldbs.sam, str(names.rootdn)) - - # 18) We rebuild SD only if defaultSecurityDescriptor is modified - # But in fact we should do it also if one object has its SD modified as - # child might need rebuild - if defSDmodified: - message(SIMPLE, "Updating SD") - ldbs.sam.set_session_info(adm_session) - # Alpha10 was a bit broken still - if re.match(r'.*alpha(\d|10)', str(oem)): + scope=SCOPE_SUBTREE, attrs=["dn"], + controls=["search_options:1:2"]) + + if (len(res) == 1): + ldbs.sam.delete(res[0]["dn"]) + res2 = ldbs.secrets.search(expression="(samaccountname=dns)", + scope=SCOPE_SUBTREE, attrs=["dn"]) + update_dns_account_password(ldbs.sam, ldbs.secrets, names) + message(SIMPLE, "IMPORTANT!!! " + "If you were using Dynamic DNS before you need " + "to update your configuration, so that the " + "tkey-gssapi-credential has the following value: " + "DNS/%s.%s" % (names.netbiosname.lower(), + names.realm.lower())) + # 15) + message(SIMPLE, "Update machine account") + update_machine_account_password(ldbs.sam, ldbs.secrets, names) + + # 16) 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 ... + if not re.match(r'.*alpha(9|\d\d+)', str(oem)): + message(SIMPLE, "Fixing old povision SD") fix_partition_sd(ldbs.sam, names) - rebuild_sd(ldbs.sam, names) - - # 19) - # Now we are quite confident in the recalculate process of the SD, we make - # it optional. - # Also the check must be done in a clever way as for the moment we just - # compare SDDL - if opts.debugchangesd: - check_updated_sd(new_ldbs.sam, ldbs.sam, names) - - # 20) - updateOEMInfo(ldbs.sam, str(names.rootdn)) - # 21) - check_for_DNS(newpaths.private_dir, paths.private_dir) - # 22) - if lastProvisionUSNs is not None: - update_provision_usn(ldbs.sam, minUSN, maxUSN) - if opts.full and (names.policyid is None or names.policyid_dc is None): - update_policyids(names, ldbs.sam) - if opts.full or opts.resetfileacl: + rebuild_sd(ldbs.sam, names) + + # We calculate the max USN before recalculating the SD because we might + # touch object that have been modified after a provision and we do not + # want that the next upgradeprovision thinks that it has a green light + # to modify them + + # 17) + maxUSN = get_max_usn(ldbs.sam, str(names.rootdn)) + + # 18) We rebuild SD only if defaultSecurityDescriptor is modified + # But in fact we should do it also if one object has its SD modified as + # child might need rebuild + if defSDmodified: + message(SIMPLE, "Updating SD") + ldbs.sam.set_session_info(adm_session) + # Alpha10 was a bit broken still + if re.match(r'.*alpha(\d|10)', str(oem)): + fix_partition_sd(ldbs.sam, names) + rebuild_sd(ldbs.sam, names) + + # 19) + # Now we are quite confident in the recalculate process of the SD, we make + # it optional. + # Also the check must be done in a clever way as for the moment we just + # compare SDDL + if opts.debugchangesd: + check_updated_sd(new_ldbs.sam, ldbs.sam, names) + + # 20) + updateOEMInfo(ldbs.sam, str(names.rootdn)) + # 21) + check_for_DNS(newpaths.private_dir, paths.private_dir) + # 22) + if lastProvisionUSNs is not None: + update_provision_usn(ldbs.sam, minUSN, maxUSN) + if opts.full and (names.policyid is None or names.policyid_dc is None): + update_policyids(names, ldbs.sam) + if opts.full or opts.resetfileacl or opts.fixntacl: try: update_gpo(paths, ldbs.sam, names, lp, message, 1) except ProvisioningError, e: message(ERROR, "The policy for domain controller is missing. " - "You should restart upgradeprovision with --full") + "You should restart upgradeprovision with --full") except IOError, e: message(ERROR, "Setting ACL not supported on your filesystem") else: @@ -1804,25 +1807,29 @@ if __name__ == '__main__': update_gpo(paths, ldbs.sam, names, lp, message, 0) except ProvisioningError, e: message(ERROR, "The policy for domain controller is missing. " - "You should restart upgradeprovision with --full") - ldbs.groupedCommit() - new_ldbs.groupedCommit() - message(SIMPLE, "Upgrade finished!") - # remove reference provision now that everything is done ! - # So we have reindexed first if need when the merged schema was reloaded - # (as new attributes could have quick in) - # But the second part of the update (when we update existing objects - # can also have an influence on indexing as some attribute might have their - # searchflag modificated - message(SIMPLE, "Reopenning samdb to trigger reindexing if needed " - "after modification") - samdb = Ldb(paths.samdb, session_info=session, credentials=creds, lp=lp) - message(SIMPLE, "Reindexing finished") - - shutil.rmtree(provisiondir) + "You should restart upgradeprovision with --full") + if not opts.fixntacl: + ldbs.groupedCommit() + new_ldbs.groupedCommit() + message(SIMPLE, "Upgrade finished!") + # remove reference provision now that everything is done ! + # So we have reindexed first if need when the merged schema was reloaded + # (as new attributes could have quick in) + # But the second part of the update (when we update existing objects + # can also have an influence on indexing as some attribute might have their + # searchflag modificated + message(SIMPLE, "Reopenning samdb to trigger reindexing if needed " + "after modification") + samdb = Ldb(paths.samdb, session_info=session, credentials=creds, lp=lp) + message(SIMPLE, "Reindexing finished") + + shutil.rmtree(provisiondir) + else: + ldbs.groupedRollback() + message(SIMPLE, "ACLs fixed !") except StandardError, err: message(ERROR, "A problem occurred while trying to upgrade your " - "provision. A full backup is located at %s" % backupdir) + "provision. A full backup is located at %s" % backupdir) if opts.debugall or opts.debugchange: (typ, val, tb) = sys.exc_info() traceback.print_exception(typ, val, tb) -- cgit From 6071ed67bf413b0f9245be9038e2e600d8ebb5aa Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Fri, 20 May 2011 19:43:19 +0400 Subject: s4-python: move function find_provision_key_parameters to provision namespace as it can be used not only for upgradeprovision --- source4/scripting/bin/upgradeprovision | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 4e48a48b45..e58a2647b6 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -44,7 +44,7 @@ from ldb import (SCOPE_SUBTREE, SCOPE_BASE, FLAG_MOD_REPLACE, FLAG_MOD_ADD, FLAG_MOD_DELETE, MessageElement, Message, Dn) from samba import param, dsdb, Ldb -from samba.provision import (get_domain_descriptor, +from samba.provision import (get_domain_descriptor, find_provision_key_parameters, get_config_descriptor, ProvisioningError, get_last_provision_usn, get_max_usn, update_provision_usn, setup_path) @@ -52,7 +52,7 @@ from samba.schema import get_linked_attributes, Schema, get_schema_descriptor from samba.dcerpc import security, drsblobs, xattr from samba.ndr import ndr_unpack from samba.upgradehelpers import (dn_sort, get_paths, newprovision, - find_provision_key_parameters, get_ldbs, + get_ldbs, usn_in_range, identic_rename, get_diff_sddls, update_secrets, CHANGE, ERROR, SIMPLE, CHANGEALL, GUESS, CHANGESD, PROVISION, -- cgit From b14bdf431b49a674bceab7f8f81ae98d938b92f6 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Sun, 5 Jun 2011 17:26:07 +0400 Subject: s4-upgradeprovision: Fix an error, so that cursddl and refsddl are not the same Thanks to Dirk Paulli for pointing it with his bug report. --- source4/scripting/bin/upgradeprovision | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index e58a2647b6..9d3b683940 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -905,7 +905,7 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): cursddl = cursd.as_sddl(names.domainsid) refsd = ndr_unpack(security.descriptor, str(reference[0]["nTSecurityDescriptor"])) - refsddl = cursd.as_sddl(names.domainsid) + refsddl = refsd.as_sddl(names.domainsid) if get_diff_sddls(refsddl, cursddl) == "": message(CHANGE, "sd are identical") -- cgit From 0065742909453f85709635aa44787b6998cccfc3 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Mon, 13 Jun 2011 17:13:26 +0400 Subject: s4-upgradeprovision: handle_special_attributes don't really need ranges of USNs, just the information if we are using replPropertyMetadata for attribute selection --- source4/scripting/bin/upgradeprovision | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 9d3b683940..c625625c44 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -297,7 +297,7 @@ def print_provision_key_parameters(names): message(GUESS, "domainlevel :" + str(names.domainlevel)) -def handle_special_case(att, delta, new, old, usn, basedn, aldb): +def handle_special_case(att, delta, new, old, useReplMetadata, basedn, aldb): """Define more complicate update rules for some attributes :param att: The attribute to be updated @@ -305,7 +305,8 @@ def handle_special_case(att, delta, new, old, usn, basedn, aldb): between the updated object and the reference one :param new: The reference object :param old: The Updated object - :param usn: The highest usn modified by a previous (upgrade)provision + :param useReplMetadata: A boolean that indicate if the update process + use replPropertyMetaData to decide what has to be updated. :param basedn: The base DN of the provision :param aldb: An ldb object used to build DN :return: True to indicate that the attribute should be kept, False for @@ -315,7 +316,7 @@ def handle_special_case(att, delta, new, old, usn, basedn, aldb): # We do most of the special case handle if we do not have the # highest usn as otherwise the replPropertyMetaData will guide us more # correctly - if usn is None: + if not useReplMetadata: if (att == "sPNMappings" and flag == FLAG_MOD_REPLACE and ldb.Dn(aldb, "CN=Directory Service,CN=Windows NT," "CN=Services,CN=Configuration,%s" % basedn) @@ -889,7 +890,7 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): # idea to change it delta.remove(att) continue - if handle_special_case(att, delta, reference, current, usns, basedn, samdb): + if handle_special_case(att, delta, reference, current, True, basedn, samdb): # This attribute is "complicated" to handle and handling # was done in handle_special_case continue @@ -959,7 +960,7 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): if not hashOverwrittenAtt.has_key(att): if msgElt.flags() != FLAG_MOD_ADD: if not handle_special_case(att, delta, reference, current, - usns, basedn, samdb): + False, basedn, samdb): if opts.debugchange or opts.debugall: try: dump_denied_change(dn, att, -- cgit From d9abcc93847fedf3ca272fe69cde0a92e76c85d0 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Mon, 13 Jun 2011 17:50:00 +0400 Subject: s4-upgradeprovision: split update_present in two functions depending on the method used In order to make the function a bit more clearer and with less depth, the selection of attribute that are not updated is split in two functions depending on the fact that we are using mainly replPropertyMetadata to make our choice or if we are using the list of attributes that should, could or shouldn't be updated/created/deleted. --- source4/scripting/bin/upgradeprovision | 301 +++++++++++++++++++-------------- 1 file changed, 171 insertions(+), 130 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index c625625c44..db42543723 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -774,6 +774,167 @@ msg_elt_flag_strs = { ldb.FLAG_MOD_REPLACE: "MOD_REPLACE", ldb.FLAG_MOD_DELETE: "MOD_DELETE" } +def checkKeepAttributeOldMtd(delta, att, reference, current, + basedn, samdb): + """ Check if we should keep the attribute modification or not. + This function didn't use replicationMetadata to take a decision. + + :param delta: A message diff object + :param att: An attribute + :param reference: A message object for the current entry comming from + the reference provision. + :param current: A message object for the current entry commin from + the current provision. + :param basedn: The DN of the partition + :param samdb: A ldb connection to the sam database of the current provision. + + :return: The modified message diff. + """ + # Old school way of handling things for pre alpha12 upgrade + global defSDmodified + isFirst = False + txt = "" + dn = current[0].dn + + for att in list(delta): + defSDmodified = True + msgElt = delta.get(att) + + if att == "nTSecurityDescriptor": + delta.remove(att) + continue + + if att == "dn": + continue + + if not hashOverwrittenAtt.has_key(att): + if msgElt.flags() != FLAG_MOD_ADD: + if not handle_special_case(att, delta, reference, current, + False, basedn, samdb): + if opts.debugchange or opts.debugall: + try: + dump_denied_change(dn, att, + msg_elt_flag_strs[msgElt.flags()], + current[0][att], reference[0][att]) + except KeyError: + dump_denied_change(dn, att, + msg_elt_flag_strs[msgElt.flags()], + current[0][att], None) + delta.remove(att) + continue + else: + if hashOverwrittenAtt.get(att)&2**msgElt.flags() : + continue + elif hashOverwrittenAtt.get(att)==never: + delta.remove(att) + continue + + return delta + +def checkKeepAttributeWithMetadata(delta, att, message, reference, current, + hash_attr_usn, basedn, usns, samdb): + """ Check if we should keep the attribute modification or not + + :param delta: A message diff object + :param att: An attribute + :param message: A function to print messages + :param reference: A message object for the current entry comming from + the reference provision. + :param current: A message object for the current entry commin from + the current provision. + :param hash_attr_usn: A dictionnary with attribute name as keys, + USN and invocation id as values. + :param basedn: The DN of the partition + :param usns: A dictionnary with invocation ID as keys and USN ranges + as values. + :param samdb: A ldb object pointing to the sam DB + + :return: The modified message diff. + """ + global defSDmodified + isFirst = False + txt = "" + dn = current[0].dn + + for att in list(delta): + # We have updated by provision usn information so let's exploit + # replMetadataProperties + if att in forwardlinked: + curval = current[0].get(att, ()) + refval = reference[0].get(att, ()) + handle_links(samdb, att, basedn, current[0]["dn"], + curval, refval, delta) + continue + + if isFirst and len(delta.items())>1: + isFirst = True + txt = "%s\n" % (str(dn)) + + keptAttr = ["dn", "rIDAvailablePool", "objectSid", "creationTime", "oEMInformation", "msDs-KeyVersionNumber"] + if att in keptAttr: + delta.remove(att) + continue + + if handle_special_case(att, delta, reference, current, True, None, None): + # This attribute is "complicated" to handle and handling + # was done in handle_special_case + continue + + attrUSN = None + if hash_attr_usn.get(att): + attrUSN = hash_attr_usn.get(att) + + if att == "forceLogoff" and attrUSN is None: + continue + if attrUSN is None: + delta.remove(att) + continue + if att == "nTSecurityDescriptor": + cursd = ndr_unpack(security.descriptor, + str(current[0]["nTSecurityDescriptor"])) + cursddl = cursd.as_sddl(names.domainsid) + refsd = ndr_unpack(security.descriptor, + str(reference[0]["nTSecurityDescriptor"])) + refsddl = refsd.as_sddl(names.domainsid) + + if get_diff_sddls(refsddl, cursddl) == "": + message(CHANGE, "sd are identical") + else: + message(CHANGE, "sd are not identical") + if attrUSN == -1: + # This attribute was last modified by another DC forget + # about it + message(CHANGE, "%sAttribute: %s has been " + "created/modified/deleted by another DC. " + "Doing nothing" % (txt, att)) + txt = "" + delta.remove(att) + continue + elif not usn_in_range(int(attrUSN), usns.get(attInvId)): + message(CHANGE, "%sAttribute: %s was not " + "created/modified/deleted during a " + "provision or upgradeprovision. Current " + "usn: %d. Doing nothing" % (txt, att, + attrUSN)) + txt = "" + delta.remove(att) + continue + else: + if att == "defaultSecurityDescriptor": + defSDmodified = True + if attrUSN: + message(CHANGE, "%sAttribute: %s will be modified" + "/deleted it was last modified " + "during a provision. Current usn: " + "%d" % (txt, att, attrUSN)) + txt = "" + else: + message(CHANGE, "%sAttribute: %s will be added because " + "it did not exist before" % (txt, att)) + txt = "" + continue + + return delta def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): """ This function updates the object that are already present in the @@ -788,7 +949,6 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): upgradeprovision :param invocationid: The value of the invocationid for the current DC""" - global defSDmodified # This hash is meant to speedup lookup of attribute name from an oid, # it's for the replPropertyMetaData handling hash_oid_name = {} @@ -805,6 +965,8 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): changed = 0 controls = ["search_options:1:2", "sd_flags:1:2"] + if usns is not None: + message(CHANGE, "Using replPropertyMetadata for change selection") for dn in listPresent: reference = ref_samdb.search(expression="dn=%s" % (str(dn)), base=basedn, scope=SCOPE_SUBTREE, @@ -826,9 +988,6 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): delta = samdb.msg_diff(current[0], reference[0]) - for att in hashAttrNotCopied.keys(): - delta.remove(att) - for att in backlinked: delta.remove(att) @@ -851,133 +1010,15 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): # Note we could just use 1 here hash_attr_usn[att] = o.originating_usn else: - hash_attr_usn[att] = -1 - - isFirst = 0 - txt = "" - - for att in list(delta): - if usns is not None: - # We have updated by provision usn information so let's exploit - # replMetadataProperties - if att in forwardlinked: - curval = current[0].get(att, ()) - refval = reference[0].get(att, ()) - handle_links(samdb, att, basedn, current[0]["dn"], - curval, refval, delta) - continue - - if isFirst == 0 and len(delta.items())>1: - isFirst = 1 - txt = "%s\n" % (str(dn)) - if att == "dn": - # There is always a dn attribute after a msg_diff - continue - if att == "rIDAvailablePool": - delta.remove(att) - continue - if att == "objectSid": - delta.remove(att) - continue - if att == "creationTime": - delta.remove(att) - continue - if att == "oEMInformation": - delta.remove(att) - continue - if att == "msDs-KeyVersionNumber": - # This is the kvno of the computer/user it's a very bad - # idea to change it - delta.remove(att) - continue - if handle_special_case(att, delta, reference, current, True, basedn, samdb): - # This attribute is "complicated" to handle and handling - # was done in handle_special_case - continue - attrUSN = hash_attr_usn.get(att) - if att == "forceLogoff" and attrUSN is None: - continue - if attrUSN is None: - delta.remove(att) - continue - if att == "nTSecurityDescriptor": - cursd = ndr_unpack(security.descriptor, - str(current[0]["nTSecurityDescriptor"])) - cursddl = cursd.as_sddl(names.domainsid) - refsd = ndr_unpack(security.descriptor, - str(reference[0]["nTSecurityDescriptor"])) - refsddl = refsd.as_sddl(names.domainsid) - - if get_diff_sddls(refsddl, cursddl) == "": - message(CHANGE, "sd are identical") - else: - message(CHANGE, "sd are not identical") - if attrUSN == -1: - # This attribute was last modified by another DC forget - # about it - message(CHANGE, "%sAttribute: %s has been " - "created/modified/deleted by another DC. " - "Doing nothing" % (txt, att)) - txt = "" - delta.remove(att) - continue - elif not usn_in_range(int(attrUSN), usns): - message(CHANGE, "%sAttribute: %s was not " - "created/modified/deleted during a " - "provision or upgradeprovision. Current " - "usn: %d. Doing nothing" % (txt, att, - attrUSN)) - txt = "" - delta.remove(att) - continue - else: - if att == "defaultSecurityDescriptor": - defSDmodified = True - if attrUSN: - message(CHANGE, "%sAttribute: %s will be modified" - "/deleted it was last modified " - "during a provision. Current usn: " - "%d" % (txt, att, attrUSN)) - txt = "" - else: - message(CHANGE, "%sAttribute: %s will be added because " - "it did not exist before" % (txt, att)) - txt = "" - continue - - else: - # Old school way of handling things for pre alpha12 upgrade - defSDmodified = True - msgElt = delta.get(att) - if att == "nTSecurityDescriptor": - delta.remove(att) - continue - - if att == "dn": - continue - - if not hashOverwrittenAtt.has_key(att): - if msgElt.flags() != FLAG_MOD_ADD: - if not handle_special_case(att, delta, reference, current, - False, basedn, samdb): - if opts.debugchange or opts.debugall: - try: - dump_denied_change(dn, att, - msg_elt_flag_strs[msgElt.flags()], - current[0][att], reference[0][att]) - except KeyError: - dump_denied_change(dn, att, - msg_elt_flag_strs[msgElt.flags()], - current[0][att], None) - delta.remove(att) - continue - else: - if hashOverwrittenAtt.get(att)&2**msgElt.flags() : - continue - elif hashOverwrittenAtt.get(att)==never: - delta.remove(att) - continue + if usns is not None: + delta = checkKeepAttributeWithMetadata(delta, att, message, reference, + current, hash_attr_usn, + basedn, usns, samdb) + else: + for att in hashAttrNotCopied.keys(): + delta.remove(att) + delta = checkKeepAttributeOldMtd(delta, att, reference, current, basedn, samdb) delta.dn = dn if len(delta.items()) >1: -- cgit From 71ab462c81b48169b34d60dd2bbeca137a15b702 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Mon, 13 Jun 2011 18:34:49 +0400 Subject: s4-upgradeprovision: add function to know if attribute is replicated or not --- source4/scripting/bin/upgradeprovision | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index db42543723..a9dffc0ab5 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -117,6 +117,7 @@ hashOverwrittenAtt = { "prefixMap": replace, "systemMayContain": replace, backlinked = [] forwardlinked = set() dn_syntax_att = [] +not_replicated = [] def define_what_to_log(opts): what = 0 if opts.debugchange: @@ -238,6 +239,25 @@ def populate_links(samdb, schemadn): for t in linkedAttHash.keys(): forwardlinked.add(t) +def isReplicated(att): + """ Indicate if the attribute is replicated or not + + :param att: Name of the attribute to be tested + :return: True is the attribute is replicated, False otherwise + """ + + return (att not in not_replicated) + +def populateNotReplicated(samdb, schemadn): + """Populate an array with all the attributes that are not replicated + + :param samdb: A LDB object for sam.ldb file + :param schemadn: DN of the schema for the partition""" + res = samdb.search(expression="(&(objectclass=attributeSchema)(systemflags:1.2.840.113556.1.4.803:=1))", base=Dn(samdb, + str(schemadn)), scope=SCOPE_SUBTREE, + attrs=["lDAPDisplayName"]) + for elem in res: + not_replicated.append(elem["lDAPDisplayName"]) def populate_dnsyntax(samdb, schemadn): """Populate an array with all the attributes that have DN synthax -- cgit From 20233cdf535b55ee3832d4844eb2109cccab5837 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Mon, 13 Jun 2011 17:39:06 +0400 Subject: s4-upgradeprovision: introduce invocation id in lastprovisionUSNs --- source4/scripting/bin/upgradeprovision | 46 +++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 12 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index a9dffc0ab5..7f11e404ab 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -902,10 +902,22 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current, attrUSN = None if hash_attr_usn.get(att): - attrUSN = hash_attr_usn.get(att) + [attrUSN, attInvId] = hash_attr_usn.get(att) + + if attrUSN is None: + # If it's a replicated attribute and we don't have any USN + # information about it. It means that we never saw it before + # so let's add it ! + # If it is a replicated attribute but we are not master on it + # (ie. not initially added in the provision we masterize). + # attrUSN will be -1 + if isReplicated(att): + continue + elif att in hashAttrNotCopied.keys(): + delta.remove(att) + else: + continue - if att == "forceLogoff" and attrUSN is None: - continue if attrUSN is None: delta.remove(att) continue @@ -956,7 +968,7 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current, return delta -def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): +def update_present(ref_samdb, samdb, basedn, listPresent, usns): """ This function updates the object that are already present in the provision @@ -966,8 +978,8 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): (ie. DC=foo, DC=bar) :param listPresent: A list of object that is present in the provision :param usns: A list of USN range modified by previous provision and - upgradeprovision - :param invocationid: The value of the invocationid for the current DC""" + upgradeprovision grouped by invocation ID + """ # This hash is meant to speedup lookup of attribute name from an oid, # it's for the replPropertyMetaData handling @@ -1026,10 +1038,10 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid): # We put in this hash only modification # made on the current host att = hash_oid_name[samdb.get_oid_from_attid(o.attid)] - if str(o.originating_invocation_id) == str(invocationid): - # Note we could just use 1 here - hash_attr_usn[att] = o.originating_usn + if str(o.originating_invocation_id) in usns.keys(): + hash_attr_usn[att] = [o.originating_usn, str(o.originating_invocation_id)] else: + hash_attr_usn[att] = [-1, None] if usns is not None: delta = checkKeepAttributeWithMetadata(delta, att, message, reference, @@ -1160,7 +1172,7 @@ def update_partition(ref_samdb, samdb, basedn, names, schema, provisionUSNs, pre message(SIMPLE, "Schema reloaded!") changed = update_present(ref_samdb, samdb, basedn, listPresent, - provisionUSNs, names.invocation) + provisionUSNs) message(SIMPLE, "There are %d changed objects" % (changed)) return 1 @@ -1665,9 +1677,19 @@ if __name__ == '__main__': # 4) lastProvisionUSNs = get_last_provision_usn(ldbs.sam) if lastProvisionUSNs is not None: + v = 0 + for k in lastProvisionUSNs.keys(): + for r in lastProvisionUSNs[k]: + v = v + 1 + message(CHANGE, - "Find a last provision USN, %d range(s)" % len(lastProvisionUSNs)) + "Find last provision USN, %d invocation(s) for a total of %d ranges" % \ + (len(lastProvisionUSNs.keys()), v /2 )) + if lastProvisionUSNs.get("default") != None: + message(CHANGE, "Old style for usn ranges used") + lastProvisionUSNs[str(names.invocation)] = lastProvisionUSNs["default"] + del lastProvisionUSNs["default"] # Objects will be created with the admin session # (not anymore system session) adm_session = admin_session(lp, str(names.domainsid)) @@ -1853,7 +1875,7 @@ if __name__ == '__main__': check_for_DNS(newpaths.private_dir, paths.private_dir) # 22) if lastProvisionUSNs is not None: - update_provision_usn(ldbs.sam, minUSN, maxUSN) + update_provision_usn(ldbs.sam, minUSN, maxUSN, names.invocation) if opts.full and (names.policyid is None or names.policyid_dc is None): update_policyids(names, ldbs.sam) if opts.full or opts.resetfileacl or opts.fixntacl: -- cgit From 9a18e07b4f186751cb25dfc0f947e6e5ca8f2fee Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Mon, 13 Jun 2011 17:56:17 +0400 Subject: s4-upgradeprovision: clean up, reformating and update docs --- source4/scripting/bin/upgradeprovision | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 7f11e404ab..85f21678d6 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -412,14 +412,14 @@ def handle_special_case(att, delta, new, old, useReplMetadata, basedn, aldb): if (att == "servicePrincipalName" and flag == FLAG_MOD_REPLACE): hash = {} newval = [] - changeDelta=0 + changeDelta = 0 for elem in old[0][att]: hash[str(elem)]=1 newval.append(str(elem)) for elem in new[0][att]: if not hash.has_key(str(elem)): - changeDelta=1 + changeDelta = 1 newval.append(str(elem)) if changeDelta == 1: delta[att] = MessageElement(newval, FLAG_MOD_REPLACE, att) @@ -1109,8 +1109,8 @@ def update_partition(ref_samdb, samdb, basedn, names, schema, provisionUSNs, pre :param basedn: String value of the DN of the partition :param names: List of key provision parameters :param schema: A Schema object - :param provisionUSNs: The USNs modified by provision/upgradeprovision - last time + :param provisionUSNs: A dictionnary with range of USN modified during provision + or upgradeprovision. Ranges are grouped by invocationID. :param prereloadfunc: A function that must be executed just before the reload of the schema """ @@ -1309,7 +1309,6 @@ def removeProvisionUSN(samdb): attrs = [samba.provision.LAST_PROVISION_USN_ATTRIBUTE, "dn"] entry = samdb.search(expression="dn=@PROVISION", base = "", scope=SCOPE_SUBTREE, - controls=["search_options:1:2"], attrs=attrs) empty = Message() empty.dn = entry[0].dn @@ -1379,7 +1378,7 @@ def update_privilege(ref_private_path, cur_private_path): os.path.join(cur_private_path, "privilege.ldb")) -def update_samdb(ref_samdb, samdb, names, highestUSN, schema, prereloadfunc): +def update_samdb(ref_samdb, samdb, names, provisionUSNs, schema, prereloadfunc): """Upgrade the SAM DB contents for all the provision partitions :param ref_sambdb: An LDB object conntected to the sam.ldb of the reference @@ -1387,8 +1386,8 @@ def update_samdb(ref_samdb, samdb, names, highestUSN, schema, prereloadfunc): :param samdb: An LDB object connected to the sam.ldb of the update provision :param names: List of key provision parameters - :param highestUSN: The highest USN modified by provision/upgradeprovision - last time + :param provisionUSNs: A dictionnary with range of USN modified during provision + or upgradeprovision. Ranges are grouped by invocationID. :param schema: A Schema object that represent the schema of the provision :param prereloadfunc: A function that must be executed just before the reload of the schema @@ -1396,7 +1395,7 @@ def update_samdb(ref_samdb, samdb, names, highestUSN, schema, prereloadfunc): message(SIMPLE, "Starting update of samdb") ret = update_partition(ref_samdb, samdb, str(names.rootdn), names, - schema, highestUSN, prereloadfunc) + schema, provisionUSNs, prereloadfunc) if ret: message(SIMPLE, "Update of samdb finished") return 1 -- cgit From 44c540625216b7f9754f7e9461bbd5d026a1e9cf Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Mon, 13 Jun 2011 17:15:37 +0400 Subject: s4-upgradeprovision: don't print dn in the list of modified attributes --- source4/scripting/bin/upgradeprovision | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 85f21678d6..b197c6cb84 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -1054,7 +1054,8 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns): delta.dn = dn if len(delta.items()) >1: - attributes=", ".join(delta.keys()) + # Skip dn as the value is not really changed ... + attributes=", ".join(delta.keys()[1:]) modcontrols = [] relaxedatt = ['iscriticalsystemobject', 'grouptype'] # Let's try to reduce as much as possible the use of relax control -- cgit From 01758595e3c01751f259e5b2edaf07beb982ed76 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Mon, 13 Jun 2011 18:37:51 +0400 Subject: s4-upgradeprovision: remove useless code --- source4/scripting/bin/upgradeprovision | 3 --- 1 file changed, 3 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index b197c6cb84..735757aa2c 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -918,9 +918,6 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current, else: continue - if attrUSN is None: - delta.remove(att) - continue if att == "nTSecurityDescriptor": cursd = ndr_unpack(security.descriptor, str(current[0]["nTSecurityDescriptor"])) -- cgit From 4305f54b8ef9fdcc1ca075b991e9dadab4b485c7 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Sun, 19 Jun 2011 00:02:03 +0400 Subject: s4-upgradeprovision: fix inverted logic and wrong flags on sd_flags control --- source4/scripting/bin/upgradeprovision | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 735757aa2c..b49ccf91c0 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -872,7 +872,7 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current, :return: The modified message diff. """ global defSDmodified - isFirst = False + isFirst = True txt = "" dn = current[0].dn @@ -887,7 +887,7 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current, continue if isFirst and len(delta.items())>1: - isFirst = True + isFirst = False txt = "%s\n" % (str(dn)) keptAttr = ["dn", "rIDAvailablePool", "objectSid", "creationTime", "oEMInformation", "msDs-KeyVersionNumber"] @@ -930,6 +930,7 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current, message(CHANGE, "sd are identical") else: message(CHANGE, "sd are not identical") + if attrUSN == -1: # This attribute was last modified by another DC forget # about it @@ -993,7 +994,7 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns): raise ProvisioningError(msg) changed = 0 - controls = ["search_options:1:2", "sd_flags:1:2"] + controls = ["search_options:1:2", "sd_flags:1:0"] if usns is not None: message(CHANGE, "Using replPropertyMetadata for change selection") for dn in listPresent: -- cgit From f76c206e2fd9af47767816e6b284e3742672b21a Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Mon, 13 Jun 2011 18:49:23 +0400 Subject: s4-upgradeprovision: change hashAttrNotCopied to be an array --- source4/scripting/bin/upgradeprovision | 48 ++++++++++++++++------------------ 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index b49ccf91c0..c353fe0749 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -81,20 +81,21 @@ __docformat__ = "restructuredText" # This is most probably because they are populated automatcally when object is # created # This also apply to imported object from reference provision -hashAttrNotCopied = { "dn": 1, "whenCreated": 1, "whenChanged": 1, - "objectGUID": 1, "uSNCreated": 1, - "replPropertyMetaData": 1, "uSNChanged": 1, - "parentGUID": 1, "objectCategory": 1, - "distinguishedName": 1, "nTMixedDomain": 1, - "showInAdvancedViewOnly": 1, "instanceType": 1, - "msDS-Behavior-Version":1, "nextRid":1, "cn": 1, - "lmPwdHistory":1, "pwdLastSet": 1, - "ntPwdHistory":1, "unicodePwd":1,"dBCSPwd":1, - "supplementalCredentials":1, "gPCUserExtensionNames":1, - "gPCMachineExtensionNames":1,"maxPwdAge":1, "secret":1, - "possibleInferiors":1, "privilege":1, - "sAMAccountType":1 } - +replAttrNotCopied = [ "dn", "whenCreated", "whenChanged", "objectGUID", + "parentGUID", "objectCategory", "distinguishedName", + "nTMixedDomain", "showInAdvancedViewOnly", + "instanceType", "msDS-Behavior-Version", "cn", + "lmPwdHistory", "pwdLastSet", "ntPwdHistory", + "unicodePwd", "dBCSPwd", "supplementalCredentials", + "gPCUserExtensionNames", "gPCMachineExtensionNames", + "maxPwdAge", "secret", "possibleInferiors", "privilege", + "sAMAccountType", "oEMInformation", "creationTime" ] + +nonreplAttrNotCopied = ["uSNCreated", "replPropertyMetaData", "uSNChanged", + "nextRid" ,"rIDNextRID"] + +attrNotCopied = replAttrNotCopied +attrNotCopied.extend(nonreplAttrNotCopied) # 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 them it's # mandatory to replace them otherwise the provision will be broken somehow. @@ -606,7 +607,7 @@ def add_missing_object(ref_samdb, samdb, dn, names, basedn, hash, index): m = re.match(r".*-(\d+)$", sid) if m and int(m.group(1))>999: delta.remove("objectSid") - for att in hashAttrNotCopied.keys(): + for att in attrNotCopied: delta.remove(att) for att in backlinked: delta.remove(att) @@ -673,7 +674,7 @@ def add_deletedobj_containers(ref_samdb, samdb, names): delta = samdb.msg_diff(empty, reference[0]) delta.dn = Dn(samdb, str(reference[0]["dn"])) - for att in hashAttrNotCopied.keys(): + for att in attrNotCopied: delta.remove(att) modcontrols = ["relax:0", "provision:0"] @@ -890,11 +891,6 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current, isFirst = False txt = "%s\n" % (str(dn)) - keptAttr = ["dn", "rIDAvailablePool", "objectSid", "creationTime", "oEMInformation", "msDs-KeyVersionNumber"] - if att in keptAttr: - delta.remove(att) - continue - if handle_special_case(att, delta, reference, current, True, None, None): # This attribute is "complicated" to handle and handling # was done in handle_special_case @@ -913,9 +909,8 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current, # attrUSN will be -1 if isReplicated(att): continue - elif att in hashAttrNotCopied.keys(): - delta.remove(att) else: + message(CHANGE, "Non replicated attribute %s changed" % att) continue if att == "nTSecurityDescriptor": @@ -1021,6 +1016,9 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns): for att in backlinked: delta.remove(att) + for att in attrNotCopied: + delta.remove(att) + delta.remove("name") if len(delta.items()) > 1 and usns is not None: @@ -1046,8 +1044,6 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns): current, hash_attr_usn, basedn, usns, samdb) else: - for att in hashAttrNotCopied.keys(): - delta.remove(att) delta = checkKeepAttributeOldMtd(delta, att, reference, current, basedn, samdb) delta.dn = dn @@ -1611,7 +1607,7 @@ def sync_calculated_attributes(samdb, names): # This resulting object is filtered to remove all the back link attribute # (ie. memberOf) as they will be created by the other linked object (ie. # the one with the member attribute) -# All attributes specified in the hashAttrNotCopied associative array are +# All attributes specified in the attrNotCopied array are # also removed it's most of the time generated attributes # After missing entries have been added the update_partition function will -- cgit From 0e729149259055e9310c1dee78fce71a744006ab Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Mon, 13 Jun 2011 22:59:35 +0400 Subject: s4-upgradeprovision: dn must be skipped as delta.remove("dn") do not remove this attribute --- source4/scripting/bin/upgradeprovision | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index c353fe0749..79cf97dce4 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -878,6 +878,9 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current, dn = current[0].dn for att in list(delta): + if att == "dn": + # dn is not removable + continue # We have updated by provision usn information so let's exploit # replMetadataProperties if att in forwardlinked: -- cgit From 930d2f28c99d5cf8823ca0837a632e13cead9fce Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Mon, 13 Jun 2011 23:23:05 +0400 Subject: s4-upgradeprovision: if there is nothing to really modify then skip it --- source4/scripting/bin/upgradeprovision | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 79cf97dce4..b214c4c8fd 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -1024,6 +1024,9 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns): delta.remove("name") + if len(delta.items()) == 1: + continue + if len(delta.items()) > 1 and usns is not None: # Fetch the replPropertyMetaData res = samdb.search(expression="dn=%s" % (str(dn)), base=basedn, -- cgit From f7a903ee8085bb041cae8fdf603997e66245f35f Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Tue, 14 Jun 2011 01:39:41 +0400 Subject: s4-upgradeprovision: add a list of attribute that are not DSDB attribute that we don't want to copy --- source4/scripting/bin/upgradeprovision | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index b214c4c8fd..e2d5cb0fb8 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -94,8 +94,12 @@ replAttrNotCopied = [ "dn", "whenCreated", "whenChanged", "objectGUID", nonreplAttrNotCopied = ["uSNCreated", "replPropertyMetaData", "uSNChanged", "nextRid" ,"rIDNextRID"] +nonDSDBAttrNotCopied = ["msDS-KeyVersionNumber", "priorSecret", "priorWhenChanged"] + + attrNotCopied = replAttrNotCopied attrNotCopied.extend(nonreplAttrNotCopied) +attrNotCopied.extend(nonDSDBAttrNotCopied) # 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 them it's # mandatory to replace them otherwise the provision will be broken somehow. -- cgit From bc7b8fa108bf27f78c69f5aec3e408e59555c232 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Tue, 14 Jun 2011 01:41:56 +0400 Subject: s4-upgradeprovision: ignore objectSid --- source4/scripting/bin/upgradeprovision | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index e2d5cb0fb8..bf06a3c4f7 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -882,9 +882,10 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current, dn = current[0].dn for att in list(delta): - if att == "dn": - # dn is not removable + if att in ["dn", "objectSid"]: + delta.remove(att) continue + # We have updated by provision usn information so let's exploit # replMetadataProperties if att in forwardlinked: -- cgit From c0eb4037585e1feb609d7acef196c4dc8872960b Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Tue, 14 Jun 2011 01:42:28 +0400 Subject: s4-upgradeprovision: remove useless comment --- source4/scripting/bin/upgradeprovision | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index bf06a3c4f7..a5a42a9d46 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -1064,7 +1064,6 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns): modcontrols = [] relaxedatt = ['iscriticalsystemobject', 'grouptype'] # Let's try to reduce as much as possible the use of relax control - #for checkedatt in relaxedatt: for attr in delta.keys(): if attr.lower() in relaxedatt: modcontrols = ["relax:0", "provision:0"] -- cgit From 5e81ee8b341c3c6a6f9a321ec6ddf9b29932b683 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Tue, 14 Jun 2011 01:42:59 +0400 Subject: s4-upgradeprovision: Rework completly how SDs are recalculated --- source4/scripting/bin/upgradeprovision | 165 ++++++++++++++++++++------------- 1 file changed, 99 insertions(+), 66 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index a5a42a9d46..284b0e0ef8 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -42,7 +42,7 @@ from samba.credentials import DONT_USE_KERBEROS from samba.auth import system_session, admin_session from ldb import (SCOPE_SUBTREE, SCOPE_BASE, FLAG_MOD_REPLACE, FLAG_MOD_ADD, FLAG_MOD_DELETE, - MessageElement, Message, Dn) + MessageElement, Message, Dn, LdbError) from samba import param, dsdb, Ldb from samba.provision import (get_domain_descriptor, find_provision_key_parameters, get_config_descriptor, @@ -119,6 +119,8 @@ hashOverwrittenAtt = { "prefixMap": replace, "systemMayContain": replace, "attributeDisplayNames": replace + add, "versionNumber": add} +dnNotToRecalculate = [] +dnToRecalculate = [] backlinked = [] forwardlinked = set() dn_syntax_att = [] @@ -822,10 +824,10 @@ def checkKeepAttributeOldMtd(delta, att, reference, current, dn = current[0].dn for att in list(delta): - defSDmodified = True msgElt = delta.get(att) if att == "nTSecurityDescriptor": + defSDmodified = True delta.remove(att) continue @@ -929,10 +931,25 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current, str(reference[0]["nTSecurityDescriptor"])) refsddl = refsd.as_sddl(names.domainsid) - if get_diff_sddls(refsddl, cursddl) == "": - message(CHANGE, "sd are identical") + diff = get_diff_sddls(refsddl, cursddl) + if diff == "": + # FIXME find a way to have it only with huge huge verbose mode + # message(CHANGE, "%ssd are identical" % txt) + # txt = "" + delta.remove(att) + continue else: - message(CHANGE, "sd are not identical") + delta.remove(att) + message(CHANGESD, "%ssd are not identical:\n%s" % (txt, diff)) + txt = "" + if attrUSN == -1: + message(CHANGESD, "But the SD has been changed by someonelse "\ + "so it's impossible to know if the difference"\ + " cames from the modification or from a previous bug") + dnNotToRecalculate.append(str(dn)) + else: + dnToRecalculate.append(str(dn)) + continue if attrUSN == -1: # This attribute was last modified by another DC forget @@ -1219,7 +1236,7 @@ def check_updated_sd(ref_sam, cur_sam, names): str(current[i]["nTSecurityDescriptor"])) sddl = cursd.as_sddl(names.domainsid) if sddl != hash[key]: - txt = get_diff_sddls(hash[key], sddl) + txt = get_diff_sddls(hash[key], sddl, False) if txt != "": message(CHANGESD, "On object %s ACL is different" " \n%s" % (current[i]["dn"], txt)) @@ -1233,37 +1250,38 @@ def fix_partition_sd(samdb, names): :param samdb: An LDB object pointing to the sam of the current provision :param names: A list of key provision parameters """ + alwaysRecalculate = False + if len(dnToRecalculate) == 0 and len(dnNotToRecalculate) == 0: + alwaysRecalculate = True + + + # NC's DN can't be both in dnToRecalculate and dnNotToRecalculate # First update the SD for the rootdn - res = samdb.search(expression="objectClass=*", base=str(names.rootdn), - scope=SCOPE_BASE, attrs=["dn", "whenCreated"], - controls=["search_options:1:2"]) - delta = Message() - delta.dn = Dn(samdb, str(res[0]["dn"])) - descr = get_domain_descriptor(names.domainsid) - delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, - "nTSecurityDescriptor") - samdb.modify(delta) + if alwaysRecalculate or str(names.rootdn) in dnToRecalculate: + delta = Message() + delta.dn = Dn(samdb, str(names.rootdn)) + descr = get_domain_descriptor(names.domainsid) + delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, + "nTSecurityDescriptor") + samdb.modify(delta) + # Then the config dn - res = samdb.search(expression="objectClass=*", base=str(names.configdn), - scope=SCOPE_BASE, attrs=["dn", "whenCreated"], - controls=["search_options:1:2"]) - delta = Message() - delta.dn = Dn(samdb, str(res[0]["dn"])) - descr = get_config_descriptor(names.domainsid) - delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, - "nTSecurityDescriptor" ) - samdb.modify(delta) - # Then the schema dn - res = samdb.search(expression="objectClass=*", base=str(names.schemadn), - scope=SCOPE_BASE, attrs=["dn", "whenCreated"], - controls=["search_options:1:2"]) + if alwaysRecalculate or str(names.configdn) in dnToRecalculate: + delta = Message() + delta.dn = Dn(samdb, str(names.configdn)) + descr = get_config_descriptor(names.domainsid) + delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, + "nTSecurityDescriptor" ) + samdb.modify(delta) - delta = Message() - delta.dn = Dn(samdb, str(res[0]["dn"])) - descr = get_schema_descriptor(names.domainsid) - delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, - "nTSecurityDescriptor" ) - samdb.modify(delta) + # Then the schema dn + if alwaysRecalculate or str(names.schemadn) in dnToRecalculate: + delta = Message() + delta.dn = Dn(samdb, str(names.schemadn)) + descr = get_schema_descriptor(names.domainsid) + delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, + "nTSecurityDescriptor" ) + samdb.modify(delta) def rebuild_sd(samdb, names): """Rebuild security descriptor of the current provision from scratch @@ -1276,30 +1294,46 @@ def rebuild_sd(samdb, names): :param names: List of key provision parameters""" + fix_partition_sd(samdb, names) + # List of namming contexts + listNC = [str(names.rootdn), str(names.configdn), str(names.schemadn)] hash = {} - res = samdb.search(expression="objectClass=*", base=str(names.rootdn), + if len(dnToRecalculate) == 0: + res = samdb.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: + for obj in res: + hash[str(obj["dn"])] = obj["whenCreated"] + else: + for dn in dnToRecalculate: + if hash.has_key(dn): + continue + # fetch each dn to recalculate and their child within the same partition + res = samdb.search(expression="objectClass=*", base=dn, + scope=SCOPE_SUBTREE, attrs=["dn", "whenCreated"]) + for obj in res: + hash[str(obj["dn"])] = obj["whenCreated"] + + listKeys = list(set(hash.keys())) + listKeys.sort(dn_sort) + + if len(dnToRecalculate) != 0: + message(CHANGESD, "%d DNs have been marked as needed to be recalculated"\ + ", recalculating %d due to inheritance" + % (len(dnToRecalculate), len(listKeys))) + + for key in listKeys: + if (key in listNC or + key in dnNotToRecalculate): + continue + delta = Message() + delta.dn = Dn(samdb, key) try: - delta = Message() - delta.dn = Dn(samdb, key) delta["whenCreated"] = MessageElement(hash[key], FLAG_MOD_REPLACE, "whenCreated" ) - samdb.modify(delta, ["recalculate_sd:0"]) - except: - # XXX: We should always catch an explicit exception. - # What could go wrong here? + samdb.modify(delta, ["recalculate_sd:0","relax:0"]) + except LdbError, e: samdb.transaction_cancel() res = samdb.search(expression="objectClass=*", base=str(names.rootdn), scope=SCOPE_SUBTREE, @@ -1307,7 +1341,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) + message(ERROR, "On %s bad stuff %s" % (str(delta.dn),badsd.as_sddl(names.domainsid))) return def removeProvisionUSN(samdb): @@ -1838,12 +1872,12 @@ if __name__ == '__main__': message(SIMPLE, "Update machine account") update_machine_account_password(ldbs.sam, ldbs.secrets, names) + dnToRecalculate.sort(dn_sort) # 16) 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 ... - if not re.match(r'.*alpha(9|\d\d+)', str(oem)): - message(SIMPLE, "Fixing old povision SD") - fix_partition_sd(ldbs.sam, names) + if str(oem) != "" and not re.match(r'.*alpha(9|\d\d+)', str(oem)): + message(SIMPLE, "Fixing very old provision SD") rebuild_sd(ldbs.sam, names) # We calculate the max USN before recalculating the SD because we might @@ -1854,23 +1888,22 @@ if __name__ == '__main__': # 17) maxUSN = get_max_usn(ldbs.sam, str(names.rootdn)) - # 18) We rebuild SD only if defaultSecurityDescriptor is modified - # But in fact we should do it also if one object has its SD modified as - # child might need rebuild - if defSDmodified: - message(SIMPLE, "Updating SD") + # 18) We rebuild SD if a we have a list of DN to recalculate or if the + # defSDmodified is set. + if defSDmodified or len(dnToRecalculate) >0: + message(SIMPLE, "Some defaultSecurityDescriptors and/or" + "securityDescriptor have changed, recalculating SD ") ldbs.sam.set_session_info(adm_session) - # Alpha10 was a bit broken still - if re.match(r'.*alpha(\d|10)', str(oem)): - fix_partition_sd(ldbs.sam, names) - rebuild_sd(ldbs.sam, names) + rebuild_sd(ldbs.sam, names) # 19) # Now we are quite confident in the recalculate process of the SD, we make - # it optional. + # it optional. And we don't do it if there is DN that we must touch + # as we are assured that on this DNs we will have differences ! # Also the check must be done in a clever way as for the moment we just # compare SDDL - if opts.debugchangesd: + if len(dnNotToRecalculate) == 0 and (opts.debugchangesd or opts.debugall): + message(CHANGESD, "Checking recalculated SDs") check_updated_sd(new_ldbs.sam, ldbs.sam, names) # 20) -- cgit From 05b2d4147a75a652f8f773d353b62a4c10821155 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Wed, 15 Jun 2011 15:20:46 +0400 Subject: s4-upgradeprovision: deltaattr can be empty or none too --- source4/scripting/bin/upgradeprovision | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 284b0e0ef8..9bf09bd432 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -1808,14 +1808,14 @@ if __name__ == '__main__': doit = True if doit: deltaattr.remove("dn") - for att in deltaattr: - if att.lower() == "dn": - continue - if (deltaattr.get(att) is not None - and deltaattr.get(att).flags() != FLAG_MOD_ADD): - doit = False - elif deltaattr.get(att) is None: - doit = False + for att in deltaattr: + if att.lower() == "dn": + continue + if (deltaattr.get(att) is not None + and deltaattr.get(att).flags() != FLAG_MOD_ADD): + doit = False + elif deltaattr.get(att) is None: + doit = False if doit: message(CHANGE, "Applying delta to @ATTRIBUTES") deltaattr.dn = ldb.Dn(basesam, "@ATTRIBUTES") -- cgit From 8a19e1ecfb716579e662d2d6b6bceeccbf7e7741 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Sun, 19 Jun 2011 01:17:27 +0400 Subject: s4-upgradeprovision: skip versionNumber, it's used by GPO --- source4/scripting/bin/upgradeprovision | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 9bf09bd432..45c14e0027 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -113,6 +113,7 @@ hashOverwrittenAtt = { "prefixMap": replace, "systemMayContain": replace, "wellKnownObjects":replace, "privilege":never, "defaultSecurityDescriptor": replace, "rIDAvailablePool": never, + "versionNumber" : add, "rIDNextRID": add, "rIDUsedPool": never, "defaultSecurityDescriptor": replace + add, "isMemberOfPartialAttributeSet": delete, -- cgit From 01ce078ed166635c29e89bd012c82e3612393f28 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Mon, 20 Jun 2011 01:05:04 +0400 Subject: s4-upgradeprovision: propose the use of findprovisionranges if no ranges are present Autobuild-User: Matthieu Patou Autobuild-Date: Mon Jun 20 00:30:59 CEST 2011 on sn-devel-104 --- source4/scripting/bin/upgradeprovision | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 45c14e0027..f10a9fcc9c 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -44,6 +44,7 @@ from ldb import (SCOPE_SUBTREE, SCOPE_BASE, FLAG_MOD_REPLACE, FLAG_MOD_ADD, FLAG_MOD_DELETE, MessageElement, Message, Dn, LdbError) from samba import param, dsdb, Ldb +from samba.common import confirm from samba.provision import (get_domain_descriptor, find_provision_key_parameters, get_config_descriptor, ProvisioningError, get_last_provision_usn, @@ -1729,6 +1730,19 @@ if __name__ == '__main__': message(CHANGE, "Old style for usn ranges used") lastProvisionUSNs[str(names.invocation)] = lastProvisionUSNs["default"] del lastProvisionUSNs["default"] + else: + message(SIMPLE, "Your provision lacks provision range information") + if confirm("Do you want to run findprovisionusnranges to try to find them ?", False): + ldbs.groupedRollback() + os.system("%s %s %s %s %s" % (os.path.join(os.path.dirname(sys.argv[0]), + "findprovisionusnranges"), + "--storedir", + paths.private_dir, + "-s", + smbconf)) + message(SIMPLE, "Once you applied/adapted the change(s) please restart the upgradeprovision script") + sys.exit(0) + # Objects will be created with the admin session # (not anymore system session) adm_session = admin_session(lp, str(names.domainsid)) -- cgit From c2dfaa2580918cf31069c1063ff07a819ca0554a Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Tue, 21 Jun 2011 13:37:26 +0400 Subject: s4-upgradeprovision: Don't forget to populate the non replicated objects, and don't touch rIDPreviousAllocationPool --- source4/scripting/bin/upgradeprovision | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/scripting/bin/upgradeprovision') diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index f10a9fcc9c..e98b642776 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -93,7 +93,7 @@ replAttrNotCopied = [ "dn", "whenCreated", "whenChanged", "objectGUID", "sAMAccountType", "oEMInformation", "creationTime" ] nonreplAttrNotCopied = ["uSNCreated", "replPropertyMetaData", "uSNChanged", - "nextRid" ,"rIDNextRID"] + "nextRid" ,"rIDNextRID", "rIDPreviousAllocationPool"] nonDSDBAttrNotCopied = ["msDS-KeyVersionNumber", "priorSecret", "priorWhenChanged"] @@ -266,7 +266,8 @@ def populateNotReplicated(samdb, schemadn): str(schemadn)), scope=SCOPE_SUBTREE, attrs=["lDAPDisplayName"]) for elem in res: - not_replicated.append(elem["lDAPDisplayName"]) + not_replicated.append(str(elem["lDAPDisplayName"])) + def populate_dnsyntax(samdb, schemadn): """Populate an array with all the attributes that have DN synthax @@ -1778,6 +1779,7 @@ if __name__ == '__main__': new_ldbs = get_ldbs(newpaths, creds, session, lp) new_ldbs.startTransactions() + populateNotReplicated(new_ldbs.sam, names.schemadn) # 8) Populate some associative array to ease the update process # List of attribute which are link and backlink populate_links(new_ldbs.sam, names.schemadn) -- cgit