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 +++++++++++++++++++++++++++++++++ 1 file changed, 87 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 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"); -- cgit