summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Dieter Wallnöfer <mdw@samba.org>2010-11-10 15:12:02 +0100
committerMatthias Dieter Wallnöfer <mdw@samba.org>2010-11-11 10:03:40 +0100
commite96c9df817326197a0866a18ad53621405b8bee8 (patch)
tree3dfd15be22bb2e6cf89ea97e3eb12db5294a443d
parent4f86f297a22655067006f88eed5f6cb980742b81 (diff)
downloadsamba-e96c9df817326197a0866a18ad53621405b8bee8.tar.gz
samba-e96c9df817326197a0866a18ad53621405b8bee8.tar.bz2
samba-e96c9df817326197a0866a18ad53621405b8bee8.zip
s4:objectclass LDB module - allow RDNs also to come from superclasses
Detected by a testcase written by Zahari Zahariev.
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectclass.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 6702b01399..811bc96f02 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -468,6 +468,8 @@ static int objectclass_do_add(struct oc_context *ac)
const struct dsdb_class *objectclass;
struct ldb_dn *objectcategory;
int32_t systemFlags = 0;
+ unsigned int i, j;
+ bool found;
int ret;
ldb = ldb_module_get_ctx(ac->module);
@@ -561,6 +563,7 @@ static int objectclass_do_add(struct oc_context *ac)
talloc_free(mem_ctx);
return ldb_oom(ldb);
}
+
ret = ldb_msg_add_string(msg, "objectClass", value);
if (ret != LDB_SUCCESS) {
ldb_set_errstring(ldb,
@@ -587,11 +590,25 @@ static int objectclass_do_add(struct oc_context *ac)
}
rdn_name = ldb_dn_get_rdn_name(msg->dn);
- if (objectclass->rDNAttID
- && ldb_attr_cmp(rdn_name, objectclass->rDNAttID) != 0) {
+ if (rdn_name == NULL) {
+ return ldb_operr(ldb);
+ }
+ found = false;
+ for (i = 0; (!found) && (i < objectclass_element->num_values);
+ i++) {
+ const struct dsdb_class *tmp_class =
+ dsdb_class_by_lDAPDisplayName_ldb_val(ac->schema,
+ &objectclass_element->values[i]);
+
+ if (tmp_class == NULL) continue;
+
+ if (ldb_attr_cmp(rdn_name, tmp_class->rDNAttID) == 0)
+ found = true;
+ }
+ if (!found) {
ldb_asprintf_errstring(ldb,
- "RDN %s is not correct for most specific structural objectclass %s, should be %s",
- rdn_name, objectclass->lDAPDisplayName, objectclass->rDNAttID);
+ "objectclass: Invalid RDN '%s' for objectclass '%s'!",
+ rdn_name, objectclass->lDAPDisplayName);
return LDB_ERR_NAMING_VIOLATION;
}
@@ -616,7 +633,6 @@ static int objectclass_do_add(struct oc_context *ac)
= ldb_msg_find_element(ac->search_res->message, "objectClass");
bool allowed_class = false;
- unsigned int i, j;
for (i=0; allowed_class == false && oc_el && i < oc_el->num_values; i++) {
const struct dsdb_class *sclass;
@@ -1256,6 +1272,7 @@ static int objectclass_do_rename2(struct oc_context *ac)
const char *rdn_name;
bool allowed_class = false;
unsigned int i, j;
+ bool found;
oc_el_entry = ldb_msg_find_element(ac->search_res->message,
"objectClass");
@@ -1270,13 +1287,24 @@ static int objectclass_do_rename2(struct oc_context *ac)
}
rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn);
- if ((objectclass->rDNAttID != NULL) &&
- (ldb_attr_cmp(rdn_name, objectclass->rDNAttID) != 0)) {
+ if (rdn_name == NULL) {
+ return ldb_operr(ldb);
+ }
+ found = false;
+ for (i = 0; (!found) && (i < oc_el_entry->num_values); i++) {
+ const struct dsdb_class *tmp_class =
+ dsdb_class_by_lDAPDisplayName_ldb_val(ac->schema,
+ &oc_el_entry->values[i]);
+
+ if (tmp_class == NULL) continue;
+
+ if (ldb_attr_cmp(rdn_name, tmp_class->rDNAttID) == 0)
+ found = true;
+ }
+ if (!found) {
ldb_asprintf_errstring(ldb,
- "objectclass: RDN %s is not correct for most specific structural objectclass %s, should be %s",
- rdn_name,
- objectclass->lDAPDisplayName,
- objectclass->rDNAttID);
+ "objectclass: Invalid RDN '%s' for objectclass '%s'!",
+ rdn_name, objectclass->lDAPDisplayName);
return LDB_ERR_UNWILLING_TO_PERFORM;
}