diff options
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules/samldb.c')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samldb.c | 684 |
1 files changed, 95 insertions, 589 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 17a99c74c7..ccf76aaef2 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -59,12 +59,6 @@ struct samldb_ctx { /* the resulting message */ struct ldb_message *msg; - /* used to find parent domain */ - struct ldb_dn *check_dn; - struct ldb_dn *domain_dn; - struct dom_sid *domain_sid; - uint32_t next_rid; - /* holds the entry SID */ struct dom_sid *sid; @@ -175,139 +169,6 @@ static int samldb_next_step(struct samldb_ctx *ac) } } -/* - * samldb_get_parent_domain (async) - */ - -static int samldb_get_parent_domain(struct samldb_ctx *ac); - -static int samldb_get_parent_domain_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct samldb_ctx *ac; - const char *nextRid; - int ret; - - ac = talloc_get_type(req->context, struct samldb_ctx); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - /* save entry */ - if ((ac->domain_dn != NULL) || (ac->domain_sid != NULL)) { - /* one too many! */ - ldb_set_errstring(ldb, - "Invalid number of results while searching " - "for domain object!"); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - nextRid = ldb_msg_find_attr_as_string(ares->message, - "nextRid", NULL); - if (nextRid == NULL) { - ldb_asprintf_errstring(ldb, - "While looking for domain above %s attribute nextRid not found in %s!", - ldb_dn_get_linearized( - ac->req->op.add.message->dn), - ldb_dn_get_linearized(ares->message->dn)); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - ac->next_rid = strtol(nextRid, NULL, 0); - - ac->domain_sid = samdb_result_dom_sid(ac, ares->message, - "objectSid"); - if (ac->domain_sid == NULL) { - ldb_set_errstring(ldb, - "Unable to get the parent domain SID!"); - ret = LDB_ERR_CONSTRAINT_VIOLATION; - break; - } - ac->domain_dn = ldb_dn_copy(ac, ares->message->dn); - - talloc_free(ares); - ret = LDB_SUCCESS; - break; - - case LDB_REPLY_REFERRAL: - /* ignore */ - talloc_free(ares); - ret = LDB_SUCCESS; - break; - - case LDB_REPLY_DONE: - talloc_free(ares); - if ((ac->domain_dn == NULL) || (ac->domain_sid == NULL)) { - /* not found -> retry */ - ret = samldb_get_parent_domain(ac); - } else { - /* found, go on */ - ret = samldb_next_step(ac); - } - break; - } - -done: - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - - return LDB_SUCCESS; -} - -/* Find a domain object in the parents of a particular DN. */ -static int samldb_get_parent_domain(struct samldb_ctx *ac) -{ - struct ldb_context *ldb; - static const char * const attrs[] = { "objectSid", "nextRid", NULL }; - struct ldb_request *req; - struct ldb_dn *dn; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - if (ac->check_dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - dn = ldb_dn_get_parent(ac, ac->check_dn); - if (dn == NULL) { - ldb_set_errstring(ldb, - "Unable to find parent domain object!"); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - ac->check_dn = dn; - - ret = ldb_build_search_req(&req, ldb, ac, - dn, LDB_SCOPE_BASE, - "(|(objectClass=domain)" - "(objectClass=builtinDomain))", - attrs, - NULL, - ac, samldb_get_parent_domain_callback, - ac->req); - - if (ret != LDB_SUCCESS) { - return ret; - } - - return ldb_next_request(ac->module, req); -} - - static int samldb_generate_samAccountName(struct ldb_message *msg) { char *name; @@ -395,7 +256,7 @@ static int samldb_check_samAccountName(struct samldb_ctx *ac) } ret = ldb_build_search_req(&req, ldb, ac, - ac->domain_dn, LDB_SCOPE_SUBTREE, + samdb_base_dn(ldb), LDB_SCOPE_SUBTREE, filter, NULL, NULL, ac, samldb_check_samAccountName_callback, @@ -464,134 +325,45 @@ static int samldb_check_samAccountType(struct samldb_ctx *ac) return samldb_next_step(ac); } - -/* - * samldb_get_sid_domain (async) - */ - -static int samldb_get_sid_domain_callback(struct ldb_request *req, - struct ldb_reply *ares) +static bool samldb_msg_add_sid(struct ldb_message *msg, + const char *name, + const struct dom_sid *sid) { - struct ldb_context *ldb; - struct samldb_ctx *ac; - const char *nextRid; - int ret; - - ac = talloc_get_type(req->context, struct samldb_ctx); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - /* save entry */ - if (ac->next_rid != 0) { - /* one too many! */ - ldb_set_errstring(ldb, - "Invalid number of results while searching " - "for domain object!"); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - nextRid = ldb_msg_find_attr_as_string(ares->message, - "nextRid", NULL); - if (nextRid == NULL) { - ldb_asprintf_errstring(ldb, - "Attribute nextRid not found in %s!", - ldb_dn_get_linearized(ares->message->dn)); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - ac->next_rid = strtol(nextRid, NULL, 0); - - ac->domain_dn = ldb_dn_copy(ac, ares->message->dn); - - talloc_free(ares); - ret = LDB_SUCCESS; - break; - - case LDB_REPLY_REFERRAL: - /* ignore */ - talloc_free(ares); - ret = LDB_SUCCESS; - break; - - case LDB_REPLY_DONE: - talloc_free(ares); - if (ac->next_rid == 0) { - ldb_asprintf_errstring(ldb, - "Unable to get nextRid from domain entry!"); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - /* found, go on */ - ret = samldb_next_step(ac); - break; - } + struct ldb_val v; + enum ndr_err_code ndr_err; -done: - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); + ndr_err = ndr_push_struct_blob(&v, msg, NULL, sid, + (ndr_push_flags_fn_t)ndr_push_dom_sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return false; } - - return LDB_SUCCESS; + return (ldb_msg_add_value(msg, name, &v, NULL) == 0); } -/* Find a domain object in the parents of a particular DN. */ -static int samldb_get_sid_domain(struct samldb_ctx *ac) + +/* allocate a SID using our RID Set */ +static int samldb_allocate_sid(struct samldb_ctx *ac) { - struct ldb_context *ldb; - static const char * const attrs[] = { "nextRid", NULL }; - struct ldb_request *req; - char *filter; + uint32_t rid; int ret; + struct ldb_context *ldb = ldb_module_get_ctx(ac->module); - ldb = ldb_module_get_ctx(ac->module); - - if (ac->sid == NULL) { - return LDB_ERR_OPERATIONS_ERROR; + ret = ridalloc_allocate_rid(ac->module, &rid); + if (ret != LDB_SUCCESS) { + return ret; } - ac->domain_sid = dom_sid_dup(ac, ac->sid); - if (!ac->domain_sid) { + ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid); + if (ac->sid == NULL) { + ldb_module_oom(ac->module); return LDB_ERR_OPERATIONS_ERROR; } - /* get the domain component part of the provided SID */ - ac->domain_sid->num_auths--; - filter = talloc_asprintf(ac, - "(&(objectSid=%s)" - "(|(objectClass=domain)" - "(objectClass=builtinDomain)))", - ldap_encode_ndr_dom_sid(ac, ac->domain_sid)); - if (filter == NULL) { + if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) { return LDB_ERR_OPERATIONS_ERROR; } - ret = ldb_build_search_req(&req, ldb, ac, - ldb_get_default_basedn(ldb), - LDB_SCOPE_SUBTREE, - filter, attrs, - NULL, - ac, samldb_get_sid_domain_callback, - ac->req); - - if (ret != LDB_SUCCESS) { - return ret; - } - - ac->next_rid = 0; - return ldb_next_request(ac->module, req); + return samldb_next_step(ac); } /* @@ -722,161 +494,6 @@ static int samldb_check_primaryGroupID_2(struct samldb_ctx *ac) } -static bool samldb_msg_add_sid(struct ldb_message *msg, - const char *name, - const struct dom_sid *sid) -{ - struct ldb_val v; - enum ndr_err_code ndr_err; - - ndr_err = ndr_push_struct_blob(&v, msg, NULL, sid, - (ndr_push_flags_fn_t)ndr_push_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return false; - } - return (ldb_msg_add_value(msg, name, &v, NULL) == 0); -} - -static int samldb_new_sid(struct samldb_ctx *ac) -{ - - if (ac->domain_sid == NULL || ac->next_rid == 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->sid = dom_sid_add_rid(ac, ac->domain_sid, ac->next_rid + 1); - if (ac->sid == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return samldb_next_step(ac); -} - -/* - * samldb_notice_sid_callback (async) - */ - -static int samldb_notice_sid_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct samldb_ctx *ac; - int ret; - - ac = talloc_get_type(req->context, struct samldb_ctx); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - if (ares->type != LDB_REPLY_DONE) { - ldb_set_errstring(ldb, - "Invalid reply type!"); - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - ret = samldb_next_step(ac); - -done: - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - - return LDB_SUCCESS; -} - -/* If we are adding new users/groups, we need to update the nextRid - * attribute to be 'above' the new/incoming RID. Attempt to do it - * atomically. */ -static int samldb_notice_sid(struct samldb_ctx *ac) -{ - struct ldb_context *ldb; - uint32_t old_id, new_id; - struct ldb_request *req; - struct ldb_message *msg; - struct ldb_message_element *els; - struct ldb_val *vals; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - old_id = ac->next_rid; - new_id = ac->sid->sub_auths[ac->sid->num_auths - 1]; - - if (old_id >= new_id) { - /* no need to update the domain nextRid attribute */ - return samldb_next_step(ac); - } - - /* we do a delete and add as a single operation. That prevents - a race, in case we are not actually on a transaction db */ - msg = ldb_msg_new(ac); - if (msg == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - els = talloc_array(msg, struct ldb_message_element, 2); - if (els == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - vals = talloc_array(msg, struct ldb_val, 2); - if (vals == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - msg->dn = ac->domain_dn; - msg->num_elements = 2; - msg->elements = els; - - els[0].num_values = 1; - els[0].values = &vals[0]; - els[0].flags = LDB_FLAG_MOD_DELETE; - els[0].name = talloc_strdup(msg, "nextRid"); - if (!els[0].name) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - els[1].num_values = 1; - els[1].values = &vals[1]; - els[1].flags = LDB_FLAG_MOD_ADD; - els[1].name = els[0].name; - - vals[0].data = (uint8_t *)talloc_asprintf(vals, "%u", old_id); - if (!vals[0].data) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - vals[0].length = strlen((char *)vals[0].data); - - vals[1].data = (uint8_t *)talloc_asprintf(vals, "%u", new_id); - if (!vals[1].data) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - vals[1].length = strlen((char *)vals[1].data); - - ret = ldb_build_mod_req(&req, ldb, ac, - msg, NULL, - ac, samldb_notice_sid_callback, - ac->req); - if (ret != LDB_SUCCESS) { - return ret; - } - - return ldb_next_request(ac->module, req); -} - /* * samldb_set_defaultObjectCategory_callback (async) */ @@ -1142,11 +759,6 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type) ldb = ldb_module_get_ctx(ac->module); - /* search for a parent domain objet */ - ac->check_dn = ac->req->op.add.message->dn; - ret = samldb_add_step(ac, samldb_get_parent_domain); - if (ret != LDB_SUCCESS) return ret; - /* Add informations for the different account types */ ac->type = type; if (strcmp(ac->type, "user") == 0) { @@ -1174,9 +786,11 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type) ret = samdb_find_or_add_attribute(ldb, ac->msg, "pwdLastSet", "0"); if (ret != LDB_SUCCESS) return ret; - ret = samdb_find_or_add_attribute(ldb, ac->msg, - "primaryGroupID", "513"); - if (ret != LDB_SUCCESS) return ret; + if (!ldb_msg_find_element(ac->msg, "primaryGroupID")) { + ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, + "primaryGroupID", DOMAIN_RID_USERS); + if (ret != LDB_SUCCESS) return ret; + } ret = samdb_find_or_add_attribute(ldb, ac->msg, "accountExpires", "9223372036854775807"); if (ret != LDB_SUCCESS) return ret; @@ -1287,20 +901,21 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type) lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), struct loadparm_context); - sid_generator = lp_sid_generator(lp_ctx); - if (sid_generator == SID_GENERATOR_INTERNAL) { - /* check if we have a valid SID */ - ac->sid = samdb_result_dom_sid(ac, ac->msg, "objectSid"); - if ( ! ac->sid) { - ret = samldb_add_step(ac, samldb_new_sid); - if (ret != LDB_SUCCESS) return ret; - } else { - ret = samldb_add_step(ac, samldb_get_sid_domain); + /* don't allow objectSID to be specified without the RELAX control */ + ac->sid = samdb_result_dom_sid(ac, ac->msg, "objectSid"); + if (ac->sid && !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID) && + !dsdb_module_am_system(ac->module)) { + ldb_asprintf_errstring(ldb, "No SID may be specified in user/group creation for %s", + ldb_dn_get_linearized(ac->msg->dn)); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + if ( ! ac->sid) { + sid_generator = lp_sid_generator(lp_ctx); + if (sid_generator == SID_GENERATOR_INTERNAL) { + ret = samldb_add_step(ac, samldb_allocate_sid); if (ret != LDB_SUCCESS) return ret; } - - ret = samldb_add_step(ac, samldb_notice_sid); - if (ret != LDB_SUCCESS) return ret; } /* finally proceed with adding the entry */ @@ -1310,144 +925,6 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type) return samldb_first_step(ac); } -/* - * samldb_foreign_notice_sid (async) - */ - -static int samldb_foreign_notice_sid_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct samldb_ctx *ac; - const char *nextRid; - const char *name; - int ret; - - ac = talloc_get_type(req->context, struct samldb_ctx); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - /* save entry */ - if (ac->next_rid != 0) { - /* one too many! */ - ldb_set_errstring(ldb, - "Invalid number of results while searching " - "for domain object!"); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - nextRid = ldb_msg_find_attr_as_string(ares->message, - "nextRid", NULL); - if (nextRid == NULL) { - ldb_asprintf_errstring(ldb, - "While looking for foreign SID %s attribute nextRid not found in %s", - dom_sid_string(ares, ac->sid), - ldb_dn_get_linearized(ares->message->dn)); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - ac->next_rid = strtol(nextRid, NULL, 0); - - ac->domain_dn = ldb_dn_copy(ac, ares->message->dn); - - name = samdb_result_string(ares->message, "name", NULL); - ldb_debug(ldb, LDB_DEBUG_TRACE, - "NOTE (strange but valid): Adding foreign SID " - "record with SID %s, but this domain (%s) is " - "not foreign in the database\n", - dom_sid_string(ares, ac->sid), name); - - talloc_free(ares); - ret = LDB_SUCCESS; - break; - - case LDB_REPLY_REFERRAL: - /* ignore */ - talloc_free(ares); - ret = LDB_SUCCESS; - break; - - case LDB_REPLY_DONE: - talloc_free(ares); - - /* if this is a fake foreign SID, notice the SID */ - if (ac->domain_dn) { - ret = samldb_notice_sid(ac); - break; - } - - /* found, go on */ - ret = samldb_next_step(ac); - break; - } - -done: - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - - return LDB_SUCCESS; -} - -/* Find a domain object in the parents of a particular DN. */ -static int samldb_foreign_notice_sid(struct samldb_ctx *ac) -{ - struct ldb_context *ldb; - static const char * const attrs[3] = { "nextRid", "name", NULL }; - struct ldb_request *req; - NTSTATUS status; - char *filter; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - if (ac->sid == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - status = dom_sid_split_rid(ac, ac->sid, &ac->domain_sid, NULL); - if (!NT_STATUS_IS_OK(status)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - - filter = talloc_asprintf(ac, - "(&(objectSid=%s)" - "(|(objectClass=domain)" - "(objectClass=builtinDomain)))", - ldap_encode_ndr_dom_sid(ac, ac->domain_sid)); - if (filter == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_build_search_req(&req, ldb, ac, - ldb_get_default_basedn(ldb), - LDB_SCOPE_SUBTREE, - filter, attrs, - NULL, - ac, samldb_foreign_notice_sid_callback, - ac->req); - - if (ret != LDB_SUCCESS) { - return ret; - } - - return ldb_next_request(ac->module, req); -} - - static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac) { struct ldb_context *ldb; @@ -1455,8 +932,6 @@ static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac) ldb = ldb_module_get_ctx(ac->module); - ac->next_rid = 0; - ac->sid = samdb_result_dom_sid(ac->msg, ac->msg, "objectSid"); if (ac->sid == NULL) { ac->sid = dom_sid_parse_talloc(ac->msg, @@ -1474,10 +949,6 @@ static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac) } } - /* check if we need to notice this SID */ - ret = samldb_add_step(ac, samldb_foreign_notice_sid); - if (ret != LDB_SUCCESS) return ret; - /* finally proceed with adding the entry */ ret = samldb_add_step(ac, samldb_add_entry); if (ret != LDB_SUCCESS) return ret; @@ -2313,6 +1784,20 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) el2->flags = LDB_FLAG_MOD_REPLACE; } + el = ldb_msg_find_element(req->op.mod.message, "primaryGroupID"); + if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) { + struct samldb_ctx *ac; + + ac = samldb_ctx_init(module, req); + if (ac == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req, + req->op.mod.message); + + return samldb_prim_group_change(ac); + } + el = ldb_msg_find_element(req->op.mod.message, "userAccountControl"); if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) { uint32_t user_account_control; @@ -2340,21 +1825,18 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) } el2 = ldb_msg_find_element(msg, "isCriticalSystemObject"); el2->flags = LDB_FLAG_MOD_REPLACE; - } - } - - el = ldb_msg_find_element(req->op.mod.message, "primaryGroupID"); - if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) { - struct samldb_ctx *ac; - ac = samldb_ctx_init(module, req); - if (ac == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req, - req->op.mod.message); - - return samldb_prim_group_change(ac); + /* DCs have primaryGroupID of DOMAIN_RID_DCS */ + if (!ldb_msg_find_element(msg, "primaryGroupID")) { + ret = samdb_msg_add_uint(ldb, msg, msg, + "primaryGroupID", DOMAIN_RID_DCS); + if (ret != LDB_SUCCESS) { + return ret; + } + el2 = ldb_msg_find_element(msg, "primaryGroupID"); + el2->flags = LDB_FLAG_MOD_REPLACE; + } + } } el = ldb_msg_find_element(req->op.mod.message, "member"); @@ -2392,17 +1874,41 @@ static int samldb_delete(struct ldb_module *module, struct ldb_request *req) return samldb_prim_group_users_check(ac); } +static int samldb_extended_allocate_rid_pool(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct dsdb_fsmo_extended_op *exop; + int ret; + + exop = talloc_get_type(req->op.extended.data, struct dsdb_fsmo_extended_op); + if (!exop) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "samldb_extended_allocate_rid_pool: invalid extended data\n"); + return LDB_ERR_PROTOCOL_ERROR; + } + + ret = ridalloc_allocate_rid_pool_fsmo(module, exop); + if (ret != LDB_SUCCESS) { + return ret; + } + + return ldb_module_done(req, NULL, NULL, LDB_SUCCESS); +} -static int samldb_init(struct ldb_module *module) +static int samldb_extended(struct ldb_module *module, struct ldb_request *req) { - return ldb_next_init(module); + if (strcmp(req->op.extended.oid, DSDB_EXTENDED_ALLOCATE_RID_POOL) == 0) { + return samldb_extended_allocate_rid_pool(module, req); + } + + return ldb_next_request(module, req); } + _PUBLIC_ const struct ldb_module_ops ldb_samldb_module_ops = { .name = "samldb", - .init_context = samldb_init, .add = samldb_add, .modify = samldb_modify, - .del = samldb_delete + .del = samldb_delete, + .extended = samldb_extended }; |