[SCM] Samba Shared Repository - branch master updated - tevent-0-9-8-370-g53d6dd3

Andrew Bartlett abartlet at samba.org
Wed Sep 16 09:52:00 MDT 2009


The branch, master has been updated
       via  53d6dd3d52b36f65dcba8ff951f2febb995660ca (commit)
       via  d70e17171912c190b258848edb1ae627fe59cde4 (commit)
       via  fec33db90ebd998f17ed2d539d67abb448e09af2 (commit)
       via  932690c093692b1e9fca4dfa75c7cd55ea4e63b1 (commit)
       via  e8e8e40505465c65bcf434373ae89c8bbf650f96 (commit)
      from  89ed2af69d6d6adcaf64d4c576ee8ba41b27b8a5 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 53d6dd3d52b36f65dcba8ff951f2febb995660ca
Author: Nadezhda Ivanova <nadezhda.ivanova at postpath.com>
Date:   Tue Sep 15 17:39:36 2009 -0700

    security:idl Generated files
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit d70e17171912c190b258848edb1ae627fe59cde4
Author: Nadezhda Ivanova <nadezhda.ivanova at postpath.com>
Date:   Mon Sep 14 19:44:41 2009 +0300

    Owner and group defaulting.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit fec33db90ebd998f17ed2d539d67abb448e09af2
Author: Zahari Zahariev <zahari.zahariev at postpath.com>
Date:   Tue Sep 15 17:34:42 2009 -0700

    Tests for descriptor inheritance
    
    Signed-off-by: Nadezhda Ivanova <nadezhda.ivanova at postpath.com>
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 932690c093692b1e9fca4dfa75c7cd55ea4e63b1
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Sep 15 22:02:36 2009 -0700

    s4:kdc In the kpasswd server, don't use the client address in mk_priv
    
    This code eventually calls into mk_priv in the Heimdal code, and if
    the client is behind NAT, or somehow has an odd idea about it's own
    network addresses, it will fail to accept this packet if we set an
    address.  It seems easiser not to.  (Found by testing with NetAPP at
    plugfest)
    
    Andrew Bartlett

commit e8e8e40505465c65bcf434373ae89c8bbf650f96
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Sep 15 22:00:45 2009 -0700

    s4:rpc_server netgotiate max xmit size with RPC client
    
    Testing against NetAPP showed that clients can object to being told a
    larger max xmit fragment size than they negotiated.  Choose the
    minimum of the server and client values.
    
    Andrew Bartlett

-----------------------------------------------------------------------

Summary of changes:
 libcli/security/security_descriptor.c          |    2 +-
 libcli/security/security_descriptor.h          |    3 +
 librpc/gen_ndr/ndr_security.c                  |   50 +
 librpc/gen_ndr/ndr_security.h                  |    3 +
 librpc/gen_ndr/security.h                      |   13 +
 librpc/idl/security.idl                        |   34 +
 source4/dsdb/samdb/ldb_modules/config.mk       |   12 +
 source4/dsdb/samdb/ldb_modules/descriptor.c    |  459 +++++++
 source4/dsdb/samdb/ldb_modules/objectclass.c   |   65 +-
 source4/kdc/kpasswdd.c                         |    8 +
 source4/lib/ldb/tests/python/sec_descriptor.py | 1610 ++++++++++++++++++++++++
 source4/libcli/security/config.mk              |    2 +-
 source4/libcli/security/create_descriptor.c    |  117 ++
 source4/rpc_server/dcerpc_server.c             |    4 +-
 source4/scripting/python/samba/provision.py    |    1 +
 source4/selftest/knownfail                     |    1 +
 source4/selftest/tests.sh                      |    3 +-
 17 files changed, 2325 insertions(+), 62 deletions(-)
 create mode 100644 source4/dsdb/samdb/ldb_modules/descriptor.c
 create mode 100644 source4/lib/ldb/tests/python/sec_descriptor.py
 create mode 100644 source4/libcli/security/create_descriptor.c


Changeset truncated at 500 lines:

diff --git a/libcli/security/security_descriptor.c b/libcli/security/security_descriptor.c
index f18a326..dbe1160 100644
--- a/libcli/security/security_descriptor.c
+++ b/libcli/security/security_descriptor.c
@@ -50,7 +50,7 @@ struct security_descriptor *security_descriptor_initialise(TALLOC_CTX *mem_ctx)
 	return sd;
 }
 
