[SCM] Samba Shared Repository - branch master updated

Matthias Dieter Wallnöfer mdw at samba.org
Sun Oct 31 15:03:01 MDT 2010


The branch, master has been updated
       via  dac6f16 s4:sam.py - test the "sAMAccountName" attribute
       via  51f4de8 s4:samldb LDB module - validate "sAMAccountName" modifications
      from  229f3cc s4:netlogon RPC server - "LogonGetDomainInfo" - always check the LDB return codes

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


- Log -----------------------------------------------------------------
commit dac6f1662e33918659e00f65813a27f3cb4728ce
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Oct 31 21:13:55 2010 +0100

    s4:sam.py - test the "sAMAccountName" attribute
    
    Autobuild-User: Matthias Dieter Wallnöfer <mdw at samba.org>
    Autobuild-Date: Sun Oct 31 21:02:48 UTC 2010 on sn-devel-104

commit 51f4de8fc85c314f23ca09ec88001f4dd2253b7f
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Oct 31 21:04:26 2010 +0100

    s4:samldb LDB module - validate "sAMAccountName" modifications
    
    Also the "sAMAccountName" attribute is protected against corruption (e.g. two
    accounts with the same name).

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/samldb.c |   74 +++++++++++++++++++++++++++++++
 source4/dsdb/tests/python/sam.py        |   59 ++++++++++++++++++++++++
 2 files changed, 133 insertions(+), 0 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 79b557d..b91ca3e 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -186,6 +186,9 @@ static int samldb_check_sAMAccountName(struct samldb_ctx *ac)
 		return ldb_operr(ldb);
 	}
 	if (ret == 1) {
+		ldb_asprintf_errstring(ldb,
+				       "samldb: Account name (sAMAccountName) '%s' already in use!",
+				       name);
 		return LDB_ERR_ENTRY_ALREADY_EXISTS;
 	}
 
@@ -1354,6 +1357,69 @@ static int samldb_group_type_change(struct samldb_ctx *ac)
 	return LDB_SUCCESS;
 }
 
+static int samldb_sam_accountname_check(struct samldb_ctx *ac)
+{
+	struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+	const char *no_attrs[] = { NULL };
+	struct ldb_result *res;
+	const char *sam_accountname, *enc_str;
+	struct ldb_message_element *el;
+	struct ldb_message *tmp_msg;
+	int ret;
+
+	ret = samldb_get_single_valued_attr(ac, "sAMAccountName", &el);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+	if (el == NULL) {
+		/* we are not affected */
+		return LDB_SUCCESS;
+	}
+
+	/* Create a temporary message for fetching the "sAMAccountName" */
+	tmp_msg = ldb_msg_new(ac->msg);
+	if (tmp_msg == NULL) {
+		return ldb_module_oom(ac->module);
+	}
+	ret = ldb_msg_add(tmp_msg, el, 0);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+	sam_accountname = ldb_msg_find_attr_as_string(tmp_msg, "sAMAccountName",
+						      NULL);
+	talloc_free(tmp_msg);
+
+	if (sam_accountname == NULL) {
+		return ldb_operr(ldb);
+	}
+
+	enc_str = ldb_binary_encode_string(ac, sam_accountname);
+	if (enc_str == NULL) {
+		return ldb_module_oom(ac->module);
+	}
+
+	/* Make sure that a "sAMAccountName" is only used once */
+
+	ret = ldb_search(ldb, ac, &res, NULL, LDB_SCOPE_SUBTREE, no_attrs,
+			 "(sAMAccountName=%s)", enc_str);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+	if (res->count > 1) {
+		return ldb_operr(ldb);
+	} else if (res->count == 1) {
+		if (ldb_dn_compare(res->msgs[0]->dn, ac->msg->dn) != 0) {
+			ldb_asprintf_errstring(ldb,
+					       "samldb: Account name (sAMAccountName) '%s' already in use!",
+					       sam_accountname);
+			return LDB_ERR_ENTRY_ALREADY_EXISTS;
+		}
+	}
+	talloc_free(res);
+
+	return LDB_SUCCESS;
+}
+
 static int samldb_member_check(struct samldb_ctx *ac)
 {
 	struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
@@ -1768,6 +1834,14 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
 		}
 	}
 
+	el = ldb_msg_find_element(ac->msg, "sAMAccountName");
+	if (el != NULL) {
+		ret = samldb_sam_accountname_check(ac);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+	}
+
 	el = ldb_msg_find_element(ac->msg, "member");
 	if (el != NULL) {
 		ret = samldb_member_check(ac);
diff --git a/source4/dsdb/tests/python/sam.py b/source4/dsdb/tests/python/sam.py
index ac4b286..cb68ca9 100755
--- a/source4/dsdb/tests/python/sam.py
+++ b/source4/dsdb/tests/python/sam.py
@@ -125,6 +125,17 @@ class SamTests(unittest.TestCase):
         group_rid_2 = security.dom_sid(ldb.schema_format_value("objectSID",
           res1[0]["objectSID"][0])).split()[1]
 
+        # Try to create a user with an invalid account name
+        try:
+            ldb.add({
+                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+                "objectclass": ["user", "person"],
+                "sAMAccountName": "administrator"})
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
+        self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
         # Try to create a user with an invalid primary group
         try:
             ldb.add({
@@ -314,6 +325,34 @@ class SamTests(unittest.TestCase):
             "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
             "objectclass": ["user", "person"]})
 
+        # Try to set an invalid account name
+        m = Message()
+        m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+        m["sAMAccountName"] = MessageElement("administrator", FLAG_MOD_REPLACE,
+          "sAMAccountName")
+        try:
+            ldb.modify(m)
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
+
+        # But to reset the actual "sAMAccountName" should still be possible
+        res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+                          scope=SCOPE_BASE, attrs=["sAMAccountName"])
+        self.assertTrue(len(res1) == 1)
+        m = Message()
+        m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+        m["sAMAccountName"] = MessageElement(res1[0]["sAMAccountName"][0], FLAG_MOD_REPLACE,
+          "sAMAccountName")
+        ldb.modify(m)
+
+        # And another (free) name should be possible as well
+        m = Message()
+        m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+        m["sAMAccountName"] = MessageElement("xxx_ldaptestuser_xxx", FLAG_MOD_REPLACE,
+          "sAMAccountName")
+        ldb.modify(m)
+
         # We should be able to reset our actual primary group
         m = Message()
         m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
@@ -635,6 +674,26 @@ class SamTests(unittest.TestCase):
         except LdbError, (num, _):
             self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
+        m = Message()
+        m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+        m["sAMAccountName"] = MessageElement("test", FLAG_MOD_ADD,
+          "sAMAccountName")
+        try:
+            ldb.modify(m)
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
+
+        m = Message()
+        m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+        m["sAMAccountName"] = MessageElement([], FLAG_MOD_DELETE,
+          "sAMAccountName")
+        try:
+            ldb.modify(m)
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
         self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
         self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list