From 6ec887605f740f10e20588eea90b3d10390d1638 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Jan 2013 15:38:07 +0100 Subject: [PATCH 01/22] libcli/security: calculate INHERIT_ONLY correcty for AUDIT and ALARM aces (bug #9481) Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 2413962d53c7923a453fc7579b24b90bc23173df) --- libcli/security/create_descriptor.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) 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) && -- 1.7.9.5 From 0518c109828129e4499e896f1bf056189163b5cc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jan 2013 13:07:32 +0100 Subject: [PATCH 02/22] tests/sec_descriptor: the default owner behavior depends on domainControllerFunctionality (bug #9481) Not on the domainFunctionality. Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit cd5cb843b4d698ed2fedf635a020ff978ae40558) --- source4/dsdb/tests/python/sec_descriptor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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: -- 1.7.9.5 From 98ac9a33ed5ac440e5758a361f0280021ec8019b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jan 2013 22:59:26 +0100 Subject: [PATCH 03/22] dsdb-descriptor: get_default_group() should always return the DAG sid (bug #9481) Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 38655a89cf902d0ea6657415e2f546c7622e279d) --- source4/dsdb/samdb/ldb_modules/descriptor.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) 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, -- 1.7.9.5 From 8d2c08852eaeb19880941070e6607bf5635c0115 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 19 Jan 2013 09:41:00 +0100 Subject: [PATCH 04/22] 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 Reviewed-by: Andrew Bartlett (cherry picked from commit ec466aa35656764c8a8af724cda692f2302a0c04) --- source4/scripting/python/samba/dbchecker.py | 183 ++++++++++++++++++++++++++- 1 file changed, 181 insertions(+), 2 deletions(-) diff --git a/source4/scripting/python/samba/dbchecker.py b/source4/scripting/python/samba/dbchecker.py index e1be6c4..d0f4048 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']) if "msDS-hasMasterNCs" in res[0]: @@ -540,6 +543,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) + + if t != last_inherited_type: + # broken + return (sd_clean, sd) + + # ok + return (sd, None) + + def err_wrong_sd(self, dn, sd, sd_broken): + '''re-write replPropertyMetaData elements for a single attribute for a + object. This is used to fix missing replPropertyMetaData elements''' + sd_attr = "nTSecurityDescriptor" + sd_val = ndr_pack(sd) + sd_flags = security.SECINFO_DACL | security.SECINFO_SACL + + if not self.confirm_all('Fix %s on %s?' % (sd_attr, dn), 'fix_ntsecuritydescriptor'): + self.report('Not fixing %s on %s\n' % (sd_attr, dn)) + return + + nmsg = ldb.Message() + nmsg.dn = dn + nmsg[sd_attr] = ldb.MessageElement(sd_val, ldb.FLAG_MOD_REPLACE, sd_attr) + if self.do_modify(nmsg, ["sd_flags:1:%d" % sd_flags], + "Failed to fix metadata for attribute %s" % sd_attr): + self.report("Fixed attribute '%s' of '%s'\n" % (sd_attr, dn)) + def is_fsmo_role(self, dn): if dn == self.samdb.domain_dn: return True @@ -580,8 +741,19 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) attrs.append("replPropertyMetaData") try: + sd_flags = 0 + sd_flags |= security.SECINFO_OWNER + sd_flags |= security.SECINFO_GROUP + sd_flags |= security.SECINFO_DACL + sd_flags |= security.SECINFO_SACL + res = self.samdb.search(base=dn, scope=ldb.SCOPE_BASE, - controls=["extended_dn:1:1", "show_recycled:1", "show_deleted:1"], + controls=[ + "extended_dn:1:1", + "show_recycled:1", + "show_deleted:1", + "sd_flags:1:%d" % sd_flags, + ], attrs=attrs) except ldb.LdbError, (enum, estr): if enum == ldb.ERR_NO_SUCH_OBJECT: @@ -608,6 +780,13 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) got_repl_property_meta_data = True continue + if str(attrname).lower() == 'ntsecuritydescriptor': + (sd, sd_broken) = self.process_sd(dn, obj) + if sd_broken is not None: + self.err_wrong_sd(dn, sd, sd_broken) + error_count += 1 + continue + if str(attrname).lower() == 'objectclass': normalised = self.samdb.dsdb_normalise_attributes(self.samdb_schema, attrname, list(obj[attrname])) if list(normalised) != list(obj[attrname]): -- 1.7.9.5 From aabd18f002b9778beb04ada3fd3bd73f7008fa24 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 15:23:13 +0100 Subject: [PATCH 05/22] samba_upgradeprovision: don't reset 'whenCreated' when resetting 'nTSecurityDescriptor' Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit b5cafa3b84e6cca5ca83fbcc0963def7d0c286d5) --- source4/scripting/bin/samba_upgradeprovision | 2 -- 1 file changed, 2 deletions(-) diff --git a/source4/scripting/bin/samba_upgradeprovision b/source4/scripting/bin/samba_upgradeprovision index 7060b73..9daabe3 100755 --- a/source4/scripting/bin/samba_upgradeprovision +++ b/source4/scripting/bin/samba_upgradeprovision @@ -1357,8 +1357,6 @@ def rebuild_sd(samdb, names): 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") -- 1.7.9.5 From 26b550833269c6712eb11fb1b41c27b1c2d54025 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 15:24:11 +0100 Subject: [PATCH 06/22] 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 Reviewed-by: Andrew Bartlett (cherry picked from commit f51248339ae7ba9843e477493a69b0c4f647935a) --- source4/scripting/bin/samba_upgradeprovision | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/scripting/bin/samba_upgradeprovision b/source4/scripting/bin/samba_upgradeprovision index 9daabe3..9898333 100755 --- a/source4/scripting/bin/samba_upgradeprovision +++ b/source4/scripting/bin/samba_upgradeprovision @@ -1360,7 +1360,7 @@ def rebuild_sd(samdb, names): 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), -- 1.7.9.5 From 1b0040f5ed072600ee6dbe04a6c0175d571d5e2d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 08:56:00 +0100 Subject: [PATCH 07/22] provision: setup names.dns{forest,domain}dn Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit b54b58e75d3c1a3080e81c61156b75ef1d241b71) --- .../scripting/python/samba/provision/__init__.py | 23 +++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index e6ea855..70b0eee 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -135,10 +135,13 @@ class ProvisionPaths(object): class ProvisionNames(object): def __init__(self): + self.ncs = None self.rootdn = None self.domaindn = None self.configdn = None self.schemadn = None + self.dnsforestdn = None + self.dnsdomaindn = None self.ldapmanagerdn = None self.dnsdomain = None self.realm = None @@ -184,7 +187,8 @@ def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, current = samdb.search(expression="(objectClass=*)", base="", scope=ldb.SCOPE_BASE, attrs=["defaultNamingContext", "schemaNamingContext", - "configurationNamingContext","rootDomainNamingContext"]) + "configurationNamingContext","rootDomainNamingContext", + "namingContexts"]) names.configdn = current[0]["configurationNamingContext"] configdn = str(names.configdn) @@ -198,6 +202,23 @@ def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, names.domaindn=current[0]["defaultNamingContext"] names.rootdn=current[0]["rootDomainNamingContext"] + names.ncs=current[0]["namingContexts"] + names.dnsforestdn = None + names.dnsdomaindn = None + + for i in range(0, len(names.ncs)): + nc = names.ncs[i] + + dnsforestdn = "DC=ForestDnsZones,%s" % (str(names.rootdn)) + if nc == dnsforestdn: + names.dnsforestdn = dnsforestdn + continue + + dnsdomaindn = "DC=DomainDnsZones,%s" % (str(names.domaindn)) + if nc == dnsdomaindn: + names.dnsdomaindn = dnsdomaindn + continue + # default site name res3 = samdb.search(expression="(objectClass=site)", base="CN=Sites," + configdn, scope=ldb.SCOPE_ONELEVEL, attrs=["cn"]) -- 1.7.9.5 From 2efc243591f0fd2625320c0b76e984a165d911f1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 09:05:36 +0100 Subject: [PATCH 08/22] provision: import/export get_dns_partition_descriptor() Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit d4653e99b8be35b6d86605a1c4c624d5db2294b1) --- .../scripting/python/samba/provision/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index 70b0eee..fe22a6d 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -86,7 +86,8 @@ from samba.provision.descriptor import ( get_domain_builtin_descriptor, get_domain_computers_descriptor, get_domain_users_descriptor, - get_domain_controllers_descriptor + get_domain_controllers_descriptor, + get_dns_partition_descriptor, ) from samba.provision.common import ( setup_path, -- 1.7.9.5 From 5923078c94a7e35c450165c5d037ba16f0920ac5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 15:51:37 +0100 Subject: [PATCH 09/22] 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 Reviewed-by: Andrew Bartlett (cherry picked from commit 27a99c6236ab270a592b4e3242f92f8923a3d7e4) --- .../scripting/python/samba/provision/descriptor.py | 62 ++++++++++---------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/source4/scripting/python/samba/provision/descriptor.py b/source4/scripting/python/samba/provision/descriptor.py index adf7579..ade6e17 100644 --- a/source4/scripting/python/samba/provision/descriptor.py +++ b/source4/scripting/python/samba/provision/descriptor.py @@ -31,14 +31,22 @@ from samba.ndr import ndr_pack # Descriptors of naming contexts and other important objects -def get_empty_descriptor(domain_sid): - sddl= "" +def sddl2binary(sddl_in, domain_sid, name_map): + sddl = "%s" % sddl_in + + for [name, sid] in name_map.items(): + sddl = sddl.replace(name, sid) + sec = security.descriptor.from_sddl(sddl, domain_sid) return ndr_pack(sec) +def get_empty_descriptor(domain_sid, name_map={}): + sddl= "" + return sddl2binary(sddl, domain_sid, name_map) + # "get_schema_descriptor" is located in "schema.py" -def get_config_descriptor(domain_sid): +def get_config_descriptor(domain_sid, name_map={}): sddl = "O:EAG:EAD:(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \ "(OA;;CR;1131f6ab-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \ "(OA;;CR;1131f6ac-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \ @@ -54,10 +62,9 @@ def get_config_descriptor(domain_sid): "(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;ER)" \ "S:(AU;SA;WPWOWD;;;WD)(AU;SA;CR;;;BA)(AU;SA;CR;;;DU)" \ "(OU;SA;CR;45ec5156-db7e-47bb-b53f-dbeb2d03c40f;;WD)" - sec = security.descriptor.from_sddl(sddl, domain_sid) - return ndr_pack(sec) + return sddl2binary(sddl, domain_sid, name_map) -def get_config_partitions_descriptor(domain_sid): +def get_config_partitions_descriptor(domain_sid, name_map={}): sddl = "D:" \ "(A;;LCLORC;;;AU)" \ "(OA;;RP;e48d0154-bcf8-11d1-8702-00c04fb96050;;AU)" \ @@ -72,10 +79,9 @@ def get_config_partitions_descriptor(domain_sid): "(OA;CIIO;WP;3df793df-9858-4417-a701-735a1ecebf74;bf967a8d-0de6-11d0-a285-00aa003049e2;BA)" \ "S:" \ "(AU;CISA;WPCRCCDCWOWDSDDT;;;WD)" - sec = security.descriptor.from_sddl(sddl, domain_sid) - return ndr_pack(sec) + return sddl2binary(sddl, domain_sid, name_map) -def get_config_sites_descriptor(domain_sid): +def get_config_sites_descriptor(domain_sid, name_map={}): sddl = "D:" \ "(A;;RPLCLORC;;;AU)" \ "(OA;CIIO;SW;d31a8757-2447-4545-8081-3bb610cacbf2;f0f8ffab-1191-11d0-a060-00aa006c33ed;ER)" \ @@ -87,10 +93,9 @@ def get_config_sites_descriptor(domain_sid): "(OU;CIIOSA;WP;f30e3bbe-9ff0-11d1-b603-0000f80367c1;bf967ab3-0de6-11d0-a285-00aa003049e2;WD)" \ "(OU;CIIOSA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967ab3-0de6-11d0-a285-00aa003049e2;WD)" \ "(OU;CIIOSA;WP;3e10944c-c354-11d0-aff8-0000f80367c1;b7b13124-b82e-11d0-afee-0000f80367c1;WD)" - sec = security.descriptor.from_sddl(sddl, domain_sid) - return ndr_pack(sec) + return sddl2binary(sddl, domain_sid, name_map) -def get_domain_descriptor(domain_sid): +def get_domain_descriptor(domain_sid, name_map={}): sddl= "O:BAG:BAD:AI(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \ "(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \ "(OA;CIIO;RP;5f202010-79a5-11d0-9020-00c04fc2d4cf;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \ @@ -140,20 +145,18 @@ def get_domain_descriptor(domain_sid): "S:AI(OU;CISA;WP;f30e3bbe-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" \ "(OU;CISA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" \ "(AU;SA;CR;;;DU)(AU;SA;CR;;;BA)(AU;SA;WPWOWD;;;WD)" - sec = security.descriptor.from_sddl(sddl, domain_sid) - return ndr_pack(sec) + return sddl2binary(sddl, domain_sid, name_map) -def get_domain_infrastructure_descriptor(domain_sid): +def get_domain_infrastructure_descriptor(domain_sid, name_map={}): sddl = "D:" \ "(A;;RPLCLORC;;;AU)" \ "(A;;RPWPCRCCLCLORCWOWDSW;;;DA)" \ "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" \ "S:" \ "(AU;SA;WPCR;;;WD)" - sec = security.descriptor.from_sddl(sddl, domain_sid) - return ndr_pack(sec) + return sddl2binary(sddl, domain_sid, name_map) -def get_domain_builtin_descriptor(domain_sid): +def get_domain_builtin_descriptor(domain_sid, name_map={}): sddl = "D:" \ "(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \ "(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \ @@ -207,10 +210,9 @@ def get_domain_builtin_descriptor(domain_sid): "(AU;SA;CR;;;DU)" \ "(AU;SA;CR;;;BA)" \ "(AU;SA;WPWOWD;;;WD)" - sec = security.descriptor.from_sddl(sddl, domain_sid) - return ndr_pack(sec) + return sddl2binary(sddl, domain_sid, name_map) -def get_domain_computers_descriptor(domain_sid): +def get_domain_computers_descriptor(domain_sid, name_map={}): sddl = "D:" \ "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" \ "(A;;RPWPCRCCDCLCLORCWOWDSW;;;DA)" \ @@ -221,10 +223,9 @@ def get_domain_computers_descriptor(domain_sid): "(A;;RPLCLORC;;;AU)" \ "(OA;;CCDC;4828cc14-1437-45bc-9b07-ad6f015e5f28;;AO)" \ "S:" - sec = security.descriptor.from_sddl(sddl, domain_sid) - return ndr_pack(sec) + return sddl2binary(sddl, domain_sid, name_map) -def get_domain_users_descriptor(domain_sid): +def get_domain_users_descriptor(domain_sid, name_map={}): sddl = "D:" \ "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" \ "(A;;RPWPCRCCDCLCLORCWOWDSW;;;DA)" \ @@ -234,10 +235,9 @@ def get_domain_users_descriptor(domain_sid): "(A;;RPLCLORC;;;AU)" \ "(OA;;CCDC;4828cc14-1437-45bc-9b07-ad6f015e5f28;;AO)" \ "S:" - sec = security.descriptor.from_sddl(sddl, domain_sid) - return ndr_pack(sec) + return sddl2binary(sddl, domain_sid, name_map) -def get_domain_controllers_descriptor(domain_sid): +def get_domain_controllers_descriptor(domain_sid, name_map={}): sddl = "D:" \ "(A;;RPLCLORC;;;AU)" \ "(A;;RPWPCRCCLCLORCWOWDSW;;;DA)" \ @@ -246,10 +246,9 @@ def get_domain_controllers_descriptor(domain_sid): "S:" \ "(AU;SA;CCDCWOWDSDDT;;;WD)" \ "(AU;CISA;WP;;;WD)" - sec = security.descriptor.from_sddl(sddl, domain_sid) - return ndr_pack(sec) + return sddl2binary(sddl, domain_sid, name_map) -def get_dns_partition_descriptor(domainsid): +def get_dns_partition_descriptor(domain_sid, name_map={}): sddl = "O:SYG:BAD:AI" \ "(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \ "(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \ @@ -301,5 +300,4 @@ def get_dns_partition_descriptor(domainsid): "(OU;CISA;WP;f30e3bbe-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" \ "(OU;CISA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" \ "(AU;SA;CR;;;DU)(AU;SA;CR;;;BA)(AU;SA;WPWOWD;;;WD)" - sec = security.descriptor.from_sddl(sddl, domainsid) - return ndr_pack(sec) + return sddl2binary(sddl, domain_sid, name_map) -- 1.7.9.5 From 883bfc8cbd1df22cd7d7e40450076dc374de038c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 15:53:00 +0100 Subject: [PATCH 10/22] 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 Reviewed-by: Andrew Bartlett (cherry picked from commit 8880c2d0d356e7208ca859e17caf208952af0e17) --- source4/scripting/python/samba/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/scripting/python/samba/schema.py b/source4/scripting/python/samba/schema.py index 2d13150..5c8f506 100644 --- a/source4/scripting/python/samba/schema.py +++ b/source4/scripting/python/samba/schema.py @@ -32,7 +32,7 @@ from samba import dsdb from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL import os -def get_schema_descriptor(domain_sid): +def get_schema_descriptor(domain_sid, name_map={}): sddl = "O:SAG:SAD:AI(OA;;CR;e12b56b6-0a95-11d1-adbb-00c04fd8d5cd;;SA)" \ "(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \ "(OA;;CR;1131f6ab-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \ -- 1.7.9.5 From b5906cc8c418a1b4e7b2888e7c0b9746833a35b1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 10:51:10 +0100 Subject: [PATCH 11/22] provision: add get_{config,domain}_delete_protected*_descriptor() Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 1207cbd123375f0ff1bfc51403af5d611a621091) --- .../scripting/python/samba/provision/__init__.py | 5 +++ .../scripting/python/samba/provision/descriptor.py | 35 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index fe22a6d..6b2d7bd 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -81,12 +81,17 @@ from samba.provision.descriptor import ( get_config_descriptor, get_config_partitions_descriptor, get_config_sites_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, ) from samba.provision.common import ( diff --git a/source4/scripting/python/samba/provision/descriptor.py b/source4/scripting/python/samba/provision/descriptor.py index ade6e17..6b03d21 100644 --- a/source4/scripting/python/samba/provision/descriptor.py +++ b/source4/scripting/python/samba/provision/descriptor.py @@ -95,6 +95,27 @@ def get_config_sites_descriptor(domain_sid, name_map={}): "(OU;CIIOSA;WP;3e10944c-c354-11d0-aff8-0000f80367c1;b7b13124-b82e-11d0-afee-0000f80367c1;WD)" return sddl2binary(sddl, domain_sid, name_map) +def get_config_delete_protected1_descriptor(domain_sid, name_map={}): + sddl = "D:AI" \ + "(A;;RPLCLORC;;;AU)" \ + "(A;;RPWPCRCCLCLORCWOWDSW;;;EA)" \ + "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" + return sddl2binary(sddl, domain_sid, name_map) + +def get_config_delete_protected1wd_descriptor(domain_sid, name_map={}): + sddl = "D:AI" \ + "(A;;RPLCLORC;;;WD)" \ + "(A;;RPWPCRCCLCLORCWOWDSW;;;EA)" \ + "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" + return sddl2binary(sddl, domain_sid, name_map) + +def get_config_delete_protected2_descriptor(domain_sid, name_map={}): + sddl = "D:AI" \ + "(A;;RPLCLORC;;;AU)" \ + "(A;;RPWPCRCCDCLCLORCWOWDSW;;;EA)" \ + "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" + return sddl2binary(sddl, domain_sid, name_map) + def get_domain_descriptor(domain_sid, name_map={}): sddl= "O:BAG:BAD:AI(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \ "(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \ @@ -248,6 +269,20 @@ def get_domain_controllers_descriptor(domain_sid, name_map={}): "(AU;CISA;WP;;;WD)" return sddl2binary(sddl, domain_sid, name_map) +def get_domain_delete_protected1_descriptor(domain_sid, name_map={}): + sddl = "D:AI" \ + "(A;;RPLCLORC;;;AU)" \ + "(A;;RPWPCRCCLCLORCWOWDSW;;;DA)" \ + "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" + return sddl2binary(sddl, domain_sid, name_map) + +def get_domain_delete_protected2_descriptor(domain_sid, name_map={}): + sddl = "D:AI" \ + "(A;;RPLCLORC;;;AU)" \ + "(A;;RPWPCRCCDCLCLORCWOWDSW;;;DA)" \ + "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" + return sddl2binary(sddl, domain_sid, name_map) + def get_dns_partition_descriptor(domain_sid, name_map={}): sddl = "O:SYG:BAD:AI" \ "(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \ -- 1.7.9.5 From cccfe80627b6a37d583f6b2dae2c25dd277f3721 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 15:39:07 +0100 Subject: [PATCH 12/22] provision: add get_config_ntds_quotas_descriptor() Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit d00fb6aff2f54b470304d3d77a53328bcbb16851) --- .../scripting/python/samba/provision/__init__.py | 1 + .../scripting/python/samba/provision/descriptor.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index 6b2d7bd..984f1e2 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -81,6 +81,7 @@ from samba.provision.descriptor import ( 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, diff --git a/source4/scripting/python/samba/provision/descriptor.py b/source4/scripting/python/samba/provision/descriptor.py index 6b03d21..dfb2a72 100644 --- a/source4/scripting/python/samba/provision/descriptor.py +++ b/source4/scripting/python/samba/provision/descriptor.py @@ -95,6 +95,13 @@ def get_config_sites_descriptor(domain_sid, name_map={}): "(OU;CIIOSA;WP;3e10944c-c354-11d0-aff8-0000f80367c1;b7b13124-b82e-11d0-afee-0000f80367c1;WD)" return sddl2binary(sddl, domain_sid, name_map) +def get_config_ntds_quotas_descriptor(domain_sid, name_map={}): + sddl = "D:" \ + "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;EA)" \ + "(A;;RPLCLORC;;;BA)" \ + "(OA;;CR;4ecc03fe-ffc0-4947-b630-eb672a8a9dbc;;WD)" + return sddl2binary(sddl, domain_sid, name_map) + def get_config_delete_protected1_descriptor(domain_sid, name_map={}): sddl = "D:AI" \ "(A;;RPLCLORC;;;AU)" \ -- 1.7.9.5 From a880bd78d029630562a46fb089048baa2575eff3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 15:55:31 +0100 Subject: [PATCH 13/22] provision: add get_dns_{forest,domain}_microsoft_dns_descriptor() Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit ebb73f1c5d577c1d32c5c0519dcf3fb25c578c45) --- .../scripting/python/samba/provision/__init__.py | 2 ++ .../scripting/python/samba/provision/descriptor.py | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index 984f1e2..cb4a081 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -94,6 +94,8 @@ from samba.provision.descriptor import ( 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, ) from samba.provision.common import ( setup_path, diff --git a/source4/scripting/python/samba/provision/descriptor.py b/source4/scripting/python/samba/provision/descriptor.py index dfb2a72..32e91ed 100644 --- a/source4/scripting/python/samba/provision/descriptor.py +++ b/source4/scripting/python/samba/provision/descriptor.py @@ -343,3 +343,17 @@ def get_dns_partition_descriptor(domain_sid, name_map={}): "(OU;CISA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" \ "(AU;SA;CR;;;DU)(AU;SA;CR;;;BA)(AU;SA;WPWOWD;;;WD)" return sddl2binary(sddl, domain_sid, name_map) + +def get_dns_forest_microsoft_dns_descriptor(domain_sid, name_map={}): + sddl = "O:SYG:SYD:AI" \ + "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" \ + "(A;CI;RPWPCRCCDCLCRCWOWDSDDTSW;;;ED)" + return sddl2binary(sddl, domain_sid, name_map) + +def get_dns_domain_microsoft_dns_descriptor(domain_sid, name_map={}): + sddl = "O:SYG:SYD:AI" \ + "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)" \ + "(A;CI;RPWPCRCCDCLCRCWOWDSDDTSW;;;DnsAdmins)" \ + "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" \ + "(A;CI;RPWPCRCCDCLCRCWOWDSDDTSW;;;ED)" + return sddl2binary(sddl, domain_sid, name_map) -- 1.7.9.5 From c7424e01a24795c619db8df830aa34cf84b66404 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 15:43:54 +0100 Subject: [PATCH 14/22] 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 Reviewed-by: Andrew Bartlett (cherry picked from commit e0712a70f5a437eb60df3cebedbbe1c6c08bd6ae) --- .../scripting/python/samba/provision/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index cb4a081..217b71a 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -159,6 +159,7 @@ class ProvisionNames(object): self.hostname = None self.sitename = None self.smbconf = None + self.name_map = {} def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, -- 1.7.9.5 From ef13f7dc15910b322e7ed807448087f6a5d326f3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 15:45:33 +0100 Subject: [PATCH 15/22] provision: setup names.name_map['DnsAdmins'] Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 4775f9ab345072e63d671e83ae2c054fd2f80c3b) --- .../scripting/python/samba/provision/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index 217b71a..db6ef9b 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -103,6 +103,7 @@ from samba.provision.common import ( setup_modify_ldif, ) from samba.provision.sambadns import ( + get_dnsadmins_sid, setup_ad_dns, create_dns_update_list ) @@ -289,6 +290,10 @@ def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, names.root_gid = res9[0]["xidNumber"][0] else: names.root_gid = pwd.getpwuid(int(res9[0]["xidNumber"][0])).pw_gid + + dns_admins_sid = get_dnsadmins_sid(samdb, names.domaindn) + names.name_map['DnsAdmins'] = str(dns_admins_sid) + return names -- 1.7.9.5 From daa8eed454f1a56ba062b8a43ca07c9371249ffe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 16:27:17 +0100 Subject: [PATCH 16/22] provision: fix nTSecurityDescriptor of CN={LostAndFound,System},${DOMAINDN} (bug #9481) Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 1de5c2f78544385d2fe270d766fc1ca6726d71fb) --- .../scripting/python/samba/provision/__init__.py | 4 ++++ source4/setup/provision.ldif | 2 ++ 2 files changed, 6 insertions(+) diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index db6ef9b..1a158cb 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -1344,6 +1344,8 @@ def fill_samdb(samdb, lp, names, logger, domainsid, domainguid, policyguid, "DOMAINDN": names.domaindn}) logger.info("Setting up sam.ldb data") infrastructure_desc = b64encode(get_domain_infrastructure_descriptor(domainsid)) + lostandfound_desc = b64encode(get_domain_delete_protected2_descriptor(domainsid)) + system_desc = b64encode(get_domain_delete_protected1_descriptor(domainsid)) builtin_desc = b64encode(get_domain_builtin_descriptor(domainsid)) controllers_desc = b64encode(get_domain_controllers_descriptor(domainsid)) setup_add_ldif(samdb, setup_path("provision.ldif"), { @@ -1356,6 +1358,8 @@ def fill_samdb(samdb, lp, names, logger, domainsid, domainguid, policyguid, "RIDAVAILABLESTART": str(next_rid + 600), "POLICYGUID_DC": policyguid_dc, "INFRASTRUCTURE_DESCRIPTOR": infrastructure_desc, + "LOSTANDFOUND_DESCRIPTOR": lostandfound_desc, + "SYSTEM_DESCRIPTOR": system_desc, "BUILTIN_DESCRIPTOR": builtin_desc, "DOMAIN_CONTROLLERS_DESCRIPTOR": controllers_desc, }) diff --git a/source4/setup/provision.ldif b/source4/setup/provision.ldif index 51e56ff..61d735c 100644 --- a/source4/setup/provision.ldif +++ b/source4/setup/provision.ldif @@ -73,6 +73,7 @@ objectClass: lostAndFound description: Default container for orphaned objects systemFlags: -1946157056 isCriticalSystemObject: TRUE +nTSecurityDescriptor:: ${LOSTANDFOUND_DESCRIPTOR} dn: CN=NTDS Quotas,${DOMAINDN} objectClass: top @@ -98,6 +99,7 @@ objectClass: container description: Builtin system settings systemFlags: -1946157056 isCriticalSystemObject: TRUE +nTSecurityDescriptor:: ${SYSTEM_DESCRIPTOR} dn: CN=AdminSDHolder,CN=System,${DOMAINDN} objectClass: top -- 1.7.9.5 From 28af962373f7d0b8ae4fe7eaeb93779f7928064e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 16:27:17 +0100 Subject: [PATCH 17/22] provision: fix nTSecurityDescriptor attributes of CN=*,${CONFIGDN} (bug #9481) Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit a477649e568577875be577c70a6b25cbeea6985a) --- .../scripting/python/samba/provision/__init__.py | 21 ++++++++++++++++++++ source4/setup/provision_configuration.ldif | 6 ++++++ source4/setup/provision_configuration_modify.ldif | 6 ++++++ source4/setup/provision_well_known_sec_princ.ldif | 1 + 4 files changed, 34 insertions(+) create mode 100644 source4/setup/provision_configuration_modify.ldif diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index 1a158cb..f5d8451 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -1298,8 +1298,14 @@ def fill_samdb(samdb, lp, names, logger, domainsid, domainguid, policyguid, # If we are setting up a subdomain, then this has been replicated in, so we don't need to add it if fill == FILL_FULL: logger.info("Setting up sam.ldb configuration data") + partitions_descr = b64encode(get_config_partitions_descriptor(domainsid)) sites_descr = b64encode(get_config_sites_descriptor(domainsid)) + ntdsquotas_descr = b64encode(get_config_ntds_quotas_descriptor(domainsid)) + protected1_descr = b64encode(get_config_delete_protected1_descriptor(domainsid)) + protected1wd_descr = b64encode(get_config_delete_protected1wd_descriptor(domainsid)) + protected2_descr = b64encode(get_config_delete_protected2_descriptor(domainsid)) + setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), { "CONFIGDN": names.configdn, "NETBIOSNAME": names.netbiosname, @@ -1311,6 +1317,12 @@ def fill_samdb(samdb, lp, names, logger, domainsid, domainguid, policyguid, "SERVERDN": names.serverdn, "FOREST_FUNCTIONALITY": str(forestFunctionality), "DOMAIN_FUNCTIONALITY": str(domainFunctionality), + "NTDSQUOTAS_DESCRIPTOR": ntdsquotas_descr, + "LOSTANDFOUND_DESCRIPTOR": protected1wd_descr, + "SERVICES_DESCRIPTOR": protected1_descr, + "PHYSICALLOCATIONS_DESCRIPTOR": protected1wd_descr, + "FORESTUPDATES_DESCRIPTOR": protected1wd_descr, + "EXTENDEDRIGHTS_DESCRIPTOR": protected2_descr, "PARTITIONS_DESCRIPTOR": partitions_descr, "SITES_DESCRIPTOR": sites_descr, }) @@ -1323,6 +1335,13 @@ def fill_samdb(samdb, lp, names, logger, domainsid, domainguid, policyguid, check_all_substituted(display_specifiers_ldif) samdb.add_ldif(display_specifiers_ldif) + logger.info("Modifying display specifiers") + setup_modify_ldif(samdb, + setup_path("provision_configuration_modify.ldif"), { + "CONFIGDN": names.configdn, + "DISPLAYSPECIFIERS_DESCRIPTOR": protected2_descr + }) + logger.info("Adding users container") users_desc = b64encode(get_domain_users_descriptor(domainsid)) setup_add_ldif(samdb, setup_path("provision_users_add.ldif"), { @@ -1372,8 +1391,10 @@ def fill_samdb(samdb, lp, names, logger, domainsid, domainguid, policyguid, "SCHEMADN": names.schemadn}) logger.info("Setting up well known security principals") + protected1wd_descr = b64encode(get_config_delete_protected1wd_descriptor(domainsid)) setup_add_ldif(samdb, setup_path("provision_well_known_sec_princ.ldif"), { "CONFIGDN": names.configdn, + "WELLKNOWNPRINCIPALS_DESCRIPTOR": protected1wd_descr, }) if fill == FILL_FULL or fill == FILL_SUBDOMAIN: diff --git a/source4/setup/provision_configuration.ldif b/source4/setup/provision_configuration.ldif index 1d818ef..42de84a 100644 --- a/source4/setup/provision_configuration.ldif +++ b/source4/setup/provision_configuration.ldif @@ -21,6 +21,7 @@ dn: CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: container systemFlags: -2147483648 +nTSecurityDescriptor:: ${EXTENDEDRIGHTS_DESCRIPTOR} dn: CN=Change-Rid-Master,CN=Extended-Rights,${CONFIGDN} objectClass: top @@ -706,6 +707,7 @@ validAccesses: 48 dn: CN=ForestUpdates,${CONFIGDN} objectClass: top objectClass: container +nTSecurityDescriptor:: ${FORESTUPDATES_DESCRIPTOR} dn: CN=ActiveDirectoryRodcUpdate,CN=ForestUpdates,${CONFIGDN} objectClass: top @@ -1001,6 +1003,7 @@ dn: CN=LostAndFoundConfig,${CONFIGDN} objectClass: top objectClass: lostAndFound systemFlags: -2147483648 +nTSecurityDescriptor:: ${LOSTANDFOUND_DESCRIPTOR} dn: CN=NTDS Quotas,${CONFIGDN} objectClass: top @@ -1009,6 +1012,7 @@ description: Quota specifications container isCriticalSystemObject: TRUE msDS-TombstoneQuotaFactor: 100 systemFlags: -2147483648 +nTSecurityDescriptor:: ${NTDSQUOTAS_DESCRIPTOR} # Partitions @@ -1053,6 +1057,7 @@ objectClass: top objectClass: locality objectClass: physicalLocation l: Physical Locations tree root +nTSecurityDescriptor:: ${PHYSICALLOCATIONS_DESCRIPTOR} # Schema located in "ad-schema/*.txt" @@ -1062,6 +1067,7 @@ dn: CN=Services,${CONFIGDN} objectClass: top objectClass: container systemFlags: -2147483648 +nTSecurityDescriptor:: ${SERVICES_DESCRIPTOR} dn: CN=MsmqServices,CN=Services,${CONFIGDN} objectClass: top diff --git a/source4/setup/provision_configuration_modify.ldif b/source4/setup/provision_configuration_modify.ldif new file mode 100644 index 0000000..6840604 --- /dev/null +++ b/source4/setup/provision_configuration_modify.ldif @@ -0,0 +1,6 @@ +dn: CN=DisplaySpecifiers,${CONFIGDN} +changetype: modify +- +replace: nTSecurityDescriptor +nTSecurityDescriptor:: ${DISPLAYSPECIFIERS_DESCRIPTOR} +- diff --git a/source4/setup/provision_well_known_sec_princ.ldif b/source4/setup/provision_well_known_sec_princ.ldif index 54691bd..1817382 100644 --- a/source4/setup/provision_well_known_sec_princ.ldif +++ b/source4/setup/provision_well_known_sec_princ.ldif @@ -4,6 +4,7 @@ dn: CN=WellKnown Security Principals,${CONFIGDN} objectClass: top objectClass: container systemFlags: -2147483648 +nTSecurityDescriptor:: ${WELLKNOWNPRINCIPALS_DESCRIPTOR} dn: CN=Anonymous Logon,CN=WellKnown Security Principals,${CONFIGDN} objectClass: top -- 1.7.9.5 From 1afbe5db0edfdd560a5ff0f64fedea3ea1b1ead5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jan 2013 16:27:17 +0100 Subject: [PATCH 18/22] provision: fix nTSecurityDescriptor of containers in the DnsZones (bug #9481) Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 5cf98823cc804906833f7ea763f99de0147b0fee) --- .../scripting/python/samba/provision/sambadns.py | 30 +++++++++++++------- source4/setup/provision_dnszones_add.ldif | 4 +++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/source4/scripting/python/samba/provision/sambadns.py b/source4/scripting/python/samba/provision/sambadns.py index a66fde1..740dd384 100644 --- a/source4/scripting/python/samba/provision/sambadns.py +++ b/source4/scripting/python/samba/provision/sambadns.py @@ -37,7 +37,11 @@ from samba.dsdb import ( ) from samba.provision.descriptor import ( get_domain_descriptor, - get_dns_partition_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 ) from samba.provision.common import ( setup_path, @@ -244,6 +248,8 @@ def setup_dns_partitions(samdb, domainsid, domaindn, forestdn, configdn, domainzone_dns = ldb.Dn(samdb, domainzone_dn).canonical_ex_str().strip() forestzone_dns = ldb.Dn(samdb, forestzone_dn).canonical_ex_str().strip() + protected1_desc = get_domain_delete_protected1_descriptor(domainsid) + protected2_desc = get_domain_delete_protected2_descriptor(domainsid) setup_add_ldif(samdb, setup_path("provision_dnszones_add.ldif"), { "DOMAINZONE_DN": domainzone_dn, "FORESTZONE_DN": forestzone_dn, @@ -253,6 +259,8 @@ def setup_dns_partitions(samdb, domainsid, domaindn, forestdn, configdn, "FORESTZONE_DNS": forestzone_dns, "CONFIGDN": configdn, "SERVERDN": serverdn, + "LOSTANDFOUND_DESCRIPTOR": b64encode(protected2_desc), + "INFRASTRUCTURE_DESCRIPTOR": b64encode(protected1_desc), }) setup_modify_ldif(samdb, setup_path("provision_dnszones_modify.ldif"), { @@ -269,18 +277,18 @@ def add_dns_accounts(samdb, domaindn): }) -def add_dns_container(samdb, domaindn, prefix, domainsid, dnsadmins_sid): +def add_dns_container(samdb, domaindn, prefix, domain_sid, dnsadmins_sid, forest=False): + name_map = {'DnsAdmins': str(dnsadmins_sid)} + if forest is True: + sd_val = get_dns_forest_microsoft_dns_descriptor(domain_sid, + name_map=name_map) + else: + sd_val = get_dns_domain_microsoft_dns_descriptor(domain_sid, + name_map=name_map) # CN=MicrosoftDNS,, - sddl = "O:SYG:SYD:AI" \ - "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)" \ - "(A;CI;RPWPCRCCDCLCRCWOWDSDDTSW;;;%s)" \ - "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" \ - "(A;CI;RPWPCRCCDCLCRCWOWDSDDTSW;;;ED)" \ - "S:AI" % dnsadmins_sid - sec = security.descriptor.from_sddl(sddl, domainsid) msg = ldb.Message(ldb.Dn(samdb, "CN=MicrosoftDNS,%s,%s" % (prefix, domaindn))) msg["objectClass"] = ["top", "container"] - msg["nTSecurityDescriptor"] = ldb.MessageElement(ndr_pack(sec), ldb.FLAG_MOD_ADD, + msg["nTSecurityDescriptor"] = ldb.MessageElement(sd_val, ldb.FLAG_MOD_ADD, "nTSecurityDescriptor") samdb.add(msg) @@ -942,7 +950,7 @@ def create_dns_partitions(samdb, domainsid, names, domaindn, forestdn, add_dns_container(samdb, domaindn, "DC=DomainDnsZones", domainsid, dnsadmins_sid) add_dns_container(samdb, forestdn, "DC=ForestDnsZones", domainsid, - dnsadmins_sid) + dnsadmins_sid, forest=True) def fill_dns_data_partitions(samdb, domainsid, site, domaindn, forestdn, diff --git a/source4/setup/provision_dnszones_add.ldif b/source4/setup/provision_dnszones_add.ldif index bd97bb9..bf872f0 100644 --- a/source4/setup/provision_dnszones_add.ldif +++ b/source4/setup/provision_dnszones_add.ldif @@ -14,12 +14,14 @@ objectClass: top objectClass: lostAndFound isCriticalSystemObject: TRUE systemFlags: -1946157056 +nTSecurityDescriptor:: ${LOSTANDFOUND_DESCRIPTOR} dn: CN=Infrastructure,${DOMAINZONE_DN} objectClass: top objectClass: infrastructureUpdate isCriticalSystemObject: TRUE systemFlags: -1946157056 +nTSecurityDescriptor:: ${INFRASTRUCTURE_DESCRIPTOR} dn: CN=NTDS Quotas,${DOMAINZONE_DN} objectClass: top @@ -41,12 +43,14 @@ objectClass: top objectClass: lostAndFound isCriticalSystemObject: TRUE systemFlags: -1946157056 +nTSecurityDescriptor:: ${LOSTANDFOUND_DESCRIPTOR} dn: CN=Infrastructure,${FORESTZONE_DN} objectClass: top objectClass: infrastructureUpdate isCriticalSystemObject: TRUE systemFlags: -1946157056 +nTSecurityDescriptor:: ${INFRASTRUCTURE_DESCRIPTOR} dn: CN=NTDS Quotas,${FORESTZONE_DN} objectClass: top -- 1.7.9.5 From 7df9d3d69e2a32d007df47f69b2b1cc8a8b49eb1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Dec 2012 12:56:37 +0100 Subject: [PATCH 19/22] samba_upgradeprovision: fix the nTSecurityDescriptor on more containers (bug #9481) Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 4752731c2eb4abeb0b5da3e33aa3096786301a19) --- source4/scripting/bin/samba_upgradeprovision | 128 ++++++++++++++++++-------- 1 file changed, 92 insertions(+), 36 deletions(-) diff --git a/source4/scripting/bin/samba_upgradeprovision b/source4/scripting/bin/samba_upgradeprovision index 9898333..883fc9a8 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 @@ -1269,8 +1287,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 +1298,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 +1377,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,8 +1405,9 @@ 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) -- 1.7.9.5 From d4a12f817ed5dba37d71043be7b4e8a730559378 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 25 Jan 2013 09:36:47 +0100 Subject: [PATCH 20/22] provision: setup names.dns_backend If we have a DomainDnsZone partition: - we use BIND9_DLZ as backend if a dns- account is available - otherwise, we use SAMBA_INTERNAL else: - we use BIND9_FLATFILE if a dns or dns- account is available - otherwise, we use NONE Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit b855df254de40d9de0b7f9042564f6d521ab1c5d) --- .../scripting/python/samba/provision/__init__.py | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index f5d8451..3c878e9 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -291,6 +291,32 @@ def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, else: names.root_gid = pwd.getpwuid(int(res9[0]["xidNumber"][0])).pw_gid + res10 = samdb.search(expression="(samaccountname=dns)", + scope=ldb.SCOPE_SUBTREE, attrs=["dn"], + controls=["search_options:1:2"]) + if (len(res10) > 0): + has_legacy_dns_account = True + else: + has_legacy_dns_account = False + + res11 = samdb.search(expression="(samaccountname=dns-%s)" % names.netbiosname, + scope=ldb.SCOPE_SUBTREE, attrs=["dn"], + controls=["search_options:1:2"]) + if (len(res11) > 0): + has_dns_account = True + else: + has_dns_account = False + + if names.dnsdomaindn is not None: + if has_dns_account: + names.dns_backend = 'BIND9_DLZ' + else: + names.dns_backend = 'SAMBA_INTERNAL' + elif has_dns_account or has_legacy_dns_account: + names.dns_backend = 'BIND9_FLATFILE' + else: + names.dns_backend = 'NONE' + dns_admins_sid = get_dnsadmins_sid(samdb, names.domaindn) names.name_map['DnsAdmins'] = str(dns_admins_sid) -- 1.7.9.5 From 39d025354e67dba268c3e8d4b8d7e12b1416b9d2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 25 Jan 2013 09:36:47 +0100 Subject: [PATCH 21/22] 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 Reviewed-by: Andrew Bartlett (cherry picked from commit 58d6d884cf8a8de5a1fa2dfd4a0cbacdff0d2483) --- source4/scripting/bin/samba_upgradeprovision | 18 ++++++++++-------- source4/scripting/python/samba/upgradehelpers.py | 3 +-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/source4/scripting/bin/samba_upgradeprovision b/source4/scripting/bin/samba_upgradeprovision index 883fc9a8..e2c57f2 100755 --- a/source4/scripting/bin/samba_upgradeprovision +++ b/source4/scripting/bin/samba_upgradeprovision @@ -228,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 @@ -238,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) @@ -249,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): @@ -1964,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/upgradehelpers.py b/source4/scripting/python/samba/upgradehelpers.py index 81fb8dc..8427f6a 100644 --- a/source4/scripting/python/samba/upgradehelpers.py +++ b/source4/scripting/python/samba/upgradehelpers.py @@ -242,7 +242,6 @@ def newprovision(names, creds, session, smbconf, provdir, logger): shutil.rmtree(provdir) os.mkdir(provdir) logger.info("Provision stored in %s", provdir) - dns_backend="BIND9_DLZ" return provision(logger, session, creds, smbconf=smbconf, targetdir=provdir, samdb_fill=FILL_FULL, realm=names.realm, domain=names.domain, domainguid=names.domainguid, @@ -255,7 +254,7 @@ def newprovision(names, creds, session, smbconf, provdir, logger): serverrole="domain controller", backend_type=None, ldapadminpass=None, ol_mmr_urls=None, slapd_path=None, - dom_for_fun_level=names.domainlevel, dns_backend=dns_backend, + dom_for_fun_level=names.domainlevel, dns_backend=names.dns_backend, useeadb=True, use_ntvfs=True) -- 1.7.9.5 From ae6cdfa695ebca34ecd6ab5640ad024cfaf12ca1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 22 Jan 2013 23:39:15 +1100 Subject: [PATCH 22/22] 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 Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Sun Jan 27 11:55:54 CET 2013 on sn-devel-104 (cherry picked from commit 0f8ef5a2c83e0496ef79c3d6f8b1188fdd1943a0) --- selftest/tests.py | 1 + .../provisions/alpha13/etc/smb.conf.template | 10 +- testprogs/blackbox/upgradeprovision-alpha13.sh | 135 ++++++++++++++++++++ 3 files changed, 141 insertions(+), 5 deletions(-) create mode 100755 testprogs/blackbox/upgradeprovision-alpha13.sh 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/selftest/provisions/alpha13/etc/smb.conf.template b/source4/selftest/provisions/alpha13/etc/smb.conf.template index cc6c82f..ffdcc04 100644 --- a/source4/selftest/provisions/alpha13/etc/smb.conf.template +++ b/source4/selftest/provisions/alpha13/etc/smb.conf.template @@ -4,14 +4,14 @@ realm = ALPHA13.SAMBA.CORP server role = domain controller - private dir = @@PREFIX@@/alpha13/private - lock dir = @@PREFIX@@/alpha13 - posix:eadb = @@PREFIX@@/alpha13/private/eadb.tdb + private dir = @@PREFIX@@/private + lock dir = @@PREFIX@@/ + posix:eadb = @@PREFIX@@/private/eadb.tdb [netlogon] - path = @@PREFIX@@/alpha13/sysvol/alpha13.samba.corp/scripts + path = @@PREFIX@@/sysvol/alpha13.samba.corp/scripts read only = no [sysvol] - path = @@PREFIX@@/alpha13/sysvol + path = @@PREFIX@@/sysvol read only = no diff --git a/testprogs/blackbox/upgradeprovision-alpha13.sh b/testprogs/blackbox/upgradeprovision-alpha13.sh new file mode 100755 index 0000000..1747c7b --- /dev/null +++ b/testprogs/blackbox/upgradeprovision-alpha13.sh @@ -0,0 +1,135 @@ +#!/bin/sh + +if [ $# -lt 1 ]; then +cat < $PREFIX_ABS/alpha13_upgrade/etc/smb.conf + + cp -a $alpha13_dir/private/*.keytab $PREFIX_ABS/alpha13_upgrade_full/private/ + cp -a $alpha13_dir/sysvol $PREFIX_ABS/alpha13_upgrade_full/ + mkdir $PREFIX_ABS/alpha13_upgrade_full/etc/ + cat $alpha13_dir/etc/smb.conf.template | \ + sed "s|@@PREFIX@@|$PREFIX_ABS/alpha13_upgrade_full|g" \ + > $PREFIX_ABS/alpha13_upgrade_full/etc/smb.conf +} + +remove_dns_user() { + # This is done, because otherwise the upgrdeprovision will not run without --full + $BINDIR/ldbdel -H tdb://$PREFIX_ABS/alpha13_upgrade/private/sam.ldb cn=dns,cn=users,dc=alpha13,dc=samba,dc=corp +} + +reindex() { + $BINDIR/samba-tool dbcheck --reindex -H tdb://$PREFIX_ABS/alpha13_upgrade/private/sam.ldb $@ +} + +# This should 'fail', because it returns the number of modified records +dbcheck() { + $BINDIR/samba-tool dbcheck --cross-ncs --fix --yes -H tdb://$PREFIX_ABS/alpha13_upgrade/private/sam.ldb $@ +} + +dbcheck_clean() { + $BINDIR/samba-tool dbcheck --cross-ncs -H tdb://$PREFIX_ABS/alpha13_upgrade/private/sam.ldb $@ +} + +# This should 'fail', because it returns the number of modified records +dbcheck_full() { + $BINDIR/samba-tool dbcheck --cross-ncs --fix --yes -H tdb://$PREFIX_ABS/alpha13_upgrade_full/private/sam.ldb $@ +} + +dbcheck_full_clean() { + $BINDIR/samba-tool dbcheck --cross-ncs -H tdb://$PREFIX_ABS/alpha13_upgrade_full/private/sam.ldb $@ +} + +upgradeprovision() { + $PYTHON $BINDIR/samba_upgradeprovision -s "$PREFIX_ABS/alpha13_upgrade/etc/smb.conf" --debugchange +} + +upgradeprovision_full() { + $PYTHON $BINDIR/samba_upgradeprovision -s "$PREFIX_ABS/alpha13_upgrade_full/etc/smb.conf" --full --debugchange +} + +if [ -d $PREFIX_ABS/alpha13_upgrade ]; then + rm -fr $PREFIX_ABS/alpha13_upgrade +fi + +if [ -d $PREFIX_ABS/alpha13_upgrade_full ]; then + rm -fr $PREFIX_ABS/alpha13_upgrade_full +fi + +if [ -d $alpha13_dir ]; then + testit "alpha13" alpha13 + testit "remove_dns_user" remove_dns_user + testit "upgradeprovision" upgradeprovision + testit "upgradeprovision_full" upgradeprovision_full + testit "reindex" reindex + testit_expect_failure "dbcheck" dbcheck + testit "dbcheck_clean" dbcheck_clean + testit_expect_failure "dbcheck_full" dbcheck_full + testit "dbcheck_full_clean" dbcheck_full_clean +else + subunit_start_test "alpha13" + subunit_skip_test "alpha13" <