summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c65
1 files changed, 55 insertions, 10 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 6df169f452..44c8fee29f 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -1002,8 +1002,41 @@ 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;
+ }
+ }
+ if (el == NULL) {
+ 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,
@@ -1033,9 +1066,20 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
return ldb_operr(ldb);
}
- /* Finds out the DN of the new primary group */
+ /* Finds out the DN of the new primary group
+ * Notice: in order to parse the primary group ID correctly we create
+ * a temporary message here. */
- rid = ldb_msg_find_attr_as_uint(ac->msg, "primaryGroupID", (uint32_t) -1);
+ msg = ldb_msg_new(ac->msg);
+ if (msg == NULL) {
+ return ldb_module_oom(ac->module);
+ }
+ ret = ldb_msg_add(msg, el, 0);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ rid = ldb_msg_find_attr_as_uint(msg, "primaryGroupID", (uint32_t) -1);
+ talloc_free(msg);
if (rid == (uint32_t) -1) {
/* we aren't affected of any primary group change */
return LDB_SUCCESS;
@@ -1066,6 +1110,9 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
/* Remove the "member" attribute on the new primary group */
msg = talloc_zero(ac, struct ldb_message);
+ if (msg == NULL) {
+ return ldb_module_oom(ac->module);
+ }
msg->dn = new_prim_group_dn;
ret = samdb_msg_add_delval(ldb, msg, msg, "member",
@@ -1081,6 +1128,9 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
/* Add a "member" attribute for the previous primary group */
msg = talloc_zero(ac, struct ldb_message);
+ if (msg == NULL) {
+ return ldb_module_oom(ac->module);
+ }
msg->dn = prev_prim_group_dn;
ret = samdb_msg_add_addval(ldb, msg, msg, "member",
@@ -1095,6 +1145,8 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
}
}
+ talloc_free(res);
+
return LDB_SUCCESS;
}
@@ -1424,19 +1476,12 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
}
el = ldb_msg_find_element(ac->msg, "primaryGroupID");
- if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE)
- && el->num_values == 1) {
- modified = true;
-
+ if (el != NULL) {
ret = samldb_prim_group_change(ac);
if (ret != LDB_SUCCESS) {
return ret;
}
}
- el = ldb_msg_find_element(ac->msg, "primaryGroupID");
- if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE)) {
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
el = ldb_msg_find_element(ac->msg, "userAccountControl");
if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE)