[SCM] Samba Shared Repository - branch master updated

Matthias Dieter Wallnöfer mdw at samba.org
Wed May 25 02:27:02 MDT 2011


The branch, master has been updated
       via  ff47927 s4:samldb LDB module - check if the RODC group exists if creating an RODC
       via  08f5ed8 s4:samldb LDB module - better to call "samldb_prim_group_trigger"
       via  779d882 s4:samldb LDB module - convert a "dsdb_module_search" into "dsdb_module_search_dn"
       via  11937ce s4:sam.py - uncomment/enhance some account type tests
       via  2ad0100 s4:samldb LDB modules - only objectClass "computer" is allowed to embed all types of account
       via  4740473 s4:sam.py - tests for "isCriticalSystemObject" attribute
       via  0c753e5 s4:samldb LDB module - fix "isCriticalSystemObject" behaviour
       via  c72d32d s4:sam.py - unchanged "primaryGroupID" when account type remains the same
       via  b712c72 s4:samldb LDB module - fix the behaviour when changing the "userAccountControl"
      from  ee0ee5e s3-testparm Warn about incorrect use of 'password server'

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


- Log -----------------------------------------------------------------
commit ff47927fb960b9a6c9a1ca7236dc4562c5a68461
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Tue May 24 22:05:46 2011 +0200

    s4:samldb LDB module - check if the RODC group exists if creating an RODC
    
    Older AD deployments simply don't have it and hence there is no RODC
    support.
    
    Reviewed-by: abartlet
    
    Autobuild-User: Matthias Dieter Wallnöfer <mdw at samba.org>
    Autobuild-Date: Wed May 25 10:26:37 CEST 2011 on sn-devel-104

commit 08f5ed8b4f21f1c52ce7a5de8c692df20d21f571
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Tue May 24 21:21:19 2011 +0200

    s4:samldb LDB module - better to call "samldb_prim_group_trigger"
    
    "samldb_prim_group_trigger" which as a wrapper calls "samldb_prim_group_change"
    for a LDB modify operation.
    
    Reviewed-by: abartlet

commit 779d882aca4fb0486bea0109c3630e1d7abef840
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Mon May 23 12:59:58 2011 +0200

    s4:samldb LDB module - convert a "dsdb_module_search" into "dsdb_module_search_dn"
    
    It saves us from checking the number of returned entries.
    
    Reviewed-by: abartlet

commit 11937ce5e1b02af2eed2bc4d61c71875838c23a8
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Mon May 23 12:52:35 2011 +0200

    s4:sam.py - uncomment/enhance some account type tests
    
    Reviewed-by: abartlet

commit 2ad0100d5ba3e388ead950b0cc6dbf887f907625
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Mon May 23 12:51:06 2011 +0200

    s4:samldb LDB modules - only objectClass "computer" is allowed to embed all types of account
    
    Reviewed-by: abartlet

commit 4740473591d5bf58570a7105123b92aadb8d056e
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Mon May 23 12:05:57 2011 +0200

    s4:sam.py - tests for "isCriticalSystemObject" attribute
    
    Reviewed-by: abartlet

commit 0c753e503c977c470aeb4fcce5b74f283ba2012f
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Mon May 23 11:46:39 2011 +0200

    s4:samldb LDB module - fix "isCriticalSystemObject" behaviour
    
    Tests against Windows Server show that it gets set to "FALSE" (not
    deleted) if we change the account type to a domain member.
    
    Reviewed-by: abartlet

commit c72d32da6ddfe5572b239a95807137d508145e53
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Mon May 23 10:48:16 2011 +0200

    s4:sam.py - unchanged "primaryGroupID" when account type remains the same
    
    Enhance the testcase with a workstation example.
    
    Reviewed-by: abartlet

commit b712c7273d2362f1f4ee7cd96f6f30c5035244d9
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Mon May 23 10:29:17 2011 +0200

    s4:samldb LDB module - fix the behaviour when changing the "userAccountControl"
    
    Ekacnet was not quite right yet but his patch made me think further.
    This primary group changing is only needed if the account type changes.
    With this patch we do one more search if the "userAccountControl"
    changes but we save us from doing these unneeded and wrong modify replace
    operations most of the time.
    
    Reviewed-by: abartlet

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/samldb.c |  167 ++++++++++++++++-----
 source4/dsdb/tests/python/sam.py        |  248 +++++++++++++++++++++++++++----
 2 files changed, 348 insertions(+), 67 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 216e14d..07c9cdd 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -3,7 +3,7 @@
 
    Copyright (C) Andrew Bartlett <abartlet at samba.org> 2005
    Copyright (C) Simo Sorce  2004-2008
-   Copyright (C) Matthias Dieter Wallnöfer 2009-2010
+   Copyright (C) Matthias Dieter Wallnöfer 2009-2011
 
    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
@@ -790,6 +790,8 @@ static int samldb_schema_info_update(struct samldb_ctx *ac)
 	return LDB_SUCCESS;
 }
 
+static int samldb_prim_group_tester(struct samldb_ctx *ac, uint32_t rid);
+
 /*
  * "Objectclass" trigger (MS-SAMR 3.1.1.8.1)
  *
@@ -897,6 +899,16 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac)
 				return LDB_ERR_OTHER;
 			}
 
+			/* Workstation and (read-only) DC objects do need objectclass "computer" */
+			if ((samdb_find_attribute(ldb, ac->msg,
+						  "objectclass", "computer") == NULL) &&
+			    (user_account_control &
+			     (UF_SERVER_TRUST_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT))) {
+				ldb_set_errstring(ldb,
+						  "samldb: Requested account type does need objectclass 'computer'!");
+				return LDB_ERR_OBJECT_CLASS_VIOLATION;
+			}
+
 			account_type = ds_uf2atype(user_account_control);
 			if (account_type == 0) {
 				ldb_set_errstring(ldb, "samldb: Unrecognized account type!");
@@ -911,11 +923,20 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac)
 			el2 = ldb_msg_find_element(ac->msg, "sAMAccountType");
 			el2->flags = LDB_FLAG_MOD_REPLACE;
 
+			/* "isCriticalSystemObject" might be set */
 			if (user_account_control &
 			    (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) {
-				ret = samdb_msg_set_string(ldb, ac->msg, ac->msg,
-							   "isCriticalSystemObject",
-							   "TRUE");
+				ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject",
+							 "TRUE");
+				if (ret != LDB_SUCCESS) {
+					return ret;
+				}
+				el2 = ldb_msg_find_element(ac->msg,
+							   "isCriticalSystemObject");
+				el2->flags = LDB_FLAG_MOD_REPLACE;
+			} else if (user_account_control & UF_WORKSTATION_TRUST_ACCOUNT) {
+				ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject",
+							 "FALSE");
 				if (ret != LDB_SUCCESS) {
 					return ret;
 				}
@@ -927,6 +948,18 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac)
 			/* Step 1.4: "userAccountControl" -> "primaryGroupID" mapping */
 			if (!ldb_msg_find_element(ac->msg, "primaryGroupID")) {
 				uint32_t rid = ds_uf2prim_group_rid(user_account_control);
+
+				/*
+				 * Older AD deployments don't know about the
+				 * RODC group
+				 */
+				if (rid == DOMAIN_RID_READONLY_DCS) {
+					ret = samldb_prim_group_tester(ac, rid);
+					if (ret != LDB_SUCCESS) {
+						return ret;
+					}
+				}
+
 				ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg,
 							 "primaryGroupID", rid);
 				if (ret != LDB_SUCCESS) {
@@ -1009,26 +1042,14 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac)
  * ac->msg contains the "add"/"modify" message
  */
 
