From aa57fd8224a09f26a0f6127024fe739b84eadf49 Mon Sep 17 00:00:00 2001 From: Nadezhda Ivanova Date: Tue, 21 Sep 2010 09:10:54 -0700 Subject: [PATCH] s4-ldap: Fixed a problem with NC's having a parentGUID attribute 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 | 40 +++++++++++++++++++--------- source4/dsdb/tests/python/ldap.py | 22 ++++++++++++++- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/operational.c b/source4/dsdb/samdb/ldb_modules/operational.c index 56fb272e2a5..ee987d078ed 100644 --- a/source4/dsdb/samdb/ldb_modules/operational.c +++ b/source4/dsdb/samdb/ldb_modules/operational.c @@ -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; } diff --git a/source4/dsdb/tests/python/ldap.py b/source4/dsdb/tests/python/ldap.py index e108e381355..1bdf6f13a1c 100755 --- a/source4/dsdb/tests/python/ldap.py +++ b/source4/dsdb/tests/python/ldap.py @@ -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 -- 2.11.4.GIT