s4-ldap: Fixed a problem with NC's having a parentGUID attribute
authorNadezhda Ivanova <nivanova@samba.org>
Tue, 21 Sep 2010 16:10:54 +0000 (09:10 -0700)
committerNadezhda Ivanova <nivanova@samba.org>
Tue, 21 Sep 2010 16:10:54 +0000 (09:10 -0700)
NC's other than default NC had a parentGUID, due to an incorrect check of whether
the object has a parent. Fixed by checking object's instanceType instead.

source4/dsdb/samdb/ldb_modules/operational.c
source4/dsdb/tests/python/ldap.py

index 56fb272e2a505f97d534ff756d0c1d118012a56e..ee987d078ed0cb1ba0d5c91ad450c1e42c74ca9f 100644 (file)
@@ -197,48 +197,62 @@ static int construct_token_groups(struct ldb_module *module,
 static int construct_parent_guid(struct ldb_module *module,
                                 struct ldb_message *msg, enum ldb_scope scope)
 {
-       struct ldb_result *res;
+       struct ldb_result *res, *parent_res;
        const struct ldb_val *parent_guid;
-       const char *attrs[] = { "objectGUID", NULL };
+       const char *attrs[] = { "instanceType", NULL };
+       const char *attrs2[] = { "objectGUID", NULL };
+       uint32_t instanceType;
        int ret;
+       struct ldb_dn *parent_dn;
        struct ldb_val v;
 
-       /* TODO:  In the future, this needs to honour the partition boundaries */
-       struct ldb_dn *parent_dn = ldb_dn_get_parent(msg, msg->dn);
+       /* determine if the object is NC by instance type */
+       ret = dsdb_module_search_dn(module, msg, &res, msg->dn, attrs,
+                                   DSDB_FLAG_NEXT_MODULE |
+                                   DSDB_SEARCH_SHOW_DELETED);
+
+       instanceType = ldb_msg_find_attr_as_uint(res->msgs[0],
+                                                "instanceType", 0);
+       talloc_free(res);
+       if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) {
+               DEBUG(4,(__location__ ": Object %s is NC\n",
+                        ldb_dn_get_linearized(msg->dn)));
+               return LDB_SUCCESS;
+       }
+       parent_dn = ldb_dn_get_parent(msg, msg->dn);
 
        if (parent_dn == NULL) {
                DEBUG(4,(__location__ ": Failed to find parent for dn %s\n",
                                         ldb_dn_get_linearized(msg->dn)));
                return LDB_SUCCESS;
        }
-
-       ret = dsdb_module_search_dn(module, msg, &res, parent_dn, attrs,
+       ret = dsdb_module_search_dn(module, msg, &parent_res, parent_dn, attrs2,
                                    DSDB_FLAG_NEXT_MODULE |
                                    DSDB_SEARCH_SHOW_DELETED);
        talloc_free(parent_dn);
 
-       /* if there is no parent for this object, then return */
+       /* not NC, so the object should have a parent*/
        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
                DEBUG(4,(__location__ ": Parent dn for %s does not exist \n",
                         ldb_dn_get_linearized(msg->dn)));
-               return LDB_SUCCESS;
+               return ldb_operr(ldb_module_get_ctx(module));
        } else if (ret != LDB_SUCCESS) {
                return ret;
        }
 
-       parent_guid = ldb_msg_find_ldb_val(res->msgs[0], "objectGUID");
+       parent_guid = ldb_msg_find_ldb_val(parent_res->msgs[0], "objectGUID");
        if (!parent_guid) {
-               talloc_free(res);
+               talloc_free(parent_res);
                return LDB_SUCCESS;
        }
 
-       v = data_blob_dup_talloc(res, parent_guid);
+       v = data_blob_dup_talloc(parent_res, parent_guid);
        if (!v.data) {
-               talloc_free(res);
+               talloc_free(parent_res);
                return ldb_oom(ldb_module_get_ctx(module));
        }
        ret = ldb_msg_add_steal_value(msg, "parentGUID", &v);
-       talloc_free(res);
+       talloc_free(parent_res);
        return ret;
 }
 
index e108e3813556e8a054627dc66d86e94ec6228466..1bdf6f13a1c5d01e1cfe0af5d059854e81fcc334 100755 (executable)
@@ -1038,11 +1038,15 @@ objectClass: container
                           attrs=["objectGUID"]);
         res3 = ldb.search(base=self.base_dn, scope=SCOPE_BASE,
                           attrs=["parentGUID"]);
+        res4 = ldb.search(base=self.configuration_dn, scope=SCOPE_BASE,
+                          attrs=["parentGUID"]);
+        res5 = ldb.search(base=self.schema_dn, scope=SCOPE_BASE,
+                          attrs=["parentGUID"]);
 
         """Check if the parentGUID is valid """
         self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
 
-        """Check if it returns nothing when there is no parent object"""
+        """Check if it returns nothing when there is no parent object - default NC"""
         has_parentGUID = False
         for key in res3[0].keys():
             if key == "parentGUID":
@@ -1050,6 +1054,22 @@ objectClass: container
                 break
         self.assertFalse(has_parentGUID);
 
+        """Check if it returns nothing when there is no parent object - configuration NC"""
+        has_parentGUID = False
+        for key in res4[0].keys():
+            if key == "parentGUID":
+                has_parentGUID = True
+                break
+        self.assertFalse(has_parentGUID);
+
+        """Check if it returns nothing when there is no parent object - schema NC"""
+        has_parentGUID = False
+        for key in res5[0].keys():
+            if key == "parentGUID":
+                has_parentGUID = True
+                break
+        self.assertFalse(has_parentGUID);
+
         """Ensures that if you look for another object attribute after the constructed
             parentGUID, it will return correctly"""
         has_another_attribute = False