diff options
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samldb.c | 90 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/util.c | 30 |
2 files changed, 36 insertions, 84 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 13b173a6bc..73776abc25 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -757,53 +757,6 @@ 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 @@ -1056,10 +1009,7 @@ static int samldb_prim_group_change(struct samldb_ctx *ac) struct ldb_dn *prev_prim_group_dn, *new_prim_group_dn; int ret; - ret = samldb_get_single_valued_attr(ac, "primaryGroupID", &el); - if (ret != LDB_SUCCESS) { - return ret; - } + el = dsdb_get_single_valued_attr(ac->msg, "primaryGroupID"); if (el == NULL) { /* we are not affected */ return LDB_SUCCESS; @@ -1204,10 +1154,7 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) struct ldb_message *tmp_msg; int ret; - ret = samldb_get_single_valued_attr(ac, "userAccountControl", &el); - if (ret != LDB_SUCCESS) { - return ret; - } + el = dsdb_get_single_valued_attr(ac->msg, "userAccountControl"); if (el == NULL) { /* we are not affected */ return LDB_SUCCESS; @@ -1280,10 +1227,7 @@ static int samldb_group_type_change(struct samldb_ctx *ac) struct ldb_message *tmp_msg; int ret; - ret = samldb_get_single_valued_attr(ac, "groupType", &el); - if (ret != LDB_SUCCESS) { - return ret; - } + el = dsdb_get_single_valued_attr(ac->msg, "groupType"); if (el == NULL) { /* we are not affected */ return LDB_SUCCESS; @@ -1369,10 +1313,7 @@ static int samldb_sam_accountname_check(struct samldb_ctx *ac) struct ldb_message *tmp_msg; int ret; - ret = samldb_get_single_valued_attr(ac, "sAMAccountName", &el); - if (ret != LDB_SUCCESS) { - return ret; - } + el = dsdb_get_single_valued_attr(ac->msg, "sAMAccountName"); if (el == NULL) { /* we are not affected */ return LDB_SUCCESS; @@ -1529,27 +1470,8 @@ static int samldb_service_principal_names_change(struct samldb_ctx *ac) unsigned int i; int ret; - /* Here it's not the same logic as with "samldb_get_single_valued_attr". - * We need to: - * - * - consider "add" and "replace" operations - the last value we take - * - ignore "delete" operations - obviously this attribute isn't - * write protected - */ - for (i = 0; i < ac->msg->num_elements; i++) { - if ((ldb_attr_cmp(ac->msg->elements[i].name, - "dNSHostName") == 0) && - (LDB_FLAG_MOD_TYPE(ac->msg->elements[i].flags) - != LDB_FLAG_MOD_DELETE)) { - el = &ac->msg->elements[i]; - } - if ((ldb_attr_cmp(ac->msg->elements[i].name, - "sAMAccountName") == 0) && - (LDB_FLAG_MOD_TYPE(ac->msg->elements[i].flags) - != LDB_FLAG_MOD_DELETE)) { - el2 = &ac->msg->elements[i]; - } - } + el = dsdb_get_single_valued_attr(ac->msg, "dNSHostName"); + el2 = dsdb_get_single_valued_attr(ac->msg, "sAMAccountName"); if ((el == NULL) && (el2 == NULL)) { /* we are not affected */ return LDB_SUCCESS; diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c index e42bc7715e..7d6fcc47ad 100644 --- a/source4/dsdb/samdb/ldb_modules/util.c +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -1108,3 +1108,33 @@ void dsdb_req_chain_debug(struct ldb_request *req, int level) DEBUG(level, ("%s\n", s)); talloc_free(s); } + +/* + * Gets back a single-valued attribute by the rules of the DSDB triggers when + * performing a modify operation. + * + * In order that the constraint checking by the "objectclass_attrs" LDB module + * does work properly, the change request should remain similar or only be + * enhanced (no other modifications as deletions, variations). + */ +struct ldb_message_element *dsdb_get_single_valued_attr(struct ldb_message *msg, + const char *attr_name) +{ + struct ldb_message_element *el = NULL; + unsigned int i; + + /* We've to walk over all modification entries and consider the last + * non-delete one which belongs to "attr_name". + * + * If "el" is NULL afterwards then that means there was no interesting + * change entry. */ + for (i = 0; i < msg->num_elements; i++) { + if ((ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) && + (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) + != LDB_FLAG_MOD_DELETE)) { + el = &msg->elements[i]; + } + } + + return el; +} |