-static struct security_acl *security_acl_dup(TALLOC_CTX *mem_ctx,
+struct security_acl *security_acl_dup(TALLOC_CTX *mem_ctx,
 					     const struct security_acl *oacl)
 {
 	struct security_acl *nacl;
diff --git a/libcli/security/security_descriptor.h b/libcli/security/security_descriptor.h
index c535f5d..a377ef5 100644
--- a/libcli/security/security_descriptor.h
+++ b/libcli/security/security_descriptor.h
@@ -61,4 +61,7 @@ struct security_ace *security_ace_create(TALLOC_CTX *mem_ctx,
 					 uint32_t access_mask,
 					 uint8_t flags);
 
+struct security_acl *security_acl_dup(TALLOC_CTX *mem_ctx,
+				      const struct security_acl *oacl);
+
 #endif /* __SECURITY_DESCRIPTOR_H__ */
diff --git a/librpc/gen_ndr/ndr_security.c b/librpc/gen_ndr/ndr_security.c
index c227170..0bc039d 100644
--- a/librpc/gen_ndr/ndr_security.c
+++ b/librpc/gen_ndr/ndr_security.c
@@ -850,6 +850,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_security_token(struct ndr_push *ndr, int ndr
 			NDR_CHECK(ndr_push_unique_ptr(ndr, r->sids[cntr_sids_0]));
 		}
 		NDR_CHECK(ndr_push_udlong(ndr, NDR_SCALARS, r->privilege_mask));
+		NDR_CHECK(ndr_push_unique_ptr(ndr, r->default_dacl));
 	}
 	if (ndr_flags & NDR_BUFFERS) {
 		if (r->user_sid) {
@@ -863,6 +864,9 @@ _PUBLIC_ enum ndr_err_code ndr_push_security_token(struct ndr_push *ndr, int ndr
 				NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, r->sids[cntr_sids_0]));
 			}
 		}
+		if (r->default_dacl) {
+			NDR_CHECK(ndr_push_security_acl(ndr, NDR_SCALARS|NDR_BUFFERS, r->default_dacl));
+		}
 	}
 	return NDR_ERR_SUCCESS;
 }
@@ -877,6 +881,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_security_token(struct ndr_pull *ndr, int ndr
 	uint32_t cntr_sids_0;
 	TALLOC_CTX *_mem_save_sids_0;
 	TALLOC_CTX *_mem_save_sids_1;
+	uint32_t _ptr_default_dacl;
+	TALLOC_CTX *_mem_save_default_dacl_0;
 	if (ndr_flags & NDR_SCALARS) {
 		NDR_CHECK(ndr_pull_align(ndr, 4));
 		NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_user_sid));
@@ -906,6 +912,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_security_token(struct ndr_pull *ndr, int ndr
 		}
 		NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sids_0, 0);
 		NDR_CHECK(ndr_pull_udlong(ndr, NDR_SCALARS, &r->privilege_mask));
+		NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_default_dacl));
+		if (_ptr_default_dacl) {
+			NDR_PULL_ALLOC(ndr, r->default_dacl);
+		} else {
+			r->default_dacl = NULL;
+		}
 		if (r->sids) {
 			NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->sids, r->num_sids));
 		}
@@ -934,6 +946,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_security_token(struct ndr_pull *ndr, int ndr
 			}
 		}
 		NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sids_0, 0);
+		if (r->default_dacl) {
+			_mem_save_default_dacl_0 = NDR_PULL_GET_MEM_CTX(ndr);
+			NDR_PULL_SET_MEM_CTX(ndr, r->default_dacl, 0);
+			NDR_CHECK(ndr_pull_security_acl(ndr, NDR_SCALARS|NDR_BUFFERS, r->default_dacl));
+			NDR_PULL_SET_MEM_CTX(ndr, _mem_save_default_dacl_0, 0);
+		}
 	}
 	return NDR_ERR_SUCCESS;
 }
@@ -972,6 +990,12 @@ _PUBLIC_ void ndr_print_security_token(struct ndr_print *ndr, const char *name,
 	}
 	ndr->depth--;
 	ndr_print_udlong(ndr, "privilege_mask", r->privilege_mask);
