From fffdce62fc1c9959f17c2dbb0a3939e95095fe54 Mon Sep 17 00:00:00 2001 From: Kamen Mazdrashki Date: Wed, 24 Feb 2010 01:45:26 +0200 Subject: s4/schema: Move msDS-IntId implementation to samldb.c module msDS-IntId attribute should be replicated, so it must be implemented in a module that is before repl_meta_data module (thanks abartlet for pointing this out). Signed-off-by: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/samldb.c | 87 ++++++++++++++++ source4/dsdb/samdb/ldb_modules/schema_data.c | 149 --------------------------- 2 files changed, 87 insertions(+), 149 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 9d79776e66..6420e05ba8 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -689,6 +689,81 @@ static int samldb_find_for_defaultObjectCategory(struct samldb_ctx *ac) return ldb_next_request(ac->module, req); } +/** + * msDS-IntId attributeSchema attribute handling + * during LDB_ADD request processing + */ +static int samldb_add_handle_msDS_IntId(struct samldb_ctx *ac) +{ + int ret; + bool id_exists; + uint32_t msds_intid; + uint32_t system_flags; + struct ldb_context *ldb; + struct ldb_result *ldb_res; + struct ldb_dn *schema_dn; + + ldb = ldb_module_get_ctx(ac->module); + schema_dn = ldb_get_schema_basedn(ldb); + + /* replicated update should always go through */ + if (ldb_request_get_control(ac->req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) { + return LDB_SUCCESS; + } + + /* msDS-IntId is handled by system and should never be + * passed by clients */ + if (ldb_msg_find_element(ac->msg, "msDS-IntId")) { + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + /* do not generate msDS-IntId if Relax control is passed */ + if (ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) { + return LDB_SUCCESS; + } + + /* check Functional Level */ + if (dsdb_functional_level(ldb) < DS_DOMAIN_FUNCTION_2003) { + return LDB_SUCCESS; + } + + /* check systemFlags for SCHEMA_BASE_OBJECT flag */ + system_flags = ldb_msg_find_attr_as_uint(ac->msg, "systemFlags", 0); + if (system_flags & SYSTEM_FLAG_SCHEMA_BASE_OBJECT) { + return LDB_SUCCESS; + } + + /* Generate new value for msDs-IntId + * Value should be in 0x80000000..0xBFFFFFFF range */ + msds_intid = generate_random() % 0X3FFFFFFF; + msds_intid += 0x80000000; + + /* probe id values until unique one is found */ + do { + msds_intid++; + if (msds_intid > 0xBFFFFFFF) { + msds_intid = 0x80000001; + } + + ret = dsdb_module_search(ac->module, ac, + &ldb_res, + schema_dn, LDB_SCOPE_ONELEVEL, NULL, 0, + "(msDS-IntId=%d)", msds_intid); + if (ret != LDB_SUCCESS) { + ldb_debug_set(ldb, LDB_DEBUG_ERROR, + __location__": Searching for msDS-IntId=%d failed - %s\n", + msds_intid, + ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + id_exists = (ldb_res->count > 0); + + talloc_free(ldb_res); + } while(id_exists); + + return ldb_msg_add_fmt(ac->msg, "msDS-IntId", "%d", msds_intid); +} + /* * samldb_add_entry (async) @@ -870,6 +945,10 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type) } } + /* handle msDS-IntID attribute */ + ret = samldb_add_handle_msDS_IntId(ac); + if (ret != LDB_SUCCESS) return ret; + ret = samldb_add_step(ac, samldb_add_entry); if (ret != LDB_SUCCESS) return ret; @@ -1763,6 +1842,14 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_UNWILLING_TO_PERFORM; } + /* msDS-IntId is not allowed to be modified + * except when modification comes from replication */ + if (ldb_msg_find_element(req->op.mod.message, "msDS-IntId")) { + if (!ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) { + return LDB_ERR_CONSTRAINT_VIOLATION; + } + } + /* TODO: do not modify original request, create a new one */ el = ldb_msg_find_element(req->op.mod.message, "groupType"); diff --git a/source4/dsdb/samdb/ldb_modules/schema_data.c b/source4/dsdb/samdb/ldb_modules/schema_data.c index 8125a46cbb..d15c675675 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_data.c +++ b/source4/dsdb/samdb/ldb_modules/schema_data.c @@ -92,37 +92,6 @@ struct schema_data_search_data { const struct dsdb_schema *schema; }; -/* context to be used during async operations */ -struct schema_data_context { - struct ldb_module *module; - struct ldb_request *req; - - const struct dsdb_schema *schema; -}; - -/* Create new context using - * ldb_request as memory context */ -static int _schema_data_context_new(struct ldb_module *module, - struct ldb_request *req, - struct schema_data_context **pac) -{ - struct schema_data_context *ac; - struct ldb_context *ldb; - - ldb = ldb_module_get_ctx(module); - - *pac = ac = talloc_zero(req, struct schema_data_context); - if (ac == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - ac->module = module; - ac->req = req; - ac->schema = dsdb_get_schema(ldb); - - return LDB_SUCCESS; -} - static int schema_data_init(struct ldb_module *module) { struct ldb_context *ldb; @@ -163,57 +132,6 @@ static int schema_data_init(struct ldb_module *module) return LDB_SUCCESS; } - -/* Generate new value for msDs-IntId - * Value should be in 0x80000000..0xBFFFFFFF range - * Generated value is added ldb_msg */ -static int _schema_data_gen_msds_intid(struct schema_data_context *ac, - struct ldb_message *ldb_msg) -{ - uint32_t id; - - /* generate random num in 0x80000000..0xBFFFFFFF */ - id = generate_random() % 0X3FFFFFFF; - id += 0x80000000; - - /* make sure id is unique and adjust if not */ - while (dsdb_attribute_by_attributeID_id(ac->schema, id)) { - id++; - if (id > 0xBFFFFFFF) { - id = 0x80000001; - } - } - - /* add generated msDS-IntId value to ldb_msg */ - return ldb_msg_add_fmt(ldb_msg, "msDS-IntId", "%d", id); -} - -static int _schema_data_add_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct schema_data_context *ac; - - ac = talloc_get_type(req->context, struct schema_data_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - if (ares->type != LDB_REPLY_DONE) { - talloc_free(ares); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); -} - static int schema_data_add(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; @@ -251,11 +169,6 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req) governsID = ldb_msg_find_ldb_val(req->op.add.message, "governsID"); if (attributeID) { - /* Sanity check for not allowed attributes */ - if (ldb_msg_find_ldb_val(req->op.add.message, "msDS-IntId")) { - return LDB_ERR_UNWILLING_TO_PERFORM; - } - oid_attr = "attributeID"; oid = talloc_strndup(req, (const char *)attributeID->data, attributeID->length); } else if (governsID) { @@ -290,67 +203,6 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req) } } - /* bypass further processing if CONTROL_RELAX is set */ - if (ldb_request_get_control(req, LDB_CONTROL_RELAX_OID)) { - return ldb_next_request(module, req); - } - - /* generate and add msDS-IntId attr value */ - if (attributeID - && (dsdb_functional_level(ldb) >= DS_DOMAIN_FUNCTION_2003) - && !(ldb_msg_find_attr_as_uint(req->op.add.message, "systemFlags", 0) & SYSTEM_FLAG_SCHEMA_BASE_OBJECT)) { - struct ldb_message *msg; - struct schema_data_context *ac; - struct ldb_request *add_req; - - if (_schema_data_context_new(module, req, &ac) != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* we have to copy the message as the caller might have it as a const */ - msg = ldb_msg_copy_shallow(ac, req->op.add.message); - if (msg == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* generate unique value for msDS-IntId attr value */ - if (_schema_data_gen_msds_intid(ac, msg) != LDB_SUCCESS) { - ldb_debug_set(ldb, LDB_DEBUG_ERROR, - "_schema_data_gen_msds_intid() failed to generate msDS-IntId value\n"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_build_add_req(&add_req, ldb, ac, - msg, - req->controls, - ac, _schema_data_add_callback, - req); - - return ldb_next_request(module, add_req); - } - - return ldb_next_request(module, req); -} - -static int schema_data_modify(struct ldb_module *module, struct ldb_request *req) -{ - /* special objects should always go through */ - if (ldb_dn_is_special(req->op.mod.message->dn)) { - return ldb_next_request(module, req); - } - - /* replicated update should always go through */ - if (ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) { - return ldb_next_request(module, req); - } - - /* msDS-IntId is not allowed to be modified */ - if (ldb_msg_find_ldb_val(req->op.mod.message, "msDS-IntId")) { - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - /* go on with the call chain */ return ldb_next_request(module, req); } @@ -609,6 +461,5 @@ _PUBLIC_ const struct ldb_module_ops ldb_schema_data_module_ops = { .name = "schema_data", .init_context = schema_data_init, .add = schema_data_add, - .modify = schema_data_modify, .search = schema_data_search }; -- cgit