-static int samldb_prim_group_set(struct samldb_ctx *ac)
+static int samldb_prim_group_tester(struct samldb_ctx *ac, uint32_t rid)
 {
 	struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
-	uint32_t rid;
 	struct dom_sid *sid;
 	struct ldb_result *res;
 	int ret;
 	const char *noattrs[] = { NULL };
 
-	rid = ldb_msg_find_attr_as_uint(ac->msg, "primaryGroupID", (uint32_t) -1);
-	if (rid == (uint32_t) -1) {
-		/* we aren't affected of any primary group set */
-		return LDB_SUCCESS;
-
-	} else if (!ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
-		ldb_set_errstring(ldb,
-				  "The primary group isn't settable on add operations!");
-		return LDB_ERR_UNWILLING_TO_PERFORM;
-	}
-
 	sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
 	if (sid == NULL) {
 		return ldb_operr(ldb);
@@ -1054,6 +1075,25 @@ static int samldb_prim_group_set(struct samldb_ctx *ac)
 	return LDB_SUCCESS;
 }
 
+static int samldb_prim_group_set(struct samldb_ctx *ac)
+{
+	struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+	uint32_t rid;
+
+	rid = ldb_msg_find_attr_as_uint(ac->msg, "primaryGroupID", (uint32_t) -1);
+	if (rid == (uint32_t) -1) {
+		/* we aren't affected of any primary group set */
+		return LDB_SUCCESS;
+
+	} else if (!ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
+		ldb_set_errstring(ldb,
+				  "The primary group isn't settable on add operations!");
+		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
+
+	return samldb_prim_group_tester(ac, rid);
+}
+
 static int samldb_prim_group_change(struct samldb_ctx *ac)
 {
 	struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
@@ -1076,14 +1116,11 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
 
 	/* Fetch information from the existing object */
 
-	ret = dsdb_module_search(ac->module, ac, &res, ac->msg->dn, LDB_SCOPE_BASE, attrs,
-				 DSDB_FLAG_NEXT_MODULE, ac->req, NULL);
+	ret = dsdb_module_search_dn(ac->module, ac, &res, ac->msg->dn, attrs,
+				    DSDB_FLAG_NEXT_MODULE, ac->req);
 	if (ret != LDB_SUCCESS) {
 		return ret;
 	}
-	if (res->count != 1) {
-		return ldb_operr(ldb);
-	}
 
 	/* Finds out the DN of the old primary group */
 
@@ -1221,17 +1258,20 @@ static int samldb_prim_group_trigger(struct samldb_ctx *ac)
 
 
 /**
- * This function is called on a LDB modify. It performs some additions/changes
- * on the current LDB message. Changes depend on the value of
- * userAccountControl.
+ * This function is called on LDB modify operations. It performs some additions/
+ * replaces on the current LDB message when "userAccountControl" changes.
  */
 static int samldb_user_account_control_change(struct samldb_ctx *ac)
 {
 	struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
-	uint32_t user_account_control, account_type;
+	uint32_t user_account_control, old_user_account_control, account_type;
 	struct ldb_message_element *el;
 	struct ldb_message *tmp_msg;
 	int ret;
+	struct ldb_result *res;
+	const char *attrs[] = { "userAccountControl", "objectClass", NULL };
+	unsigned int i;
+	bool is_computer = false;
 
 	el = dsdb_get_single_valued_attr(ac->msg, "userAccountControl",
 					 ac->req->operation);
@@ -1259,6 +1299,49 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
 		return LDB_ERR_OTHER;
 	}
 
+	/* Fetch the old "userAccountControl" and "objectClass" */
+	ret = dsdb_module_search_dn(ac->module, ac, &res, ac->msg->dn, attrs,
+				    DSDB_FLAG_NEXT_MODULE, ac->req);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+	old_user_account_control = ldb_msg_find_attr_as_uint(res->msgs[0], "userAccountControl", 0);
+	if (old_user_account_control == 0) {
+		return ldb_operr(ldb);
+	}
+	el = ldb_msg_find_element(res->msgs[0], "objectClass");
+	if (el == NULL) {
+		return ldb_operr(ldb);
+	}
+
+	/* When we do not have objectclass "computer" we cannot switch to a (read-only) DC */
+	for (i = 0; i < el->num_values; i++) {
+		if (ldb_attr_cmp((char *)el->values[i].data, "computer") == 0) {
+			is_computer = true;
+			break;
+		}
+	}
+	if (!is_computer &&
+	    (user_account_control & (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT))) {
+		ldb_set_errstring(ldb,
+				  "samldb: Requested account type does need objectclass 'computer'!");
+		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
+
+	/*
+	 * The functions "ds_uf2atype" and "ds_uf2prim_group_rid" are used as
+	 * detectors for account type changes.
+	 * So if the account type does change then we need to adjust the
+	 * "sAMAccountType", the "isCriticalSystemObject" and the
+	 * "primaryGroupID" attribute.
+	 */
+	if ((ds_uf2atype(user_account_control)
+	     == ds_uf2atype(old_user_account_control)) &&
+	    (ds_uf2prim_group_rid(user_account_control)
+	     == ds_uf2prim_group_rid(old_user_account_control))) {
+		return LDB_SUCCESS;
+	}
+
 	account_type = ds_uf2atype(user_account_control);
 	if (account_type == 0) {
 		ldb_set_errstring(ldb, "samldb: Unrecognized account type!");
@@ -1272,6 +1355,7 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
 	el = ldb_msg_find_element(ac->msg, "sAMAccountType");
 	el->flags = LDB_FLAG_MOD_REPLACE;
 
+	/* "isCriticalSystemObject" might be set/changed */
 	if (user_account_control
 	    & (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) {
 		ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject",
@@ -1282,19 +1366,28 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
 		el = ldb_msg_find_element(ac->msg,
 					   "isCriticalSystemObject");
 		el->flags = LDB_FLAG_MOD_REPLACE;
+	} else if (user_account_control & UF_WORKSTATION_TRUST_ACCOUNT) {
+		ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject",
+					 "FALSE");
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+		el = ldb_msg_find_element(ac->msg,
+					   "isCriticalSystemObject");
+		el->flags = LDB_FLAG_MOD_REPLACE;
 	}
 
-	/*
-	 * If the account has UF_SERVER_TRUST_ACCOUNT or
-	 * UF_WORKSTATION_TRUST_ACCOUNT then change the group
-	 * as it's either a workstation, a RODC, or a DC.
-	 *
-	 * If not it might be just a user that we are enabling
-	 * and in this case we don't want to change its default group.
-	 */
-	if (user_account_control & (UF_SERVER_TRUST_ACCOUNT| UF_WORKSTATION_TRUST_ACCOUNT) &&
-			!ldb_msg_find_element(ac->msg, "primaryGroupID")) {
+	if (!ldb_msg_find_element(ac->msg, "primaryGroupID")) {
 		uint32_t rid = ds_uf2prim_group_rid(user_account_control);
+
+		/* Older AD deployments don't know about the RODC group */
+		if (rid == DOMAIN_RID_READONLY_DCS) {
+			ret = samldb_prim_group_tester(ac, rid);
+			if (ret != LDB_SUCCESS) {
+				return ret;
+			}
+		}
+
 		ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg,
 					 "primaryGroupID", rid);
 		if (ret != LDB_SUCCESS) {
@@ -1992,7 +2085,7 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
 
 	el = ldb_msg_find_element(ac->msg, "primaryGroupID");
 	if (el != NULL) {
-		ret = samldb_prim_group_change(ac);
+		ret = samldb_prim_group_trigger(ac);
 		if (ret != LDB_SUCCESS) {
 			return ret;
 		}
diff --git a/source4/dsdb/tests/python/sam.py b/source4/dsdb/tests/python/sam.py
index ee6f122..b08fba5 100755
--- a/source4/dsdb/tests/python/sam.py
+++ b/source4/dsdb/tests/python/sam.py
@@ -1471,25 +1471,33 @@ class SamTests(unittest.TestCase):
             self.assertEquals(num, ERR_OTHER)
         delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
-# This isn't supported yet in s4
-#        try:
-#            ldb.add({
-#                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
-#                "objectclass": "user",
-#                "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
-#            self.fail()
-#        except LdbError, (num, _):
-#            self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
-#        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-#
-#        try:
-#            ldb.add({
-#                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
-#                "objectclass": "user",
-#                "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)})
-#        except LdbError, (num, _):
-#            self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
-#        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+        try:
+            ldb.add({
+                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+                "objectclass": "user",
+                "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
+        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+        try:
+            ldb.add({
+                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+                "objectclass": "user",
+                "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)})
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
+        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+        try:
+            ldb.add({
+                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+                "objectclass": "user",
+                "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)})
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
+        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
 # This isn't supported yet in s4 - needs ACL module adaption
 #        try:
@@ -1570,17 +1578,16 @@ class SamTests(unittest.TestCase):
         except LdbError, (num, _):
             self.assertEquals(num, ERR_OTHER)
 
-# This isn't supported yet in s4
-#        try:
-#            m = Message()
-#            m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-#            m["userAccountControl"] = MessageElement(
-#              str(UF_SERVER_TRUST_ACCOUNT),
-#              FLAG_MOD_REPLACE, "userAccountControl")
-#            ldb.modify(m)
-#            self.fail()
-#        except LdbError, (num, _):
-#            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+        try:
+            m = Message()
+            m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+            m["userAccountControl"] = MessageElement(
+              str(UF_SERVER_TRUST_ACCOUNT),
+              FLAG_MOD_REPLACE, "userAccountControl")
+            ldb.modify(m)
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
         m = Message()
         m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
@@ -1589,6 +1596,17 @@ class SamTests(unittest.TestCase):
           FLAG_MOD_REPLACE, "userAccountControl")
         ldb.modify(m)
 
+        try:
+            m = Message()
+            m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+            m["userAccountControl"] = MessageElement(
+              str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT),
+              FLAG_MOD_REPLACE, "userAccountControl")
+            ldb.modify(m)
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
         res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
                           scope=SCOPE_BASE, attrs=["sAMAccountType"])
         self.assertTrue(len(res1) == 1)
@@ -1866,6 +1884,10 @@ class SamTests(unittest.TestCase):
 #        except LdbError, (num, _):
 #            self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
 
+        # "primaryGroupID" does not change if account type remains the same
+
+        # For a user account
+
         ldb.add({
             "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
             "objectclass": "user",
@@ -1900,13 +1922,179 @@ class SamTests(unittest.TestCase):
         res1 = ldb.search("cn=ldaptestuser2,cn=users," + self.base_dn,
                           scope=SCOPE_BASE,
                           attrs=["userAccountControl", "primaryGroupID"])
+        self.assertTrue(len(res1) == 1)
         self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
         self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_ADMINS)
 
+        # For a workstation account
+
+        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+                          scope=SCOPE_BASE,
+                          attrs=["primaryGroupID"])
+        self.assertTrue(len(res1) == 1)
+        self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_DOMAIN_MEMBERS)
+
+        m = Message()
+        m.dn = Dn(ldb, "<SID=" + ldb.get_domain_sid() + "-" + str(DOMAIN_RID_USERS) + ">")
+        m["member"] = MessageElement(
+          "cn=ldaptestcomputer,cn=computers," + self.base_dn, FLAG_MOD_ADD, "member")
+        ldb.modify(m)
+
+        m = Message()
+        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+        m["primaryGroupID"] = MessageElement(str(DOMAIN_RID_USERS),
+          FLAG_MOD_REPLACE, "primaryGroupID")
+        ldb.modify(m)
+
+        m = Message()
+        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+        m["userAccountControl"] = MessageElement(
+          str(UF_WORKSTATION_TRUST_ACCOUNT),
+          FLAG_MOD_REPLACE, "userAccountControl")
+        ldb.modify(m)
+
+        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+                          scope=SCOPE_BASE,
+                          attrs=["primaryGroupID"])
+        self.assertTrue(len(res1) == 1)
+        self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS)
+
         delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
         delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
         delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
+    def test_isCriticalSystemObject(self):
+        """Test the isCriticalSystemObject behaviour"""
+        print "Testing isCriticalSystemObject behaviour\n"
+
+        # Add tests
+
+        ldb.add({
+            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+            "objectclass": "computer"})
+
+        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+                          scope=SCOPE_BASE,
+                          attrs=["isCriticalSystemObject"])
+        self.assertTrue(len(res1) == 1)
+        self.assertTrue("isCriticalSystemObject" not in res1[0])
+
+        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+        ldb.add({
+            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+            "objectclass": "computer",
+            "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)})
+
+        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+                          scope=SCOPE_BASE,
+                          attrs=["isCriticalSystemObject"])
+        self.assertTrue(len(res1) == 1)
+        self.assertEquals(res1[0]["isCriticalSystemObject"][0], "FALSE")
+
+        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+        ldb.add({
+            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+            "objectclass": "computer",
+            "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)})
+
+        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+                          scope=SCOPE_BASE,
+                          attrs=["isCriticalSystemObject"])
+        self.assertTrue(len(res1) == 1)
+        self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
+
+        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+        ldb.add({
+            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+            "objectclass": "computer",
+            "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
+
+        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+                          scope=SCOPE_BASE,
+                          attrs=["isCriticalSystemObject"])
+        self.assertTrue(len(res1) == 1)
+        self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
+
+        # Modification tests
+


-- 
Samba Shared Repository


More information about the samba-cvs mailing list