The branch, master has been updated via 28598e7 s4-dfs: Use a workaround for ndr relative pointer bug/limitation via 0d2019d s4-torture: Add more tests to DFS referral suite via 6553940 torture: adapt to idl evolution via c590c3a s4-dfs: clean the code via 3478e3a s4-dfs: fix bugs in idl and adapt code accordingly via d24a22f s4-python: add an option for just fixing gpo folders via 2a5ff15 s4-python: keep wheel_gid as an integer via c2ac747 s4-python: raise an error if unable to bind remote ldap while joining from 8cf14c2 Fix the SMB2 showstopper, found by an extended torture test from Volker.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 28598e79330f37abbb709e2b317dde9c8d6c90b5 Author: Matthieu Patou <m...@matws.net> Date: Mon May 16 20:51:20 2011 +0400 s4-dfs: Use a workaround for ndr relative pointer bug/limitation Autobuild-User: Matthieu Patou <m...@samba.org> Autobuild-Date: Tue May 17 01:33:27 CEST 2011 on sn-devel-104 commit 0d2019dcbaad7f82319c1aac1aae51ab45e77c52 Author: Matthieu Patou <m...@matws.net> Date: Sun May 15 22:17:46 2011 +0400 s4-torture: Add more tests to DFS referral suite commit 6553940c0176298eb25bac850db55363c991cdec Author: root <root@ares.(none)> Date: Sun May 15 16:25:15 2011 +0400 torture: adapt to idl evolution commit c590c3a47c39aeb79a8bce502a5477b62e36bbd7 Author: Matthieu Patou <m...@matws.net> Date: Sun May 15 22:18:19 2011 +0400 s4-dfs: clean the code commit 3478e3add376a291e4b4e3acfe92b2df22287142 Author: Matthieu Patou <m...@matws.net> Date: Sun May 15 19:56:25 2011 +0400 s4-dfs: fix bugs in idl and adapt code accordingly commit d24a22fe9a414bf37859967848c45f2a7494193d Author: Matthieu Patou <m...@matws.net> Date: Sun May 15 16:06:18 2011 +0400 s4-python: add an option for just fixing gpo folders commit 2a5ff1513fe07894e0f9f8ee3ac6fd5ea87a4a6d Author: Matthieu Patou <m...@matws.net> Date: Sun May 15 16:02:54 2011 +0400 s4-python: keep wheel_gid as an integer commit c2ac7473f38a1e61499f6cf01ce9de19bcd3abc6 Author: Matthieu Patou <m...@matws.net> Date: Fri May 13 16:04:07 2011 +0400 s4-python: raise an error if unable to bind remote ldap while joining ----------------------------------------------------------------------- Summary of changes: librpc/idl/dfsblobs.idl | 17 +- source4/scripting/bin/upgradeprovision | 385 +++++++++++----------- source4/scripting/python/samba/join.py | 11 + source4/scripting/python/samba/upgradehelpers.py | 2 +- source4/smb_server/smb/trans2.c | 141 +++++---- source4/torture/dfs/domaindfs.c | 124 +++++--- source4/torture/ndr/dfsblob.c | 2 +- 7 files changed, 361 insertions(+), 321 deletions(-) Changeset truncated at 500 lines: diff --git a/librpc/idl/dfsblobs.idl b/librpc/idl/dfsblobs.idl index 6151c3f..7b8795d 100644 --- a/librpc/idl/dfsblobs.idl +++ b/librpc/idl/dfsblobs.idl @@ -53,7 +53,6 @@ interface dfsblobs [relative_short] nstring *DFS_path; [relative_short] nstring *DFS_alt_path; [relative_short] nstring *netw_address; - /* As stated in MS DFSC 2.2.4.3.1 this array was guid but now MUST be 16 null bytes*/ } dfs_normal_referral; typedef struct { @@ -74,32 +73,20 @@ interface dfsblobs } dfs_padding; typedef [flag(NDR_NOALIGN)] struct { + uint16 size; DFS_SERVER_TYPE server_type; DFS_FLAGS_REFERRAL entry_flags; uint32 ttl; [switch_is(entry_flags & DFS_FLAG_REFERRAL_DOMAIN_RESP)] dfs_referral referrals; - } dfs_referral_v3_remaining; - - typedef [flag(NDR_NOALIGN)] struct { - uint16 size; - dfs_referral_v3_remaining data; /* this is either 0 or 16 bytes */ [switch_is(size - 18)] dfs_padding service_site_guid; } dfs_referral_v3; - typedef struct { - uint16 size; - DFS_SERVER_TYPE server_type; - DFS_FLAGS_REFERRAL entry_flags; - uint32 ttl; - dfs_normal_referral r1; - } dfs_referral_v4; - typedef [nodiscriminant] union { [case(1)] dfs_referral_v1 v1; [case(2)] dfs_referral_v2 v2; [case(3)] dfs_referral_v3 v3; - [case(4)] dfs_referral_v4 v4; + [case(4)] dfs_referral_v3 v4; [default]; } dfs_referral_version; diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 8c79917..4e48a48 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) diff --git a/source4/scripting/python/samba/join.py b/source4/scripting/python/samba/join.py index c0aee71..b586e2c 100644 --- a/source4/scripting/python/samba/join.py +++ b/source4/scripting/python/samba/join.py @@ -36,6 +36,11 @@ import talloc # this makes debugging easier talloc.enable_null_tracking() +class DCJoinException(Exception): + + def __init__(self, msg): + super(DCJoinException, self).__init__("Can't join, error: %s" % msg) + class dc_join(object): '''perform a DC join''' @@ -62,6 +67,12 @@ class dc_join(object): session_info=system_session(), credentials=ctx.creds, lp=ctx.lp) + try: + ctx.samdb.search(scope=ldb.SCOPE_ONELEVEL, attrs=["dn"]) + except ldb.LdbError, (enum, estr): + raise DCJoinException(estr) + + -- Samba Shared Repository