From 1087bd1782b239b208d2d231fd19ad9bd90dfdcb Mon Sep 17 00:00:00 2001 From: Nadezhda Ivanova Date: Fri, 10 Apr 2009 11:50:57 +0300 Subject: [PATCH] Fixed problem with schemaUpdateNow request. "Object already exists" error was returned on schemaUpdateNow request. Python test that adds a new attribute and a new class anc checks for their successfull addition is included in ldap.py. --- source4/dsdb/samdb/ldb_modules/partition.c | 8 +++- source4/dsdb/samdb/ldb_modules/rootdse.c | 2 +- source4/dsdb/schema/schema_init.c | 2 +- source4/dsdb/schema/schema_set.c | 6 +- source4/lib/ldb/tests/python/ldap.py | 57 ++++++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 6 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 3231f7a..808256b 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -1057,7 +1057,13 @@ static int partition_extended_schema_update_now(struct ldb_module *module, struc } /* fire the first one */ - return partition_call_first(ac); + ret = partition_call_first(ac); + + if (ret != LDB_SUCCESS){ + return ret; + } + + return ldb_request_done(req, ret); } diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 9ae894d..5c2a11a 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -454,7 +454,7 @@ static int rootdse_modify(struct ldb_module *module, struct ldb_request *req) } talloc_free(ext_res); - return ret; + return ldb_request_done(req, ret); } _PUBLIC_ const struct ldb_module_ops ldb_rootdse_module_ops = { diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index 3a65c47..0540a08 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -576,7 +576,7 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, (*prefixes)[i].id = blob->ctr.dsdb.mappings[i].id_prefix<<16; oid = talloc_strdup(mem_ctx, blob->ctr.dsdb.mappings[i].oid.oid); (*prefixes)[i].oid = talloc_asprintf_append(oid, "."); - (*prefixes)[i].oid_len = strlen(blob->ctr.dsdb.mappings[i].oid.oid); + (*prefixes)[i].oid_len = strlen((*prefixes)[i].oid); } talloc_free(blob); diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c index dcaeb4f..549fe76 100644 --- a/source4/dsdb/schema/schema_set.c +++ b/source4/dsdb/schema/schema_set.c @@ -130,7 +130,7 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem mod_msg = ldb_msg_diff(ldb, res->msgs[0], msg); if (mod_msg->num_elements > 0) { - ret = ldb_modify(ldb, mod_msg); + ret = samdb_replace(ldb, mem_ctx, mod_msg); } } @@ -149,7 +149,7 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem if (ret == LDB_ERR_NO_SUCH_OBJECT) { ret = ldb_add(ldb, msg_idx); } else if (ret != LDB_SUCCESS) { - } else if (res->count != 1) { + } else if (res_idx->count != 1) { ret = ldb_add(ldb, msg_idx); } else { ret = LDB_SUCCESS; @@ -158,7 +158,7 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem mod_msg = ldb_msg_diff(ldb, res_idx->msgs[0], msg_idx); if (mod_msg->num_elements > 0) { - ret = ldb_modify(ldb, mod_msg); + ret = samdb_replace(ldb, mem_ctx, mod_msg); } } if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py index 7d2c7d0..1aa85a7 100755 --- a/source4/lib/ldb/tests/python/ldap.py +++ b/source4/lib/ldb/tests/python/ldap.py @@ -1043,6 +1043,12 @@ class BaseDnTests(unittest.TestCase): self.assertEquals(len(res), 0) class SchemaTests(unittest.TestCase): + + def delete_force(self, ldb, dn): + try: + ldb.delete(dn) + except LdbError, (num, _): + self.assertEquals(num, ERR_NO_SUCH_OBJECT) def find_schemadn(self, ldb): res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"]) self.assertEquals(len(res), 1) @@ -1069,6 +1075,57 @@ class SchemaTests(unittest.TestCase): self.assertFalse("dITContentRules" in res[0]) self.assertFalse("objectClasses" in res[0]) self.assertFalse("attributeTypes" in res[0]) + + def test_schemaUpdateNow(self): + """Testing schemaUpdateNow works correctly""" + self.delete_force(self.ldb, "CN=ATest-Attribute1," + self.schema_dn) + ldif = "dn: CN=ATest-Attribute1," + self.schema_dn + ldif += "\nobjectClass: top" + ldif += "\nobjectClass: attributeSchema" + ldif += "\ncn: ATest-Attribute1" + ldif += "\nlDAPDisplayName: atestAttribute1" + ldif += "\nobjectCategory: CN=AAttribute-Schema," + self.schema_dn + ldif += "\nattributeID: 1.2.840.113556.1.999.998" + ldif += "\nattributeSyntax: 2.5.5.10" + ldif += "\ninstanceType: 4" + ldif += "\nisSingleValued: TRUE" + ldif += "\noMSyntax: 4" + self.ldb.add_ldif(ldif) + # Call schemaUpdateNow + ldif = "dn:" + ldif += "\nchangetype: modify" + ldif += "\nadd: schemaUpdateNow" + ldif += "\nschemaUpdateNow: 1" + self.ldb.modify_ldif(ldif) + # Create schemaClass object + self.delete_force(self.ldb, "CN=Test-Class," + self.schema_dn) + ldif = "dn: CN=Test-Class," + self.schema_dn + ldif += "\nobjectClass: top" + ldif += "\nobjectClass: classSchema" + ldif += "\ncn: Test-Class" + ldif += "\nlDAPDisplayName: testClass" + ldif += "\ndefaultObjectCategory: CN=Person," + self.schema_dn + ldif += "\nobjectCategory: CN=Class-Schema," + self.schema_dn + ldif += "\ngovernsID: 1.2.840.113556.1.5.9999" + ldif += "\ninstanceType: 4" + ldif += "\nobjectClassCategory: 1" + ldif += "\nsubClassOf: organizationalPerson" + self.ldb.add_ldif(ldif) + # Call schemaUpdateNow + ldif = "dn:" + ldif += "\nchangetype: modify" + ldif += "\nadd: schemaUpdateNow" + ldif += "\nschemaUpdateNow: 1" + self.ldb.modify_ldif(ldif) + # Search for created attribute + res = self.ldb.search("cn=atest-attribute1," + self.schema_dn, scope=SCOPE_BASE, attrs=["*"]) + self.assertEquals(len(res), 1) + # Search for created objectClass + res = self.ldb.search("cn=test-class," + self.schema_dn, scope=SCOPE_BASE, attrs=["*"]) + self.assertEquals(len(res), 1) + # Get rid of the garbage + self.delete_force(self.ldb, "CN=ATest-Attribute1," + self.schema_dn) + self.delete_force(self.ldb, "CN=Test-Class," + self.schema_dn) if not "://" in host: host = "ldap://%s" % host -- 1.6.0.6