The branch, master has been updated via 0f8ef5a selftest: Add test of upgradeprovision using the old alpha13 tree via 58d6d88 samba_upgradeprovision: detect dns_backend for the reference provision via b855df2 provision: setup names.dns_backend via 4752731 samba_upgradeprovision: fix the nTSecurityDescriptor on more containers (bug #9481) via 5cf9882 provision: fix nTSecurityDescriptor of containers in the DnsZones (bug #9481) via a477649 provision: fix nTSecurityDescriptor attributes of CN=*,${CONFIGDN} (bug #9481) via 1de5c2f provision: fix nTSecurityDescriptor of CN={LostAndFound,System},${DOMAINDN} (bug #9481) via 4775f9a provision: setup names.name_map['DnsAdmins'] via e0712a7 provision: introduce names.name_map = {} via ebb73f1 provision: add get_dns_{forest,domain}_microsoft_dns_descriptor() via d00fb6a provision: add get_config_ntds_quotas_descriptor() via 1207cbd provision: add get_{config,domain}_delete_protected*_descriptor() via 8880c2d schema.py: add optional name_map={} to get_schema_descriptor() via 27a99c6 provision: add optional name_map={} argument to get_*_descriptor() via d4653e9 provision: import/export get_dns_partition_descriptor() via b54b58e provision: setup names.dns{forest,domain}dn via f512483 samba_upgradeprovision: fix resetting of 'nTSecurityDescriptor' on schema objects via b5cafa3 samba_upgradeprovision: don't reset 'whenCreated' when resetting 'nTSecurityDescriptor' via ec466aa dbckecker: fix nTSecurityDescriptor values from before 4.0.0rc6 (bug #9481) via 38655a8 dsdb-descriptor: get_default_group() should always return the DAG sid (bug #9481) via cd5cb84 tests/sec_descriptor: the default owner behavior depends on domainControllerFunctionality (bug #9481) via 2413962 libcli/security: calculate INHERIT_ONLY correcty for AUDIT and ALARM aces (bug #9481) from b9f1c88 s4-process_single: Use pid,task_id as cluster_id in process_single just like process_prefork
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 0f8ef5a2c83e0496ef79c3d6f8b1188fdd1943a0 Author: Andrew Bartlett <abart...@samba.org> Date: Tue Jan 22 23:39:15 2013 +1100 selftest: Add test of upgradeprovision using the old alpha13 tree This ensures that upgradeprovision works as expected on a known good old database. Andrew Bartlett Reviewed-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Andrew Bartlett <abart...@samba.org> Autobuild-Date(master): Sun Jan 27 11:55:54 CET 2013 on sn-devel-104 commit 58d6d884cf8a8de5a1fa2dfd4a0cbacdff0d2483 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jan 25 09:36:47 2013 +0100 samba_upgradeprovision: detect dns_backend for the reference provision If we have a DomainDnsZone partition, we use BIND9_DLZ as backend and fix errors in the ForestDnsZone and DomainDnsZone partitions. Note: this should work fine also for SAMBA_INTERNAL. If the current setup doesn't use dns specific partitions (e.g. alpha13 setups) we pass dns_backend=BIND9_FLATFILE. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit b855df254de40d9de0b7f9042564f6d521ab1c5d Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jan 25 09:36:47 2013 +0100 provision: setup names.dns_backend If we have a DomainDnsZone partition: - we use BIND9_DLZ as backend if a dns-<netbiosname> account is available - otherwise, we use SAMBA_INTERNAL else: - we use BIND9_FLATFILE if a dns or dns-<netbiosname> account is available - otherwise, we use NONE Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 4752731c2eb4abeb0b5da3e33aa3096786301a19 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Dec 13 12:56:37 2012 +0100 samba_upgradeprovision: fix the nTSecurityDescriptor on more containers (bug #9481) Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 5cf98823cc804906833f7ea763f99de0147b0fee Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 16:27:17 2013 +0100 provision: fix nTSecurityDescriptor of containers in the DnsZones (bug #9481) Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit a477649e568577875be577c70a6b25cbeea6985a Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 16:27:17 2013 +0100 provision: fix nTSecurityDescriptor attributes of CN=*,${CONFIGDN} (bug #9481) Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 1de5c2f78544385d2fe270d766fc1ca6726d71fb Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 16:27:17 2013 +0100 provision: fix nTSecurityDescriptor of CN={LostAndFound,System},${DOMAINDN} (bug #9481) Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 4775f9ab345072e63d671e83ae2c054fd2f80c3b Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 15:45:33 2013 +0100 provision: setup names.name_map['DnsAdmins'] Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit e0712a70f5a437eb60df3cebedbbe1c6c08bd6ae Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 15:43:54 2013 +0100 provision: introduce names.name_map = {} This will be used to translated names in SDDL values, which are not wellknown, e.g. 'DnsAdmins'. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit ebb73f1c5d577c1d32c5c0519dcf3fb25c578c45 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 15:55:31 2013 +0100 provision: add get_dns_{forest,domain}_microsoft_dns_descriptor() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit d00fb6aff2f54b470304d3d77a53328bcbb16851 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 15:39:07 2013 +0100 provision: add get_config_ntds_quotas_descriptor() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 1207cbd123375f0ff1bfc51403af5d611a621091 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 10:51:10 2013 +0100 provision: add get_{config,domain}_delete_protected*_descriptor() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 8880c2d0d356e7208ca859e17caf208952af0e17 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 15:53:00 2013 +0100 schema.py: add optional name_map={} to get_schema_descriptor() This is not used, but makes the prototype compatible with the other get_*_descriptor() functions. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 27a99c6236ab270a592b4e3242f92f8923a3d7e4 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 15:51:37 2013 +0100 provision: add optional name_map={} argument to get_*_descriptor() This will allow subsitute non-wellkown names in the SDDL, e.g. 'DnsAdmins'. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit d4653e99b8be35b6d86605a1c4c624d5db2294b1 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 09:05:36 2013 +0100 provision: import/export get_dns_partition_descriptor() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit b54b58e75d3c1a3080e81c61156b75ef1d241b71 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 08:56:00 2013 +0100 provision: setup names.dns{forest,domain}dn Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit f51248339ae7ba9843e477493a69b0c4f647935a Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 15:24:11 2013 +0100 samba_upgradeprovision: fix resetting of 'nTSecurityDescriptor' on schema objects Without this schema_data_modify() will reject updates to schema objects by default. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit b5cafa3b84e6cca5ca83fbcc0963def7d0c286d5 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 23 15:23:13 2013 +0100 samba_upgradeprovision: don't reset 'whenCreated' when resetting 'nTSecurityDescriptor' Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit ec466aa35656764c8a8af724cda692f2302a0c04 Author: Stefan Metzmacher <me...@samba.org> Date: Sat Jan 19 09:41:00 2013 +0100 dbckecker: fix nTSecurityDescriptor values from before 4.0.0rc6 (bug #9481) They inherited effective ACE for the wrong object classes. For SACL ACEs the problem was also present in 4.0.0. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 38655a89cf902d0ea6657415e2f546c7622e279d Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jan 24 22:59:26 2013 +0100 dsdb-descriptor: get_default_group() should always return the DAG sid (bug #9481) Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit cd5cb843b4d698ed2fedf635a020ff978ae40558 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jan 24 13:07:32 2013 +0100 tests/sec_descriptor: the default owner behavior depends on domainControllerFunctionality (bug #9481) Not on the domainFunctionality. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 2413962d53c7923a453fc7579b24b90bc23173df Author: Stefan Metzmacher <me...@samba.org> Date: Tue Jan 22 15:38:07 2013 +0100 libcli/security: calculate INHERIT_ONLY correcty for AUDIT and ALARM aces (bug #9481) Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> ----------------------------------------------------------------------- Summary of changes: libcli/security/create_descriptor.c | 20 ++- selftest/tests.py | 1 + source4/dsdb/samdb/ldb_modules/descriptor.c | 15 +- source4/dsdb/tests/python/sec_descriptor.py | 8 +- source4/scripting/bin/samba_upgradeprovision | 150 +++++++++++----- source4/scripting/python/samba/dbchecker.py | 183 +++++++++++++++++++- .../scripting/python/samba/provision/__init__.py | 91 ++++++++++- .../scripting/python/samba/provision/descriptor.py | 118 +++++++++---- .../scripting/python/samba/provision/sambadns.py | 30 ++-- source4/scripting/python/samba/schema.py | 2 +- source4/scripting/python/samba/upgradehelpers.py | 3 +- .../provisions/alpha13/etc/smb.conf.template | 10 +- source4/setup/provision.ldif | 2 + source4/setup/provision_configuration.ldif | 6 + source4/setup/provision_configuration_modify.ldif | 6 + source4/setup/provision_dnszones_add.ldif | 4 + source4/setup/provision_well_known_sec_princ.ldif | 1 + testprogs/blackbox/upgradeprovision-alpha13.sh | 135 ++++++++++++++ 18 files changed, 670 insertions(+), 115 deletions(-) create mode 100644 source4/setup/provision_configuration_modify.ldif create mode 100755 testprogs/blackbox/upgradeprovision-alpha13.sh Changeset truncated at 500 lines: diff --git a/libcli/security/create_descriptor.c b/libcli/security/create_descriptor.c index 42ca1a7..23e7e9b 100644 --- a/libcli/security/create_descriptor.c +++ b/libcli/security/create_descriptor.c @@ -165,6 +165,8 @@ static struct security_acl *calculate_inherited_from_parent(TALLOC_CTX *mem_ctx, struct security_ace *ace = &acl->aces[i]; if ((ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) || (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT)) { + struct GUID inherited_object = GUID_zero(); + tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces, struct security_ace, tmp_acl->num_aces+1); @@ -184,10 +186,18 @@ static struct security_acl *calculate_inherited_from_parent(TALLOC_CTX *mem_ctx, if (is_container && (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT)) tmp_acl->aces[tmp_acl->num_aces].flags |= SEC_ACE_FLAG_INHERIT_ONLY; - if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || - ace->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT) { - struct GUID inherited_object = GUID_zero(); - + switch (ace->type) { + case SEC_ACE_TYPE_ACCESS_ALLOWED: + case SEC_ACE_TYPE_ACCESS_DENIED: + case SEC_ACE_TYPE_SYSTEM_AUDIT: + case SEC_ACE_TYPE_SYSTEM_ALARM: + case SEC_ACE_TYPE_ALLOWED_COMPOUND: + break; + + case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: + case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: + case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: + case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) { inherited_object = ace->object.object.inherited_type.inherited_type; } @@ -196,7 +206,9 @@ static struct security_acl *calculate_inherited_from_parent(TALLOC_CTX *mem_ctx, tmp_acl->aces[tmp_acl->num_aces].flags |= SEC_ACE_FLAG_INHERIT_ONLY; } + break; } + tmp_acl->num_aces++; if (is_container) { if (!(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) && diff --git a/selftest/tests.py b/selftest/tests.py index d845834..03bedfc 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -46,6 +46,7 @@ planpythontestsuite("none", "samba.tests.messaging") planpythontestsuite("none", "samba.tests.samba3sam") planpythontestsuite("none", "wafsamba.tests.test_suite", extra_path=[os.path.join(samba4srcdir, "..", "buildtools"), os.path.join(samba4srcdir, "..", "buildtools", "wafadmin")]) plantestsuite("samba4.blackbox.dbcheck.alpha13", "none" , ["PYTHON=%s" % python, os.path.join(bbdir, "dbcheck-alpha13.sh"), '$PREFIX_ABS/provision', configuration]) +plantestsuite("samba4.blackbox.upgradeprovision.alpha13", "none" , ["PYTHON=%s" % python, os.path.join(bbdir, "upgradeprovision-alpha13.sh"), '$PREFIX_ABS/provision', configuration]) planpythontestsuite("none", "samba.tests.upgradeprovision") planpythontestsuite("none", "samba.tests.xattr") planpythontestsuite("none", "samba.tests.ntacls") diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c index fb100f7..d9bc89f 100644 --- a/source4/dsdb/samdb/ldb_modules/descriptor.c +++ b/source4/dsdb/samdb/ldb_modules/descriptor.c @@ -153,11 +153,16 @@ static struct dom_sid *get_default_group(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct dom_sid *dag) { - if (dsdb_functional_level(ldb) >= DS_DOMAIN_FUNCTION_2008) { - return dag; - } - - return NULL; + /* + * This depends on the function level of the DC + * which is 2008R2 in our case. Which means it is + * higher than 2003 and we should use the + * "default administrator group" also as owning group. + * + * This matches dcpromo for a 2003 domain + * on a Windows 2008R2 DC. + */ + return dag; } static struct security_descriptor *descr_handle_sd_flags(TALLOC_CTX *mem_ctx, diff --git a/source4/dsdb/tests/python/sec_descriptor.py b/source4/dsdb/tests/python/sec_descriptor.py index 78cd052..10d3718 100755 --- a/source4/dsdb/tests/python/sec_descriptor.py +++ b/source4/dsdb/tests/python/sec_descriptor.py @@ -313,10 +313,10 @@ class OwnerGroupDescriptorTests(DescriptorTests): "175" : "O:DAG:DA", }, } - # Discover 'msDS-Behavior-Version' - res = self.ldb_admin.search(base=self.base_dn, expression="distinguishedName=%s" % self.base_dn, \ - attrs=['msDS-Behavior-Version']) - res = int(res[0]['msDS-Behavior-Version'][0]) + # Discover 'domainControllerFunctionality' + res = self.ldb_admin.search(base="", scope=SCOPE_BASE, + attrs=['domainControllerFunctionality']) + res = int(res[0]['domainControllerFunctionality'][0]) if res < DS_DOMAIN_FUNCTION_2008: self.DS_BEHAVIOR = "ds_behavior_win2003" else: diff --git a/source4/scripting/bin/samba_upgradeprovision b/source4/scripting/bin/samba_upgradeprovision index 7060b73..e2c57f2 100755 --- a/source4/scripting/bin/samba_upgradeprovision +++ b/source4/scripting/bin/samba_upgradeprovision @@ -45,8 +45,26 @@ from ldb import (SCOPE_SUBTREE, SCOPE_BASE, 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, get_empty_descriptor, +from samba.provision import (find_provision_key_parameters, + get_empty_descriptor, + get_config_descriptor, + get_config_partitions_descriptor, + get_config_sites_descriptor, + get_config_ntds_quotas_descriptor, + get_config_delete_protected1_descriptor, + get_config_delete_protected1wd_descriptor, + get_config_delete_protected2_descriptor, + get_domain_descriptor, + get_domain_infrastructure_descriptor, + get_domain_builtin_descriptor, + get_domain_computers_descriptor, + get_domain_users_descriptor, + get_domain_controllers_descriptor, + get_domain_delete_protected1_descriptor, + get_domain_delete_protected2_descriptor, + get_dns_partition_descriptor, + get_dns_forest_microsoft_dns_descriptor, + get_dns_domain_microsoft_dns_descriptor, ProvisioningError, get_last_provision_usn, get_max_usn, update_provision_usn, setup_path) from samba.schema import get_linked_attributes, Schema, get_schema_descriptor @@ -210,7 +228,7 @@ creds.set_kerberos_state(DONT_USE_KERBEROS) -def check_for_DNS(refprivate, private): +def check_for_DNS(refprivate, private, dns_backend): """Check if the provision has already the requirement for dynamic dns :param refprivate: The path to the private directory of the reference @@ -220,10 +238,6 @@ def check_for_DNS(refprivate, private): spnfile = "%s/spn_update_list" % private dnsfile = "%s/dns_update_list" % private - namedfile = lp.get("dnsupdate:path") - - if not namedfile: - namedfile = "%s/named.conf.update" % private if not os.path.exists(spnfile): shutil.copy("%s/spn_update_list" % refprivate, "%s" % spnfile) @@ -231,10 +245,16 @@ def check_for_DNS(refprivate, private): if not os.path.exists(dnsfile): shutil.copy("%s/dns_update_list" % refprivate, "%s" % dnsfile) - destdir = "%s/new_dns" % private - dnsdir = "%s/dns" % private + if dns_backend not in ['BIND9_DLZ', 'BIND9_FLATFILE']: + return + namedfile = lp.get("dnsupdate:path") + if not namedfile: + namedfile = "%s/named.conf.update" % private if not os.path.exists(namedfile): + destdir = "%s/new_dns" % private + dnsdir = "%s/dns" % private + if not os.path.exists(destdir): os.mkdir(destdir) if not os.path.exists(dnsdir): @@ -1269,8 +1289,8 @@ def check_updated_sd(ref_sam, cur_sam, names): -def fix_partition_sd(samdb, names): - """This function fix the SD for partition containers (basedn, configdn, ...) +def fix_wellknown_sd(samdb, names): + """This function fix the SD for partition/wellknown containers (basedn, configdn, ...) This is needed because some provision use to have broken SD on containers :param samdb: An LDB object pointing to the sam of the current provision @@ -1280,34 +1300,73 @@ def fix_partition_sd(samdb, names): if len(dnToRecalculate) == 0 and len(dnNotToRecalculate) == 0: alwaysRecalculate = True + list_wellknown_dns = [] + + # Then subcontainers + subcontainers = [ + ("%s" % str(names.domaindn), get_domain_descriptor), + ("CN=LostAndFound,%s" % str(names.domaindn), get_domain_delete_protected2_descriptor), + ("CN=System,%s" % str(names.domaindn), get_domain_delete_protected1_descriptor), + ("CN=Infrastructure,%s" % str(names.domaindn), get_domain_infrastructure_descriptor), + ("CN=Builtin,%s" % str(names.domaindn), get_domain_builtin_descriptor), + ("CN=Computers,%s" % str(names.domaindn), get_domain_computers_descriptor), + ("CN=Users,%s" % str(names.domaindn), get_domain_users_descriptor), + ("OU=Domain Controllers,%s" % str(names.domaindn), get_domain_controllers_descriptor), + ("CN=MicrosoftDNS,CN=System,%s" % str(names.domaindn), get_dns_domain_microsoft_dns_descriptor), + + ("%s" % str(names.configdn), get_config_descriptor), + ("CN=NTDS Quotas,%s" % str(names.configdn), get_config_ntds_quotas_descriptor), + ("CN=LostAndFoundConfig,%s" % str(names.configdn), get_config_delete_protected1wd_descriptor), + ("CN=Services,%s" % str(names.configdn), get_config_delete_protected1_descriptor), + ("CN=Physical Locations,%s" % str(names.configdn), get_config_delete_protected1wd_descriptor), + ("CN=WellKnown Security Principals,%s" % str(names.configdn), get_config_delete_protected1wd_descriptor), + ("CN=ForestUpdates,%s" % str(names.configdn), get_config_delete_protected1wd_descriptor), + ("CN=DisplaySpecifiers,%s" % str(names.configdn), get_config_delete_protected2_descriptor), + ("CN=Extended-Rights,%s" % str(names.configdn), get_config_delete_protected2_descriptor), + ("CN=Partitions,%s" % str(names.configdn), get_config_partitions_descriptor), + ("CN=Sites,%s" % str(names.configdn), get_config_sites_descriptor), + + ("%s" % str(names.schemadn), get_schema_descriptor), + ] + + if names.dnsforestdn is not None: + c = ("%s" % str(names.dnsforestdn), get_dns_partition_descriptor) + subcontainers.append(c) + c = ("CN=Infrastructure,%s" % str(names.dnsforestdn), + get_domain_delete_protected1_descriptor) + subcontainers.append(c) + c = ("CN=LostAndFound,%s" % str(names.dnsforestdn), + get_domain_delete_protected2_descriptor) + subcontainers.append(c) + c = ("CN=MicrosoftDNS,%s" % str(names.dnsforestdn), + get_dns_forest_microsoft_dns_descriptor) + subcontainers.append(c) + + if names.dnsdomaindn is not None: + c = ("%s" % str(names.dnsdomaindn), get_dns_partition_descriptor) + subcontainers.append(c) + c = ("CN=Infrastructure,%s" % str(names.dnsdomaindn), + get_domain_delete_protected1_descriptor) + subcontainers.append(c) + c = ("CN=LostAndFound,%s" % str(names.dnsdomaindn), + get_domain_delete_protected2_descriptor) + subcontainers.append(c) + c = ("CN=MicrosoftDNS,%s" % str(names.dnsdomaindn), + get_dns_domain_microsoft_dns_descriptor) + subcontainers.append(c) + + for [dn, descriptor_fn] in subcontainers: + list_wellknown_dns.append(dn) + if alwaysRecalculate or dn in dnToRecalculate: + delta = Message() + delta.dn = Dn(samdb, str(dn)) + descr = descriptor_fn(names.domainsid, name_map=names.name_map) + delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, + "nTSecurityDescriptor" ) + samdb.modify(delta) + message(CHANGESD, "nTSecurityDescriptor updated on wellknown DN: %s" % delta.dn) - # NC's DN can't be both in dnToRecalculate and dnNotToRecalculate - # First update the SD for the rootdn - 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 - 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) - - # 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) + return list_wellknown_dns def rebuild_sd(samdb, names): """Rebuild security descriptor of the current provision from scratch @@ -1320,10 +1379,8 @@ def rebuild_sd(samdb, names): :param names: List of key provision parameters""" - fix_partition_sd(samdb, names) + listWellknown = fix_wellknown_sd(samdb, names) - # List of namming contexts - listNC = [str(names.rootdn), str(names.configdn), str(names.schemadn)] hash = {} if len(dnToRecalculate) == 0: res = samdb.search(expression="objectClass=*", base=str(names.rootdn), @@ -1350,19 +1407,18 @@ def rebuild_sd(samdb, names): % (len(dnToRecalculate), len(listKeys))) for key in listKeys: - if (key in listNC or - key in dnNotToRecalculate): + if key in listWellknown: + continue + if key in dnNotToRecalculate: continue delta = Message() delta.dn = Dn(samdb, key) sd_flags = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL | SECINFO_SACL try: - delta["whenCreated"] = MessageElement(hash[key], FLAG_MOD_REPLACE, - "whenCreated" ) descr = get_empty_descriptor(names.domainsid) delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE, "nTSecurityDescriptor") - samdb.modify(delta, ["sd_flags:1:%d" % sd_flags,"relax:0"]) + samdb.modify(delta, ["sd_flags:1:%d" % sd_flags,"relax:0","local_oid:%s:0" % dsdb.DSDB_CONTROL_DBCHECK]) except LdbError, e: samdb.transaction_cancel() res = samdb.search(expression="objectClass=*", base=str(delta.dn), @@ -1910,7 +1966,7 @@ if __name__ == '__main__': # 20) updateOEMInfo(ldbs.sam, str(names.rootdn)) # 21) - check_for_DNS(newpaths.private_dir, paths.private_dir) + check_for_DNS(newpaths.private_dir, paths.private_dir, names.dns_backend) # 22) if lastProvisionUSNs is not None: update_provision_usn(ldbs.sam, minUSN, maxUSN, names.invocation) diff --git a/source4/scripting/python/samba/dbchecker.py b/source4/scripting/python/samba/dbchecker.py index bc68457..06fd827 100644 --- a/source4/scripting/python/samba/dbchecker.py +++ b/source4/scripting/python/samba/dbchecker.py @@ -21,9 +21,10 @@ import ldb from samba import dsdb from samba import common from samba.dcerpc import misc -from samba.ndr import ndr_unpack +from samba.ndr import ndr_unpack, ndr_pack from samba.dcerpc import drsblobs from samba.common import dsdb_Dn +from samba.dcerpc import security class dbcheck(object): @@ -49,6 +50,7 @@ class dbcheck(object): self.fix_all_missing_backlinks = False self.fix_all_orphaned_backlinks = False self.fix_rmd_flags = False + self.fix_ntsecuritydescriptor = False self.seize_fsmo_role = False self.move_to_lost_and_found = False self.fix_instancetype = False @@ -58,6 +60,7 @@ class dbcheck(object): self.schema_dn = samdb.get_schema_basedn() self.rid_dn = ldb.Dn(samdb, "CN=RID Manager$,CN=System," + samdb.domain_dn()) self.ntds_dsa = samdb.get_dsServiceName() + self.class_schemaIDGUID = {} res = self.samdb.search(base=self.ntds_dsa, scope=ldb.SCOPE_BASE, attrs=['msDS-hasMasterNCs', 'hasMasterNCs']) if "msDS-hasMasterNCs" in res[0]: @@ -548,6 +551,164 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) "Failed to fix metadata for attribute %s" % attr): self.report("Fixed metadata for attribute %s" % attr) + def ace_get_effective_inherited_type(self, ace): + if ace.flags & security.SEC_ACE_FLAG_INHERIT_ONLY: + return None + + check = False + if ace.type == security.SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: + check = True + elif ace.type == security.SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: + check = True + elif ace.type == security.SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: + check = True + elif ace.type == security.SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: + check = True + + if not check: + return None + + if not ace.object.flags & security.SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT: + return None + + return str(ace.object.inherited_type) + + def lookup_class_schemaIDGUID(self, cls): + if cls in self.class_schemaIDGUID: + return self.class_schemaIDGUID[cls] + + flt = "(&(ldapDisplayName=%s)(objectClass=classSchema))" % cls + res = self.samdb.search(base=self.schema_dn, + expression=flt, + attrs=["schemaIDGUID"]) + t = str(ndr_unpack(misc.GUID, res[0]["schemaIDGUID"][0])) + + self.class_schemaIDGUID[cls] = t + return t + + def process_sd(self, dn, obj): + sd_attr = "nTSecurityDescriptor" + sd_val = obj[sd_attr] + + sd = ndr_unpack(security.descriptor, str(sd_val)) + + is_deleted = 'isDeleted' in obj and obj['isDeleted'][0].upper() == 'TRUE' + if is_deleted: + # we don't fix deleted objects + return (sd, None) + + sd_clean = security.descriptor() + sd_clean.owner_sid = sd.owner_sid + sd_clean.group_sid = sd.group_sid + sd_clean.type = sd.type + sd_clean.revision = sd.revision + + broken = False + last_inherited_type = None + + aces = [] + if sd.sacl is not None: + aces = sd.sacl.aces + for i in range(0, len(aces)): + ace = aces[i] + + if not ace.flags & security.SEC_ACE_FLAG_INHERITED_ACE: + sd_clean.sacl_add(ace) + continue + + t = self.ace_get_effective_inherited_type(ace) + if t is None: + continue + + if last_inherited_type is not None: + if t != last_inherited_type: + # if it inherited from more than + # one type it's very likely to be broken + # + # If not the recalculation will calculate + # the same result. + broken = True + continue + + last_inherited_type = t + + aces = [] + if sd.dacl is not None: + aces = sd.dacl.aces + for i in range(0, len(aces)): + ace = aces[i] + + if not ace.flags & security.SEC_ACE_FLAG_INHERITED_ACE: + sd_clean.dacl_add(ace) + continue + + t = self.ace_get_effective_inherited_type(ace) + if t is None: + continue + + if last_inherited_type is not None: + if t != last_inherited_type: + # if it inherited from more than + # one type it's very likely to be broken + # + # If not the recalculation will calculate + # the same result. + broken = True + continue + + last_inherited_type = t + + if broken: + return (sd_clean, sd) + + if last_inherited_type is None: + # ok + return (sd, None) + + cls = None + try: + cls = obj["objectClass"][-1] + except KeyError, e: + pass + + if cls is None: + res = self.samdb.search(base=dn, scope=ldb.SCOPE_BASE, + attrs=["isDeleted", "objectClass"], + controls=["show_recycled:1"]) + o = res[0] + is_deleted = 'isDeleted' in o and o['isDeleted'][0].upper() == 'TRUE' + if is_deleted: + # we don't fix deleted objects + return (sd, None) + cls = o["objectClass"][-1] + + t = self.lookup_class_schemaIDGUID(cls) -- Samba Shared Repository