+	ndr_print_ptr(ndr, "default_dacl", r->default_dacl);
+	ndr->depth++;
+	if (r->default_dacl) {
+		ndr_print_security_acl(ndr, "default_dacl", r->default_dacl);
+	}
+	ndr->depth--;
 	ndr->depth--;
 }
 
@@ -1030,3 +1054,29 @@ _PUBLIC_ void ndr_print_kerb_EncTypes(struct ndr_print *ndr, const char *name, u
 	ndr->depth--;
 }
 
+_PUBLIC_ enum ndr_err_code ndr_push_security_autoinherit(struct ndr_push *ndr, int ndr_flags, uint32_t r)
+{
+	NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
+	return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_security_autoinherit(struct ndr_pull *ndr, int ndr_flags, uint32_t *r)
+{
+	uint32_t v;
+	NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+	*r = v;
+	return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_security_autoinherit(struct ndr_print *ndr, const char *name, uint32_t r)
+{
+	ndr_print_uint32(ndr, name, r);
+	ndr->depth++;
+	ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "SEC_DACL_AUTO_INHERIT", SEC_DACL_AUTO_INHERIT, r);
+	ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "SEC_SACL_AUTO_INHERIT", SEC_SACL_AUTO_INHERIT, r);
+	ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "SEC_DEFAULT_DESCRIPTOR", SEC_DEFAULT_DESCRIPTOR, r);
+	ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "SEC_OWNER_FROM_PARENT", SEC_OWNER_FROM_PARENT, r);
+	ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "SEC_GROUP_FROM_PARENT", SEC_GROUP_FROM_PARENT, r);
+	ndr->depth--;
+}
+
diff --git a/librpc/gen_ndr/ndr_security.h b/librpc/gen_ndr/ndr_security.h
index eddd3c3..b900d54 100644
--- a/librpc/gen_ndr/ndr_security.h
+++ b/librpc/gen_ndr/ndr_security.h
@@ -51,4 +51,7 @@ void ndr_print_security_secinfo(struct ndr_print *ndr, const char *name, uint32_
 enum ndr_err_code ndr_push_kerb_EncTypes(struct ndr_push *ndr, int ndr_flags, uint32_t r);
 enum ndr_err_code ndr_pull_kerb_EncTypes(struct ndr_pull *ndr, int ndr_flags, uint32_t *r);
 void ndr_print_kerb_EncTypes(struct ndr_print *ndr, const char *name, uint32_t r);
+enum ndr_err_code ndr_push_security_autoinherit(struct ndr_push *ndr, int ndr_flags, uint32_t r);
+enum ndr_err_code ndr_pull_security_autoinherit(struct ndr_pull *ndr, int ndr_flags, uint32_t *r);
+void ndr_print_security_autoinherit(struct ndr_print *ndr, const char *name, uint32_t r);
 #endif /* _HEADER_NDR_security */
diff --git a/librpc/gen_ndr/security.h b/librpc/gen_ndr/security.h
index d1dcbe5..e0a3528 100644
--- a/librpc/gen_ndr/security.h
+++ b/librpc/gen_ndr/security.h
@@ -76,6 +76,11 @@
 #define STANDARD_RIGHTS_READ_ACCESS	( SEC_STD_READ_CONTROL )
 #define STANDARD_RIGHTS_WRITE_ACCESS	( (SEC_STD_WRITE_OWNER|SEC_STD_WRITE_DAC|SEC_STD_DELETE) )
 #define STANDARD_RIGHTS_REQUIRED_ACCESS	( (SEC_STD_DELETE|SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER) )
+#define SEC_ADS_GENERIC_ALL_DS	( (SEC_STD_DELETE|SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER|SEC_ADS_CREATE_CHILD|SEC_ADS_DELETE_CHILD|SEC_ADS_DELETE_TREE|SEC_ADS_CONTROL_ACCESS) )
+#define SEC_ADS_GENERIC_EXECUTE	( SEC_STD_READ_CONTROL|SEC_ADS_LIST )
+#define SEC_ADS_GENERIC_WRITE	( (SEC_STD_READ_CONTROL|SEC_ADS_SELF_WRITE|SEC_ADS_WRITE_PROP) )
+#define SEC_ADS_GENERIC_READ	( (SEC_STD_READ_CONTROL|SEC_ADS_LIST|SEC_ADS_READ_PROP|SEC_ADS_LIST_OBJECT) )
+#define SEC_ADS_GENERIC_ALL	( (SEC_ADS_GENERIC_EXECUTE|SEC_ADS_GENERIC_WRITE|SEC_ADS_GENERIC_READ|SEC_ADS_GENERIC_ALL_DS) )
 #define SID_NULL	( "S-1-0-0" )
 #define NAME_WORLD	( "WORLD" )
 #define SID_WORLD_DOMAIN	( "S-1-1" )
@@ -341,6 +346,7 @@ struct security_token {
 	uint32_t num_sids;
 	struct dom_sid **sids;/* [unique,size_is(num_sids)] */
 	uint64_t privilege_mask;
+	struct security_acl *default_dacl;/* [unique] */
 }/* [public] */;
 
 /* bitmap security_secinfo */
@@ -360,4 +366,11 @@ struct security_token {
 #define KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 ( 0x00000008 )
 #define KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 ( 0x00000010 )
 
+/* bitmap security_autoinherit */
+#define SEC_DACL_AUTO_INHERIT ( 0x00000001 )
+#define SEC_SACL_AUTO_INHERIT ( 0x00000002 )
+#define SEC_DEFAULT_DESCRIPTOR ( 0x00000004 )
+#define SEC_OWNER_FROM_PARENT ( 0x00000008 )
+#define SEC_GROUP_FROM_PARENT ( 0x00000010 )
+
 #endif /* _HEADER_security */
diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl
index 9728c7f..96d24b6 100644
--- a/librpc/idl/security.idl
+++ b/librpc/idl/security.idl
@@ -159,6 +159,32 @@ interface security
 		 SEC_STD_WRITE_DAC		|
 		 SEC_STD_WRITE_OWNER);	/* 0x000f0000 */
 
+	/* generic->specific mappings for Directory Service objects */
+	/* directory specific part of GENERIC_ALL */
+	const int SEC_ADS_GENERIC_ALL_DS =
+		(SEC_STD_DELETE                 |
+		 SEC_STD_WRITE_DAC              |
+		 SEC_STD_WRITE_OWNER            |
+		 SEC_ADS_CREATE_CHILD           |
+		 SEC_ADS_DELETE_CHILD           |
+		 SEC_ADS_DELETE_TREE            |
+		 SEC_ADS_CONTROL_ACCESS);
+	const int SEC_ADS_GENERIC_EXECUTE = SEC_STD_READ_CONTROL | SEC_ADS_LIST;
+	const int SEC_ADS_GENERIC_WRITE   =
+		(SEC_STD_READ_CONTROL           |
+		 SEC_ADS_SELF_WRITE             |
+		 SEC_ADS_WRITE_PROP);
+	const int SEC_ADS_GENERIC_READ    =
+		(SEC_STD_READ_CONTROL           |
+		 SEC_ADS_LIST                   |
+		 SEC_ADS_READ_PROP              |
+		 SEC_ADS_LIST_OBJECT);
+	const int SEC_ADS_GENERIC_ALL     =
+		(SEC_ADS_GENERIC_EXECUTE        |
+		 SEC_ADS_GENERIC_WRITE          |
+		 SEC_ADS_GENERIC_READ           |
+		 SEC_ADS_GENERIC_ALL_DS);
+
 	/***************************************************************/
 	/* WELL KNOWN SIDS */
 
@@ -397,6 +423,7 @@ interface security
 		uint32 num_sids;
 		[size_is(num_sids)] dom_sid *sids[*];
 		udlong privilege_mask;
+		security_acl *default_dacl;
 	} security_token;
 
 	/* bits that determine which parts of a security descriptor
@@ -420,4 +447,11 @@ interface security
 		KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 = 0x00000010
 	} kerb_EncTypes;
 
+	typedef [public,bitmap32bit] bitmap {
+		SEC_DACL_AUTO_INHERIT                = 0x00000001,
+		SEC_SACL_AUTO_INHERIT                = 0x00000002,
+		SEC_DEFAULT_DESCRIPTOR               = 0x00000004,
+		SEC_OWNER_FROM_PARENT                = 0x00000008,
+		SEC_GROUP_FROM_PARENT                = 0x00000010
+	} security_autoinherit;
 }
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk
index 18144dd..f868f8a 100644
--- a/source4/dsdb/samdb/ldb_modules/config.mk
+++ b/source4/dsdb/samdb/ldb_modules/config.mk
@@ -334,3 +334,15 @@ INIT_FUNCTION = LDB_MODULE(operational)
 ################################################
 
 ldb_operational_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/operational.o
+
+################################################
+# Start MODULE ldb_descriptor
+[MODULE::ldb_descriptor]
+INIT_FUNCTION = LDB_MODULE(descriptor)
+CFLAGS = -Ilib/ldb/include
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBSECURITY NDR_SECURITY SAMDB
+SUBSYSTEM = LIBLDB
+# End MODULE ldb_descriptor
+################################################
+
+ldb_descriptor_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/descriptor.o
diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c
new file mode 100644
index 0000000..a22cce7
--- /dev/null
+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c
@@ -0,0 +1,459 @@
+   /*
+   ldb database library
+
+   Copyright (C) Simo Sorce  2006-2008
+   Copyright (C) Andrew Bartlett <abartlet at samba.org> 2005-2007
+   Copyright (C) Nadezhda Ivanova  2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ *  Name: ldb
+ *
+ *  Component: DS Security descriptor module
+ *
+ *  Description:
+ *  - Calculate the security descriptor of a newly created object
+ *  - Perform sd recalculation on a move operation
+ *  - Handle sd modification invariants
+ *
+ *  Author: Nadezhda Ivanova
+ */
+
+#include "includes.h"
+#include "ldb_module.h"
+#include "dlinklist.h"
+#include "dsdb/samdb/samdb.h"
+#include "librpc/ndr/libndr.h"
+#include "librpc/gen_ndr/ndr_security.h"
+#include "libcli/security/security.h"
+#include "auth/auth.h"
+#include "param/param.h"
+
+struct descriptor_context {
+		struct ldb_module *module;
+		struct ldb_request *req;
+		struct ldb_reply *search_res;
+		int (*step_fn)(struct descriptor_context *);
+};
+
+static struct dsdb_class * get_last_structural_class(const struct dsdb_schema *schema, struct ldb_message_element *element)
+{
+	struct dsdb_class *last_class = NULL;
+	int i;
+	for (i = 0; i < element->num_values; i++){
+		if (!last_class)
+			last_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &element->values[i]);
+		else {
+			struct dsdb_class *tmp_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &element->values[i]);
+			if (tmp_class->subClass_order > last_class->subClass_order)
+				last_class = tmp_class;
+		}
+	}
+	return last_class;
+}
+
+struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
+			       struct ldb_dn *dn,
+			       struct security_token *token,
+			       struct ldb_context *ldb)
+{
+	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+	struct ldb_dn *root_base_dn = ldb_get_root_basedn(ldb);
+	struct ldb_dn *schema_base_dn = ldb_get_schema_basedn(ldb);
+	struct ldb_dn *config_base_dn = ldb_get_config_basedn(ldb);
+	const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
+	struct dom_sid *da_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
+	struct dom_sid *ea_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS);
+	struct dom_sid *sa_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_SCHEMA_ADMINS);
+	struct dom_sid *dag_sid;
+
+	if (ldb_dn_compare_base(schema_base_dn, dn) == 0){
+		if (security_token_has_sid(token, sa_sid))
+			dag_sid = dom_sid_dup(mem_ctx, sa_sid);
+		else if (security_token_has_sid(token, ea_sid))
+			dag_sid = dom_sid_dup(mem_ctx, ea_sid);
+		else if (security_token_has_sid(token, da_sid))
+			dag_sid = dom_sid_dup(mem_ctx, da_sid);
+		else
+			dag_sid = NULL;
+	}
+	else if (ldb_dn_compare_base(config_base_dn, dn) == 0){
+		if (security_token_has_sid(token, ea_sid))
+			dag_sid = dom_sid_dup(mem_ctx, ea_sid);
+		else if (security_token_has_sid(token, da_sid))
+			dag_sid = dom_sid_dup(mem_ctx, da_sid);
+		else
+			dag_sid = NULL;
+	}
+	else if (ldb_dn_compare_base(root_base_dn, dn) == 0){
+		if (security_token_has_sid(token, da_sid))
+			dag_sid = dom_sid_dup(mem_ctx, da_sid);
+		else if (security_token_has_sid(token, ea_sid))
+				dag_sid = dom_sid_dup(mem_ctx, ea_sid);
+		else
+			dag_sid = NULL;
+	}
+	else
+		dag_sid = NULL;
+
+	talloc_free(tmp_ctx);
+	return dag_sid;
+}
+
+static struct security_descriptor *get_sd_unpacked(struct ldb_module *module, TALLOC_CTX *mem_ctx,
+					    const struct dsdb_class *objectclass)
+{
+	struct ldb_context *ldb = ldb_module_get_ctx(module);
+	struct security_descriptor *sd;
+	const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
+
+	if (!objectclass->defaultSecurityDescriptor || !domain_sid) {
+		return NULL;
+	}
+
+	sd = sddl_decode(mem_ctx,
+			 objectclass->defaultSecurityDescriptor,
+			 domain_sid);
+	return sd;
+}
+
+static struct dom_sid *get_default_group(TALLOC_CTX *mem_ctx,
+					 struct ldb_context *ldb,
+					 struct dom_sid *dag)
+{
+	int *domainFunctionality;
+
+	domainFunctionality = talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int);
+
+	if (*domainFunctionality && (*domainFunctionality >= DS_BEHAVIOR_WIN2008)){
+		return dag;
+	}
+
+	return NULL;
+}
+
+static DATA_BLOB *get_new_descriptor(struct ldb_module *module,
+				     struct ldb_dn *dn,
+				     TALLOC_CTX *mem_ctx,
+				     const struct dsdb_class *objectclass,
+				     struct ldb_val *parent,
+				     struct ldb_val *object)
+{
+	struct security_descriptor *user_descriptor = NULL, *parent_descriptor = NULL;
+	struct security_descriptor *new_sd;
+	DATA_BLOB *linear_sd;
+	enum ndr_err_code ndr_err;
+	struct ldb_context *ldb = ldb_module_get_ctx(module);
+	struct auth_session_info *session_info
+		= ldb_get_opaque(ldb, "sessionInfo");
+	const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
+	char *sddl_sd;
+	struct dom_sid *default_owner;
+	struct dom_sid *default_group;
+
+	if (object){
+		user_descriptor = talloc(mem_ctx, struct security_descriptor);
+		if(!user_descriptor)
+			return NULL;
+		ndr_err = ndr_pull_struct_blob(object, user_descriptor, NULL,
+					       user_descriptor,
+					       (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
+
+		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)){
+			talloc_free(user_descriptor);
+			return NULL;
+		}
+	}
+	else
+		user_descriptor = get_sd_unpacked(module, mem_ctx, objectclass);
+
+	if (parent){
+		parent_descriptor = talloc(mem_ctx, struct security_descriptor);
+		if(!parent_descriptor)
+			return NULL;
+		ndr_err = ndr_pull_struct_blob(parent, parent_descriptor, NULL,
+					       parent_descriptor,
+					       (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
+
+		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)){
+			talloc_free(parent_descriptor);
+			return NULL;
+		}
+	}
+	default_owner = get_default_ag(mem_ctx, dn,
+				       session_info->security_token, ldb);
+	default_group = get_default_group(mem_ctx, ldb, default_owner);
+	new_sd = create_security_descriptor(mem_ctx, parent_descriptor, user_descriptor, true,
+					    NULL, SEC_DACL_AUTO_INHERIT|SEC_SACL_AUTO_INHERIT,
+					    session_info->security_token,
+					    default_owner, default_group,
+					    map_generic_rights_ds);
+	if (!new_sd)
+		return NULL;
+
+
+	sddl_sd = sddl_encode(mem_ctx, new_sd, domain_sid);
+	DEBUG(10, ("Object %s created with desriptor %s", ldb_dn_get_linearized(dn), sddl_sd));
+
+	linear_sd = talloc(mem_ctx, DATA_BLOB);
+	if (!linear_sd) {
+		return NULL;
+	}
+
+	ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
+				       lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
+				       new_sd,
+				       (ndr_push_flags_fn_t)ndr_push_security_descriptor);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		return NULL;
+	}
+
+	return linear_sd;
+}
+
+static struct descriptor_context *descriptor_init_context(struct ldb_module *module,
+							  struct ldb_request *req)
+{
+	struct ldb_context *ldb;
+	struct descriptor_context *ac;
+
+	ldb = ldb_module_get_ctx(module);
+
+	ac = talloc_zero(req, struct descriptor_context);
+	if (ac == NULL) {
+		ldb_set_errstring(ldb, "Out of Memory");
+		return NULL;
+	}
+
+	ac->module = module;
+	ac->req = req;
+	return ac;
+}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list