s4:samldb LDB module - add a new function which handles special cases for single...
authorMatthias Dieter Wallnöfer <mdw@samba.org>
Sat, 30 Oct 2010 17:37:30 +0000 (19:37 +0200)
committerMatthias Dieter Wallnöfer <mdw@samba.org>
Sat, 30 Oct 2010 18:23:31 +0000 (20:23 +0200)
This saves quiet some work.

source4/dsdb/samdb/ldb_modules/samldb.c

index b5e8187c7886d5e7a4dd3399113597a6faa14a78..56875609769c505d45cd9936c4ecc972fefab5e5 100644 (file)
@@ -750,6 +750,53 @@ static int samldb_schema_info_update(struct samldb_ctx *ac)
        return LDB_SUCCESS;
 }
 
+/*
+ * 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)
  *
@@ -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,