From 5585591b2e6959bebb005966ad72eb7af4bf1760 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Fri, 12 Nov 2010 18:57:57 +0100 Subject: s4:samldb/objectclass_attrs LDB modules - move "description" logic from "objectclass_attrs" into "samldb" This according to an answer from dochelp is SAM specific behaviour. --- source4/dsdb/samdb/ldb_modules/samldb.c | 81 +++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'source4/dsdb/samdb/ldb_modules/samldb.c') diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 0cd8bc9bcc..4b8a303753 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -1496,6 +1496,79 @@ static int samldb_member_check(struct samldb_ctx *ac) } } + talloc_free(res); + + return LDB_SUCCESS; +} + +/* SAM objects have special rules regarding the "description" attribute on + * modify operations. */ +static int samldb_description_check(struct samldb_ctx *ac) +{ + struct ldb_context *ldb = ldb_module_get_ctx(ac->module); + const char * const attrs[] = { "objectClass", "description", NULL }; + struct ldb_message_element *el; + struct ldb_result *res; + unsigned int i; + int ret; + + /* Fetch informations from the existing object */ + + ret = ldb_search(ldb, ac, &res, ac->msg->dn, LDB_SCOPE_BASE, attrs, + NULL); + if (ret != LDB_SUCCESS) { + return ret; + } + if (res->count != 1) { + return ldb_operr(ldb); + } + + /* if it's not a SAM object then please skip the constraints */ + if ((samdb_find_attribute(ldb, res->msgs[0], "objectClass", + "group") == NULL) && + (samdb_find_attribute(ldb, res->msgs[0], "objectClass", + "samDomain") == NULL) && + (samdb_find_attribute(ldb, res->msgs[0], "objectClass", + "samServer") == NULL) && + (samdb_find_attribute(ldb, res->msgs[0], "objectClass", + "user") == NULL)) { + talloc_free(res); + return LDB_SUCCESS; + } + + /* We've to walk over all modification entries and consider the + * "description" ones. */ + for (i = 0; i < ac->msg->num_elements; i++) { + if (ldb_attr_cmp(ac->msg->elements[i].name, + "description") != 0) { + continue; + } + + el = &ac->msg->elements[i]; + + /* Multi-valued add or replace operations are always denied */ + if ((LDB_FLAG_MOD_TYPE(el->flags) != LDB_FLAG_MOD_DELETE) && + (el->num_values > 1)) { + ldb_asprintf_errstring(ldb, + "samldb: Description on SAM entry '%s' is changed using a multi-valued add or replace operation!", + ldb_dn_get_linearized(ac->msg->dn)); + return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + } + + /* Add operations are only allowed if no value exists */ + if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_ADD) { + if (ldb_msg_find_element(res->msgs[0], "description") + != NULL) { + ldb_asprintf_errstring(ldb, + "samldb: Description on SAM entry '%s' is changed using an add operation while a value already exists!", + ldb_dn_get_linearized(ac->msg->dn)); + return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + } + } + } + + talloc_free(res); + return LDB_SUCCESS; } @@ -1894,6 +1967,14 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) } } + el = ldb_msg_find_element(ac->msg, "description"); + if (el != NULL) { + ret = samldb_description_check(ac); + if (ret != LDB_SUCCESS) { + return ret; + } + } + el = ldb_msg_find_element(ac->msg, "dNSHostName"); el2 = ldb_msg_find_element(ac->msg, "sAMAccountName"); if ((el != NULL) || (el2 != NULL)) { -- cgit