[SCM] Samba Shared Repository - branch master updated

Matthias Dieter Wallnöfer mdw at samba.org
Thu Mar 4 10:16:53 MST 2010


The branch, master has been updated
       via  3d94b28... s4:ldap.py - give the "primaryGroupToken" test a better name
       via  4546b6b... s4:ldap.py - add test for "tokenGroups"
       via  8297302... s4:operational LDB - don't accidentally "ate" search helper attributes if we need them for more constructed attributes
       via  ffa0382... s4:operational LDB module - make the counters unsigned
       via  bf94d68... s4:operational LDB - implement the "tokenGroups" constructed attribute
       via  1f371cd... s4:sam.c - make "authsam_expand_nested_groups" public
       via  7587665... s4:sam.c - cosmetic indentation fix
       via  0049c9e... s4:sam.c - change variable types to unsigned in "sids_contains_sid"
       via  e34ee26... s4:operational LDB module - use right memory context int "construct_primary_group_token"
      from  bc2ff7a... Revert "s3:configure: add --enable-as-needed"

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


- Log -----------------------------------------------------------------
commit 3d94b284411d912449b6a316439cc3d013bf1570
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Thu Mar 4 17:54:45 2010 +0100

    s4:ldap.py - give the "primaryGroupToken" test a better name
    
    It tests also some other constructed attributes in a basic way.

commit 4546b6b7dfd7f0e59e11b63c6cf91a4594b8ca54
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Thu Mar 4 17:51:09 2010 +0100

    s4:ldap.py - add test for "tokenGroups"

commit 8297302e989c62092b50a275207046e83cd52800
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Thu Mar 4 16:28:03 2010 +0100

    s4:operational LDB - don't accidentally "ate" search helper attributes if we need them for more constructed attributes
    
    With this patch we delete the helper attributes at the end where all constructed
    attributes have already been computed.

commit ffa03820f1352779988f7cf19190ef6ec2eae33d
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Thu Mar 4 15:44:10 2010 +0100

    s4:operational LDB module - make the counters unsigned
    
    No need to have signed counters here.

commit bf94d68df82f3c7085a6e468b4247fa55d4648ba
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Thu Mar 4 13:58:16 2010 +0100

    s4:operational LDB - implement the "tokenGroups" constructed attribute
    
    It contains the transitive SID closure (expand member/memberOf attributes) of a
    certain SAM object. The "tokenGroups" attribute never contains the SID of the
    object itself.
    
    References: http://msdn.microsoft.com/en-us/library/ms680275(VS.85).aspx,
    http://support.microsoft.com/kb/301916,
    MS-ADTS 3.1.1.4.5.19.

commit 1f371cdbe5a5c2f02ca82a492530fc00b67960d4
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Thu Mar 4 13:49:18 2010 +0100

    s4:sam.c - make "authsam_expand_nested_groups" public
    
    This is needed by the "tokenGroups" work in the operational LDB module.

commit 7587665d928b3297259950ccad0947c192360765
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Thu Mar 4 13:48:17 2010 +0100

    s4:sam.c - cosmetic indentation fix

commit 0049c9ed1c0585b81eeaddd2770e545409b307ed
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Thu Mar 4 13:46:34 2010 +0100

    s4:sam.c - change variable types to unsigned in "sids_contains_sid"
    
    Should also be unsigned - no need for a signed "i" and "num_sids" here.

commit e34ee26169a893e4219e49803885718261faf82b
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Thu Mar 4 14:28:04 2010 +0100

    s4:operational LDB module - use right memory context int "construct_primary_group_token"
    
    Use the "msg" as temporary context and not "ldb" which lives much longer.

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

Summary of changes:
 source4/auth/auth.h                          |    6 ++
 source4/auth/sam.c                           |   12 ++--
 source4/dsdb/samdb/ldb_modules/config.mk     |    2 +-
 source4/dsdb/samdb/ldb_modules/operational.c |  123 +++++++++++++++++++++++--
 source4/lib/ldb/tests/python/ldap.py         |   50 ++++++++++-
 5 files changed, 173 insertions(+), 20 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/auth/auth.h b/source4/auth/auth.h
index b0a907f..bbdbbc3 100644
--- a/source4/auth/auth.h
+++ b/source4/auth/auth.h
@@ -237,6 +237,12 @@ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
 			    bool allow_domain_trust,
 			    bool password_change);
 struct auth_session_info *system_session(struct loadparm_context *lp_ctx);
