summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb/ldb_modules/objectclass.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2007-11-13 22:54:52 +0100
committerStefan Metzmacher <metze@samba.org>2007-12-21 05:45:11 +0100
commit5d4f507a65144d8fe30b3fcd0b9cbcdc088146c6 (patch)
tree6a134f6519fd958bc3dde6cf4021ca1147521202 /source4/dsdb/samdb/ldb_modules/objectclass.c
parent7f18e15e3f48d92a4f8f2b929a6337761b26fc67 (diff)
downloadsamba-5d4f507a65144d8fe30b3fcd0b9cbcdc088146c6.tar.gz
samba-5d4f507a65144d8fe30b3fcd0b9cbcdc088146c6.tar.bz2
samba-5d4f507a65144d8fe30b3fcd0b9cbcdc088146c6.zip
r25942: Make various ldb modules handle an LDB backend that enforces validity
of Base DNs in searches (returning an error of LDB_ERR_NO_SUCH_ENTRY). We need to handle this if ldb_tdb is to behave correctly compared with LDAP, as well as if we are using an LDAP backend. In doing so, I realised that subtree_rename and subtree_delete (prevention) need rather different wait loops, so it seemed easier to split it out into it's own module. I've fixed the licence on both of these modules to be GPLv3. Andrew Bartlett (This used to be commit d3894c90f31fb45e038ab478cd9d7d34962d069b)
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules/objectclass.c')
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectclass.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 50ea2ec4e2..5626d9a891 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -68,6 +68,8 @@ struct class_list {
const struct dsdb_class *objectclass;
};
+static int objectclass_do_add(struct ldb_handle *h);
+
static struct ldb_handle *oc_init_handle(struct ldb_request *req, struct ldb_module *module)
{
struct oc_context *ac;
@@ -388,11 +390,17 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
/* return or own handle to deal with this call */
req->handle = h;
- parent_dn = ldb_dn_get_parent(ac, ac->orig_req->op.mod.message->dn);
+ /* If there isn't a parent, just go on to the add processing */
+ if (ldb_dn_get_comp_num(ac->orig_req->op.add.message->dn) == 1) {
+ return objectclass_do_add(h);
+ }
+
+ parent_dn = ldb_dn_get_parent(ac, ac->orig_req->op.add.message->dn);
if (parent_dn == NULL) {
ldb_oom(module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
+
ret = ldb_build_search_req(&ac->search_req, module->ldb,
ac, parent_dn, LDB_SCOPE_BASE,
"(objectClass=*)",
@@ -443,9 +451,7 @@ static int objectclass_do_add(struct ldb_handle *h)
/* Check we have a valid parent */
if (ac->search_res == NULL) {
- if (ldb_dn_get_comp_num(ac->orig_req->op.add.message->dn) <= 1) {
- /* Allow cn=rootdse and cn=templates for now... */
- } else if (ldb_dn_compare(ldb_get_root_basedn(ac->module->ldb), ac->orig_req->op.add.message->dn) == 0) {
+ if (ldb_dn_compare(ldb_get_root_basedn(ac->module->ldb), ac->orig_req->op.add.message->dn) == 0) {
/* Allow the tree to be started */
} else {
ldb_asprintf_errstring(ac->module->ldb, "objectclass: Cannot add %s, parent does not exist!",
@@ -461,6 +467,8 @@ static int objectclass_do_add(struct ldb_handle *h)
&msg->dn);
if (ret != LDB_SUCCESS) {
+ ldb_asprintf_errstring(ac->module->ldb, "Could not munge DN %s into normal form",
+ ldb_dn_get_linearized(ac->orig_req->op.add.message->dn));
return ret;
}
@@ -601,7 +609,9 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req
switch (objectclass_element->flags & LDB_FLAG_MOD_MASK) {
case LDB_FLAG_MOD_DELETE:
- return LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED;
+ if (objectclass_element->num_values == 0) {
+ return LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED;
+ }
break;
case LDB_FLAG_MOD_REPLACE:
{
@@ -1026,11 +1036,12 @@ static int oc_wait(struct ldb_handle *handle) {
case OC_SEARCH_ADD_PARENT:
ret = ldb_wait(ac->search_req->handle, LDB_WAIT_NONE);
- if (ret != LDB_SUCCESS) {
+ if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
handle->status = ret;
goto done;
}
- if (ac->search_req->handle->status != LDB_SUCCESS) {
+ if (ac->search_req->handle->status != LDB_SUCCESS
+ && ac->search_req->handle->status != LDB_ERR_NO_SUCH_OBJECT) {
handle->status = ac->search_req->handle->status;
goto done;
}
@@ -1063,11 +1074,11 @@ static int oc_wait(struct ldb_handle *handle) {
case OC_SEARCH_RENAME_PARENT:
ret = ldb_wait(ac->search_req->handle, LDB_WAIT_NONE);
- if (ret != LDB_SUCCESS) {
+ if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
handle->status = ret;
goto done;
}
- if (ac->search_req->handle->status != LDB_SUCCESS) {
+ if (ac->search_req->handle->status != LDB_SUCCESS && ac->search_req->handle->status != LDB_ERR_NO_SUCH_OBJECT) {
handle->status = ac->search_req->handle->status;
goto done;
}