summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Dieter Wallnöfer <mdw@samba.org>2010-10-30 19:37:30 +0200
committerMatthias Dieter Wallnöfer <mdw@samba.org>2010-10-30 20:23:31 +0200
commit098ea71728eb6389ff4c5314d17df533f79a07a8 (patch)
tree971f257550ad10c79423bc461b32b9530112bfc7
parent095c8b2078128838f6b830613e80cbdcf49e10cf (diff)
downloadsamba-098ea71728eb6389ff4c5314d17df533f79a07a8.tar.gz
samba-098ea71728eb6389ff4c5314d17df533f79a07a8.tar.bz2
samba-098ea71728eb6389ff4c5314d17df533f79a07a8.zip
s4:samldb LDB module - add a new function which handles special cases for single-valued attribute on SAM modifications
This saves quiet some work.
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c79
1 files changed, 51 insertions, 28 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index b5e8187c78..5687560976 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -751,6 +751,53 @@ static int samldb_schema_info_update(struct samldb_ctx *ac)
}
/*
+ * Gets back a single-valued attribute by the rules of the SAM triggers when
+ * performing a modify operation
+ */
+static int samldb_get_single_valued_attr(struct samldb_ctx *ac,
+ const char *attr_name,
+ struct ldb_message_element **attr)
+{
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+ struct ldb_message_element *el = NULL;
+ unsigned int i;
+
+ /* We've to walk over all modification entries and consider the
+ * "attr_name" ones.
+ *
+ * 1.) Add operations aren't allowed and there is returned
+ * "ATTRIBUTE_OR_VALUE_EXISTS".
+ * 2.) Replace operations are allowed but the last one is taken
+ * 3.) Delete operations are also not allowed and there is returned
+ * "UNWILLING_TO_PERFORM".
+ *
+ * If "el" is afterwards NULL then that means we've nothing to do here.
+ */
+ for (i = 0; i < ac->msg->num_elements; i++) {
+ if (ldb_attr_cmp(ac->msg->elements[i].name, attr_name) != 0) {
+ continue;
+ }
+
+ el = &ac->msg->elements[i];
+ if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_ADD) {
+ ldb_asprintf_errstring(ldb,
+ "samldb: attribute '%s' already exists!",
+ attr_name);
+ return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+ }
+ if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
+ ldb_asprintf_errstring(ldb,
+ "samldb: attribute '%s' cannot be deleted!",
+ attr_name);
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
+ }
+
+ *attr = el;
+ return LDB_SUCCESS;
+}
+
+/*
* "Objectclass" trigger (MS-SAMR 3.1.1.8.1)
*
* Has to be invoked on "add" and "modify" operations on "user", "computer" and
@@ -1002,41 +1049,17 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
uint32_t rid;
struct dom_sid *sid;
struct ldb_dn *prev_prim_group_dn, *new_prim_group_dn;
- unsigned int i;
int ret;
- /* We've to walk over all modification entries and consider the
- * "primaryGroupID" ones.
- *
- * 1.) Add operations aren't allowed and there is returned
- * "ATTRIBUTE_OR_VALUE_EXISTS".
- * 2.) Replace operations are allowed but the last one is taken
- * 3.) Delete operations are also not allowed and there is returned
- * "UNWILLING_TO_PERFORM".
- *
- * If "el" is afterwards NULL then that means we've nothing to do here.
- */
- el = NULL;
- for (i = 0; i < ac->msg->num_elements; i++) {
- if (ldb_attr_cmp(ac->msg->elements[i].name,
- "primaryGroupID") != 0) {
- continue;
- }
-
- el = &ac->msg->elements[i];
- if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_ADD) {
- return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
- }
- if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
+ ret = samldb_get_single_valued_attr(ac, "primaryGroupID", &el);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
if (el == NULL) {
+ /* we are not affected */
return LDB_SUCCESS;
}
- /* Okay, now for sure we are performing a "primaryGroupID" replace */
-
/* Fetch informations from the existing object */
ret = ldb_search(ldb, ac, &res, ac->msg->dn, LDB_SCOPE_BASE, attrs,