+NTSTATUS authsam_expand_nested_groups(struct ldb_context *sam_ctx,
+				      const struct dom_sid *sid,
+				      const bool only_childs,
+				      TALLOC_CTX *res_sids_ctx,
+				      struct dom_sid ***res_sids,
+				      unsigned int *num_res_sids);
 NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
 					   const char *netbios_name,
 					   const char *domain_name,
diff --git a/source4/auth/sam.c b/source4/auth/sam.c
index 3ded739..20efc36 100644
--- a/source4/auth/sam.c
+++ b/source4/auth/sam.c
@@ -270,10 +270,11 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
 }
 
 /* This function tests if a SID structure "sids" contains the SID "sid" */
-static bool sids_contains_sid(const struct dom_sid **sids, const int num_sids,
-	const struct dom_sid *sid)
+static bool sids_contains_sid(const struct dom_sid **sids,
+			      const unsigned int num_sids,
+			      const struct dom_sid *sid)
 {
-	int i;
+	unsigned int i;
 
 	for (i = 0; i < num_sids; i++) {
 		if (dom_sid_equal(sids[i], sid))
@@ -296,7 +297,7 @@ static bool sids_contains_sid(const struct dom_sid **sids, const int num_sids,
  *
  * At the beginning "res_sids" should reference to a NULL pointer.
  */
-static NTSTATUS authsam_expand_nested_groups(struct ldb_context *sam_ctx,
+_PUBLIC_ NTSTATUS authsam_expand_nested_groups(struct ldb_context *sam_ctx,
 	const struct dom_sid *sid, const bool only_childs,
 	TALLOC_CTX *res_sids_ctx, struct dom_sid ***res_sids,
 	unsigned int *num_res_sids)
@@ -379,8 +380,7 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx,
 					   struct ldb_message *msg,
 					   DATA_BLOB user_sess_key,
 					   DATA_BLOB lm_sess_key,
-					   struct auth_serversupplied_info
-						   **_server_info)
+					   struct auth_serversupplied_info **_server_info)
 {
 	NTSTATUS status;
 	struct auth_serversupplied_info *server_info;
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk
index e13f44a..586e937 100644
--- a/source4/dsdb/samdb/ldb_modules/config.mk
+++ b/source4/dsdb/samdb/ldb_modules/config.mk
@@ -400,7 +400,7 @@ ldb_instancetype_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/instancetype.o
 [MODULE::ldb_operational]
 SUBSYSTEM = LIBLDB
 CFLAGS = -Ilib/ldb/include
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT LIBSAMBA-UTIL SAMDB_COMMON DSDB_MODULE_HELPERS
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT LIBSAMBA-UTIL SAMDB_COMMON DSDB_MODULE_HELPERS auth_sam
 INIT_FUNCTION = LDB_MODULE(operational)
 # End MODULE ldb_operational
 ################################################
diff --git a/source4/dsdb/samdb/ldb_modules/operational.c b/source4/dsdb/samdb/ldb_modules/operational.c
index b017f23..1d02698 100644
--- a/source4/dsdb/samdb/ldb_modules/operational.c
+++ b/source4/dsdb/samdb/ldb_modules/operational.c
@@ -72,6 +72,9 @@
 #include "dsdb/samdb/samdb.h"
 #include "dsdb/samdb/ldb_modules/util.h"
 
+#include "auth/auth.h"
+#include "libcli/security/dom_sid.h"
+
 #ifndef ARRAY_SIZE
 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
 #endif
@@ -106,18 +109,109 @@ static int construct_primary_group_token(struct ldb_module *module,
 	ldb = ldb_module_get_ctx(module);
 	if (ldb_match_msg_objectclass(msg, "group") == 1) {
 		primary_group_token
-			= samdb_result_rid_from_sid(ldb, msg, "objectSid", 0);
+			= samdb_result_rid_from_sid(msg, msg, "objectSid", 0);
 		if (primary_group_token == 0) {
 			return LDB_SUCCESS;
 		}
 
-		return samdb_msg_add_int(ldb, ldb, msg, "primaryGroupToken",
+		return samdb_msg_add_int(ldb, msg, msg, "primaryGroupToken",
 			primary_group_token);
 	} else {
 		return LDB_SUCCESS;
 	}
 }
 
+/*
+  construct the token groups for SAM objects from a message
+*/
+static int construct_token_groups(struct ldb_module *module,
+				  struct ldb_message *msg)
+{
+	struct ldb_context *ldb;
+	const struct dom_sid *sid;
+
+	ldb = ldb_module_get_ctx(module);
+
+	sid = samdb_result_dom_sid(msg, msg, "objectSid");
+	if (sid != NULL) {
+		NTSTATUS status;
+		uint32_t prim_group_rid;
+		struct dom_sid **sids = NULL;
+		unsigned int i, num_sids = 0;
+		int ret;
+
+		prim_group_rid = samdb_result_uint(msg, "primaryGroupID", 0);
+		if (prim_group_rid != 0) {
+			struct dom_sid *prim_group_sid;
+
+			prim_group_sid = dom_sid_add_rid(msg,
+							 samdb_domain_sid(ldb),
+							 prim_group_rid);
+			if (prim_group_sid == NULL) {
+				ldb_oom(ldb);
+				return LDB_ERR_OPERATIONS_ERROR;
+			}
+
+			/* onlyChilds = false, we want to consider also the
+			 * "primaryGroupID" for membership */
+			status = authsam_expand_nested_groups(ldb,
+							      prim_group_sid,
+							      false, msg,
+							      &sids, &num_sids);
+			if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) {
+				ldb_oom(ldb);
+				return LDB_ERR_OPERATIONS_ERROR;
+			}
+			if (!NT_STATUS_IS_OK(status)) {
+				return LDB_ERR_OPERATIONS_ERROR;
+			}
+
+			for (i = 0; i < num_sids; i++) {
+				ret = samdb_msg_add_dom_sid(ldb, msg, msg,
+							    "tokenGroups",
+							    sids[i]);
+				if (ret != LDB_SUCCESS) {
+					talloc_free(sids);
+					return ret;
+				}
+			}
+
+			talloc_free(sids);
+		}
+
+		sids = NULL;
+		num_sids = 0;
+
+		/* onlyChils = true, we don't want to have the SAM object itself
+		 * in the result */
+		status = authsam_expand_nested_groups(ldb, sid, true, msg,
+						      &sids, &num_sids);
+		if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) {
+			ldb_oom(ldb);
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+		if (!NT_STATUS_IS_OK(status)) {
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+
+		for (i = 0; i < num_sids; i++) {
+			ret = samdb_msg_add_dom_sid(ldb, msg, msg,
+						    "tokenGroups", sids[i]);
+			if (ret != LDB_SUCCESS) {
+				talloc_free(sids);
+				return ret;
+			}
+		}
+
+		talloc_free(sids);
+	}
+
+	return LDB_SUCCESS;
+}
+
+/*
+  construct the parent GUID for an entry from a message
+*/
 static int construct_parent_guid(struct ldb_module *module,
 				 struct ldb_message *msg)
 {
@@ -207,6 +301,7 @@ static const struct {
 	{ "structuralObjectClass", "objectClass", NULL , NULL },
 	{ "canonicalName", "distinguishedName", NULL , construct_canonical_name },
 	{ "primaryGroupToken", "objectClass", "objectSid", construct_primary_group_token },
+	{ "tokenGroups", "objectSid", "primaryGroupID", construct_token_groups },
 	{ "parentGUID", NULL, NULL, construct_parent_guid },
 	{ "subSchemaSubEntry", NULL, NULL, construct_subschema_subentry }
 };
@@ -249,7 +344,8 @@ static int operational_search_post_process(struct ldb_module *module,
 					   bool sd_flags_set)
 {
 	struct ldb_context *ldb;
-	int i, a=0;
+	unsigned int i, a = 0;
+	bool constructed_attributes = false;
 
 	ldb = ldb_module_get_ctx(module);
 
@@ -281,6 +377,7 @@ static int operational_search_post_process(struct ldb_module *module,
 
 			/* construct the new attribute, using either a supplied
 			   constructor or a simple copy */
+			constructed_attributes = true;
 			if (search_sub[i].constructor != NULL) {
 				if (search_sub[i].constructor(module, msg) != LDB_SUCCESS) {
 					goto failed;
@@ -290,17 +387,23 @@ static int operational_search_post_process(struct ldb_module *module,
 						     search_sub[i].attr) != LDB_SUCCESS) {
 				goto failed;
 			}
+		}
+	}
 
-			/* remove the added search attribute, unless it was
- 			   asked for by the user */
+	/* Deletion of the search helper attributes are needed if:
+	 * - we generated constructed attributes and
+	 * - we aren't requesting all attributes
+	 */
+	if ((constructed_attributes) && (!ldb_attr_in_list(attrs, "*"))) {
+		for (i=0;i<ARRAY_SIZE(search_sub);i++) {
+			/* remove the added search helper attributes, unless
+			 * they were asked for by the user */
 			if (search_sub[i].replace != NULL && 
-			    !ldb_attr_in_list(attrs, search_sub[i].replace) &&
-			    !ldb_attr_in_list(attrs, "*")) {
+			    !ldb_attr_in_list(attrs, search_sub[i].replace)) {
 				ldb_msg_remove_attr(msg, search_sub[i].replace);
 			}
 			if (search_sub[i].extra_attr != NULL && 
-			    !ldb_attr_in_list(attrs, search_sub[i].extra_attr) &&
-			    !ldb_attr_in_list(attrs, "*")) {
+			    !ldb_attr_in_list(attrs, search_sub[i].extra_attr)) {
 				ldb_msg_remove_attr(msg, search_sub[i].extra_attr);
 			}
 		}
@@ -377,7 +480,7 @@ static int operational_search(struct ldb_module *module, struct ldb_request *req
 	struct operational_context *ac;
 	struct ldb_request *down_req;
 	const char **search_attrs = NULL;
-	int i, a;
+	unsigned int i, a;
 	int ret;
 
 	ldb = ldb_module_get_ctx(module);
diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py
index 798047c..6d01fcd 100755
--- a/source4/lib/ldb/tests/python/ldap.py
+++ b/source4/lib/ldb/tests/python/ldap.py
@@ -772,9 +772,9 @@ objectClass: container
         self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
         self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
 
-    def test_primary_group_token(self):
-        """Test the primary group token behaviour (hidden-generated-readonly attribute on groups)"""
-        print "Testing primary group token behaviour\n"
+    def test_primary_group_token_constructed(self):
+        """Test the primary group token behaviour (hidden-generated-readonly attribute on groups) and some other constructed attributes"""
+        print "Testing primary group token behaviour and other constructed attributes\n"
 
         try:
             ldb.add({
@@ -846,6 +846,50 @@ objectClass: container
         self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
         self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
+    def test_tokenGroups(self):
+        """Test the tokenGroups behaviour (hidden-generated-readonly attribute on SAM objects)"""
+        print "Testing tokenGroups behaviour\n"
+
+        # The domain object shouldn't contain any "tokenGroups" entry
+        res = ldb.search(self.base_dn, scope=SCOPE_BASE, attrs=["tokenGroups"])
+        self.assertTrue(len(res) == 1)
+        self.assertFalse("tokenGroups" in res[0])
+
+        # The domain administrator should contain "tokenGroups" entries
+        # (the exact number depends on the domain/forest function level and the
+        # DC software versions)
+        res = ldb.search("cn=Administrator,cn=Users," + self.base_dn,
+                         scope=SCOPE_BASE, attrs=["tokenGroups"])
+        self.assertTrue(len(res) == 1)
+        self.assertTrue("tokenGroups" in res[0])
+
+        ldb.add({
+            "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+            "objectclass": ["user", "person"]})
+
+        # This testuser should contain at least two "tokenGroups" entries
+        # (exactly two on an unmodified "Domain Users" and "Users" group)
+        res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+                         scope=SCOPE_BASE, attrs=["tokenGroups"])
+        self.assertTrue(len(res) == 1)
+        self.assertTrue(len(res[0]["tokenGroups"]) >= 2)
+
+        # one entry which we need to find should point to domains "Domain Users"
+        # group and another entry should point to the builtin "Users"group
+        domain_users_group_found = False
+        users_group_found = False
+        for sid in res[0]["tokenGroups"]:
+            rid = security.dom_sid(ldb.schema_format_value("objectSID", sid)).split()[1]
+            if rid == 513:
+                domain_users_group_found = True
+            if rid == 545:
+                users_group_found = True
+
+        self.assertTrue(domain_users_group_found)
+        self.assertTrue(users_group_found)
+
+        self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
     def test_wkguid(self):
         """Test Well known GUID behaviours (including DN+Binary)"""
         print "Test Well known GUID behaviours (including DN+Binary)"""


-- 
Samba Shared Repository


More information about the samba-cvs mailing list