summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Dieter Wallnöfer <mdw@samba.org>2010-10-25 13:56:14 +0200
committerMatthias Dieter Wallnöfer <mdw@samba.org>2010-10-26 18:12:00 +0000
commit4f25eec5a5d9e57f0a63591535fe3f581ce23f45 (patch)
treea298fe64410462b36dc587f9f6ffd3013a7aed0b
parentc251cb62eca1b96e0b5b22a40c5a054d5d40c1f2 (diff)
downloadsamba-4f25eec5a5d9e57f0a63591535fe3f581ce23f45.tar.gz
samba-4f25eec5a5d9e57f0a63591535fe3f581ce23f45.tar.bz2
samba-4f25eec5a5d9e57f0a63591535fe3f581ce23f45.zip
s4:objectclass_attrs.c - rework to support these special "description" constraints
Only the "description" attribute has this special restrictions.
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectclass_attrs.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
index b3f7048a39..5d3f51fbf5 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
@@ -139,17 +139,47 @@ static int attr_handler(struct oc_context *ac)
}
}
- /* Multi-valued replace operations are generally denied but
- * there do exist exceptions where attributes have the flag
- * "FLAG_ATTR_REQ_PARTIAL_SET_MEMBER" set. */
+ /* "description" on AD is very special: it's nearly single-
+ * valued (only on add operations it isn't). */
if ((ac->req->operation == LDB_MODIFY) &&
- (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_REPLACE) &&
- (msg->elements[i].num_values > 1) &&
- ((attr->systemFlags & DS_FLAG_ATTR_REQ_PARTIAL_SET_MEMBER) == 0)) {
- ldb_asprintf_errstring(ldb, "objectclass_attrs: attribute '%s' on entry '%s' is replaced multi-valued!",
- msg->elements[i].name,
- ldb_dn_get_linearized(msg->dn));
- return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+ (ldb_attr_cmp(attr->lDAPDisplayName, "description") == 0)) {
+ /* Multi-valued add or replace operations are always
+ * denied */
+ if ((LDB_FLAG_MOD_TYPE(msg->elements[i].flags)
+ != LDB_FLAG_MOD_DELETE) &&
+ (msg->elements[i].num_values > 1)) {
+ ldb_asprintf_errstring(ldb,
+ "objectclass_attrs: attribute '%s' on entry '%s' is changed using a multi-valued add or replace operation!",
+ msg->elements[i].name,
+ ldb_dn_get_linearized(msg->dn));
+ return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+ }
+
+ /* Add operations are only allowed if no value exists */
+ if (LDB_FLAG_MOD_TYPE(msg->elements[i].flags)
+ == LDB_FLAG_MOD_ADD) {
+ const char *attrs[] = { attr->lDAPDisplayName,
+ NULL };
+ struct ldb_result *res;
+ struct ldb_message_element *el;
+
+ ret = ldb_search(ldb, ac, &res, msg->dn,
+ LDB_SCOPE_BASE, attrs, NULL);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ el = ldb_msg_find_element(res->msgs[0],
+ attr->lDAPDisplayName);
+ if (el != NULL) {
+ ldb_asprintf_errstring(ldb,
+ "objectclass_attrs: attribute '%s' on entry '%s' is changed using an add operation, but there a value already exists!",
+ msg->elements[i].name,
+ ldb_dn_get_linearized(msg->dn));
+ return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+ }
+ talloc_free(res);
+ }
}
/* Substitute the attribute name to match in case */