From c915bd87185f37f95272b3332aecb470d93a5548 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 3 Jan 2010 23:08:46 +0100 Subject: linked_attributes: Fix missing dependency on util. --- source4/dsdb/samdb/ldb_modules/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 6128dc9d65..8f7b5d3258 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -337,7 +337,7 @@ ldb_subtree_delete_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/subtree_delete.o [MODULE::ldb_linked_attributes] INIT_FUNCTION = LDB_MODULE(linked_attributes) CFLAGS = -Ilib/ldb/include -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SAMDB +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SAMDB DSDB_MODULE_HELPERS SUBSYSTEM = LIBLDB # End MODULE ldb_linked_attributes ################################################ -- cgit From 7f90a05c66df5483e949b109b9018ee70b9c5d27 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 5 Jan 2010 17:09:51 +1100 Subject: s4-samldb: use RID Set to allocate user/group RIDs This is the first step towards DRS-friendly RID allocation. We now get the next rid from the RID Set object Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/samldb.c | 663 +++++--------------------------- 1 file changed, 104 insertions(+), 559 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 17a99c74c7..4fb842fdc6 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,128 @@ static int samldb_check_samAccountType(struct samldb_ctx *ac) return samldb_next_step(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); +} -/* - * samldb_get_sid_domain (async) - */ -static int samldb_get_sid_domain_callback(struct ldb_request *req, - struct ldb_reply *ares) +/* allocate a SID using our RID Set */ +static int samldb_allocate_sid(struct samldb_ctx *ac) { struct ldb_context *ldb; - struct samldb_ctx *ac; - const char *nextRid; + static const char * const attrs[] = { "rIDAllocationPool", "rIDNextRID" , NULL }; int ret; + struct ldb_dn *rid_set_dn; + struct ldb_result *res; + uint64_t alloc_pool; + uint32_t alloc_pool_lo, alloc_pool_hi; + int next_rid; + struct ldb_message *msg; + TALLOC_CTX *tmp_ctx = talloc_new(ac); + struct ldb_message_element *el; + struct ldb_val v1, v2; + char *ridstring; - 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; + ret = samdb_rid_set_dn(ldb, tmp_ctx, &rid_set_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": No RID Set DN"); + talloc_free(tmp_ctx); + return ret; } -done: + ret = dsdb_module_search_dn(ac->module, tmp_ctx, &res, rid_set_dn, + attrs, 0); if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); + ldb_asprintf_errstring(ldb, __location__ ": No RID Set %s", ldb_dn_get_linearized(rid_set_dn)); + talloc_free(tmp_ctx); + return ret; } - return LDB_SUCCESS; -} + alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0); + next_rid = ldb_msg_find_attr_as_int(res->msgs[0], "rIDNextRID", -1); + if (next_rid == -1 || alloc_pool == 0) { + ldb_asprintf_errstring(ldb, __location__ ": Bad RID Set %s", ldb_dn_get_linearized(rid_set_dn)); + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } -/* Find a domain object in the parents of a particular DN. */ -static int samldb_get_sid_domain(struct samldb_ctx *ac) -{ - struct ldb_context *ldb; - static const char * const attrs[] = { "nextRid", NULL }; - struct ldb_request *req; - char *filter; - int ret; + alloc_pool_lo = alloc_pool & 0xFFFFFFFF; + alloc_pool_hi = alloc_pool >> 32; + if (next_rid > alloc_pool_hi) { + /* TODO: add call to RID Manager */ + ldb_asprintf_errstring(ldb, __location__ ": Out of RIDs in RID Set %s", + ldb_dn_get_linearized(rid_set_dn)); + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } - ldb = ldb_module_get_ctx(ac->module); + /* despite the name, rIDNextRID is the value of the last user + * added by this DC, not the next available RID */ + ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), next_rid+1); if (ac->sid == NULL) { + talloc_free(tmp_ctx); return LDB_ERR_OPERATIONS_ERROR; } - ac->domain_sid = dom_sid_dup(ac, ac->sid); - if (!ac->domain_sid) { + if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) { + talloc_free(tmp_ctx); 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) { + /* now modify the RID Set to use up this RID using a + * constrained delete/add */ + msg = ldb_msg_new(tmp_ctx); + msg->dn = rid_set_dn; + + ret = ldb_msg_add_empty(msg, "rIDNextRID", LDB_FLAG_MOD_DELETE, &el); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + el->num_values = 1; + el->values = &v1; + ridstring = talloc_asprintf(msg, "%u", (unsigned)next_rid); + if (!ridstring) { + ldb_module_oom(ac->module); return LDB_ERR_OPERATIONS_ERROR; } + v1 = data_blob_string_const(ridstring); - 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); + ret = ldb_msg_add_empty(msg, "rIDNextRID", LDB_FLAG_MOD_ADD, &el); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + el->num_values = 1; + el->values = &v2; + ridstring = talloc_asprintf(msg, "%u", (unsigned)next_rid+1); + if (!ridstring) { + ldb_module_oom(ac->module); + return LDB_ERR_OPERATIONS_ERROR; + } + v2 = data_blob_string_const(ridstring); + ret = dsdb_module_modify(ac->module, msg, 0); if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); return ret; } - ac->next_rid = 0; - return ldb_next_request(ac->module, req); + return samldb_next_step(ac); } /* @@ -722,161 +577,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 +842,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) { @@ -1287,20 +982,20 @@ 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)) { + 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 +1005,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 +1012,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 +1029,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; @@ -2393,14 +1944,8 @@ static int samldb_delete(struct ldb_module *module, struct ldb_request *req) } -static int samldb_init(struct ldb_module *module) -{ - return ldb_next_init(module); -} - _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 -- cgit From 226460d543892fcfcb569297bc450648f4fc4f0f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 5 Jan 2010 18:23:46 +1100 Subject: s4-dsdb: move the RID allocation logic into ridalloc.c This will end up having the RID Manager logic as well, so all the RID pool allocation logic is in one spot Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/config.mk | 4 +- source4/dsdb/samdb/ldb_modules/ridalloc.c | 140 ++++++++++++++++++++++++++++++ source4/dsdb/samdb/ldb_modules/samldb.c | 93 ++------------------ 3 files changed, 148 insertions(+), 89 deletions(-) create mode 100644 source4/dsdb/samdb/ldb_modules/ridalloc.c (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 8f7b5d3258..38ea1483e9 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -3,7 +3,9 @@ [SUBSYSTEM::DSDB_MODULE_HELPERS] PRIVATE_DEPENDENCIES = LIBLDB LIBNDR SAMDB_SCHEMA -DSDB_MODULE_HELPERS_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/util.o +DSDB_MODULE_HELPERS_OBJ_FILES = \ + $(dsdbsrcdir)/samdb/ldb_modules/util.o \ + $(dsdbsrcdir)/samdb/ldb_modules/ridalloc.o $(eval $(call proto_header_template,$(dsdbsrcdir)/samdb/ldb_modules/util_proto.h,$(DSDB_MODULE_HELPERS_OBJ_FILES:.o=.c))) diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c new file mode 100644 index 0000000000..12318314d8 --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -0,0 +1,140 @@ +/* + RID allocation helper functions + + Copyright (C) Andrew Bartlett 2010 + Copyright (C) Andrew Tridgell 2010 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * Name: ldb + * + * Component: RID allocation logic + * + * Description: manage RID Set and RID Manager objects + * + */ + +#include "includes.h" +#include "ldb_module.h" +#include "dsdb/samdb/samdb.h" +#include "dsdb/samdb/ldb_modules/util.h" + +/* allocate a RID using our RID Set + If we run out of RIDs then allocate a new pool + either locally or by contacting the RID Manager +*/ +int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) +{ + struct ldb_context *ldb; + static const char * const attrs[] = { "rIDAllocationPool", "rIDNextRID" , NULL }; + int ret; + struct ldb_dn *rid_set_dn; + struct ldb_result *res; + uint64_t alloc_pool; + uint32_t alloc_pool_lo, alloc_pool_hi; + int next_rid; + struct ldb_message *msg; + TALLOC_CTX *tmp_ctx = talloc_new(module); + struct ldb_message_element *el; + struct ldb_val v1, v2; + char *ridstring; + + ldb = ldb_module_get_ctx(module); + + ret = samdb_rid_set_dn(ldb, tmp_ctx, &rid_set_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": No RID Set DN"); + talloc_free(tmp_ctx); + return ret; + } + + ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_set_dn, attrs, 0); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": No RID Set %s", + ldb_dn_get_linearized(rid_set_dn)); + talloc_free(tmp_ctx); + return ret; + } + + alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0); + next_rid = ldb_msg_find_attr_as_int(res->msgs[0], "rIDNextRID", -1); + if (next_rid == -1 || alloc_pool == 0) { + ldb_asprintf_errstring(ldb, __location__ ": Bad RID Set %s", + ldb_dn_get_linearized(rid_set_dn)); + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + alloc_pool_lo = alloc_pool & 0xFFFFFFFF; + alloc_pool_hi = alloc_pool >> 32; + if (next_rid > alloc_pool_hi) { + /* TODO: add call to RID Manager */ + ldb_asprintf_errstring(ldb, __location__ ": Out of RIDs in RID Set %s", + ldb_dn_get_linearized(rid_set_dn)); + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* despite the name, rIDNextRID is the value of the last user + * added by this DC, not the next available RID */ + + (*rid) = next_rid + 1; + + /* now modify the RID Set to use up this RID using a + * constrained delete/add */ + msg = ldb_msg_new(tmp_ctx); + msg->dn = rid_set_dn; + + ret = ldb_msg_add_empty(msg, "rIDNextRID", LDB_FLAG_MOD_DELETE, &el); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + el->num_values = 1; + el->values = &v1; + ridstring = talloc_asprintf(msg, "%u", (unsigned)next_rid); + if (!ridstring) { + ldb_module_oom(module); + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + v1 = data_blob_string_const(ridstring); + + ret = ldb_msg_add_empty(msg, "rIDNextRID", LDB_FLAG_MOD_ADD, &el); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + el->num_values = 1; + el->values = &v2; + ridstring = talloc_asprintf(msg, "%u", (unsigned)next_rid+1); + if (!ridstring) { + ldb_module_oom(module); + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + v2 = data_blob_string_const(ridstring); + + ret = dsdb_module_modify(module, msg, 0); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + talloc_free(tmp_ctx); + + return LDB_SUCCESS; +} diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 4fb842fdc6..eb83633fe2 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -344,107 +344,24 @@ static bool samldb_msg_add_sid(struct ldb_message *msg, /* 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[] = { "rIDAllocationPool", "rIDNextRID" , NULL }; + uint32_t rid; int ret; - struct ldb_dn *rid_set_dn; - struct ldb_result *res; - uint64_t alloc_pool; - uint32_t alloc_pool_lo, alloc_pool_hi; - int next_rid; - struct ldb_message *msg; - TALLOC_CTX *tmp_ctx = talloc_new(ac); - struct ldb_message_element *el; - struct ldb_val v1, v2; - char *ridstring; - - ldb = ldb_module_get_ctx(ac->module); - - ret = samdb_rid_set_dn(ldb, tmp_ctx, &rid_set_dn); - if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, __location__ ": No RID Set DN"); - talloc_free(tmp_ctx); - return ret; - } + struct ldb_context *ldb = ldb_module_get_ctx(ac->module); - ret = dsdb_module_search_dn(ac->module, tmp_ctx, &res, rid_set_dn, - attrs, 0); + ret = ridalloc_allocate_rid(ac->module, &rid); if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, __location__ ": No RID Set %s", ldb_dn_get_linearized(rid_set_dn)); - talloc_free(tmp_ctx); return ret; } - alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0); - next_rid = ldb_msg_find_attr_as_int(res->msgs[0], "rIDNextRID", -1); - if (next_rid == -1 || alloc_pool == 0) { - ldb_asprintf_errstring(ldb, __location__ ": Bad RID Set %s", ldb_dn_get_linearized(rid_set_dn)); - talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - alloc_pool_lo = alloc_pool & 0xFFFFFFFF; - alloc_pool_hi = alloc_pool >> 32; - if (next_rid > alloc_pool_hi) { - /* TODO: add call to RID Manager */ - ldb_asprintf_errstring(ldb, __location__ ": Out of RIDs in RID Set %s", - ldb_dn_get_linearized(rid_set_dn)); - talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* despite the name, rIDNextRID is the value of the last user - * added by this DC, not the next available RID */ - - ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), next_rid+1); + ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid); if (ac->sid == NULL) { - talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) { - talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* now modify the RID Set to use up this RID using a - * constrained delete/add */ - msg = ldb_msg_new(tmp_ctx); - msg->dn = rid_set_dn; - - ret = ldb_msg_add_empty(msg, "rIDNextRID", LDB_FLAG_MOD_DELETE, &el); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return ret; - } - el->num_values = 1; - el->values = &v1; - ridstring = talloc_asprintf(msg, "%u", (unsigned)next_rid); - if (!ridstring) { ldb_module_oom(ac->module); return LDB_ERR_OPERATIONS_ERROR; } - v1 = data_blob_string_const(ridstring); - ret = ldb_msg_add_empty(msg, "rIDNextRID", LDB_FLAG_MOD_ADD, &el); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return ret; - } - el->num_values = 1; - el->values = &v2; - ridstring = talloc_asprintf(msg, "%u", (unsigned)next_rid+1); - if (!ridstring) { - ldb_module_oom(ac->module); + if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) { return LDB_ERR_OPERATIONS_ERROR; } - v2 = data_blob_string_const(ridstring); - - ret = dsdb_module_modify(ac->module, msg, 0); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return ret; - } return samldb_next_step(ac); } -- cgit From f137f93e098b23b48d3e7bc9e0bbc46f04b29cbd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 09:17:19 +1100 Subject: s4-dsdb: added dsdb_module_add() added a ldb add function for modules Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/util.c | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c index 32b79a6701..5d66177d8b 100644 --- a/source4/dsdb/samdb/ldb_modules/util.c +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -391,6 +391,52 @@ int dsdb_module_rename(struct ldb_module *module, return ret; } +/* + a ldb_add request operating on modules below the + current module + */ +int dsdb_module_add(struct ldb_module *module, + const struct ldb_message *message, + uint32_t dsdb_flags) +{ + struct ldb_request *req; + int ret; + struct ldb_context *ldb = ldb_module_get_ctx(module); + TALLOC_CTX *tmp_ctx = talloc_new(module); + + ret = ldb_build_add_req(&req, ldb, tmp_ctx, + message, + NULL, + NULL, + ldb_op_default_callback, + NULL); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + ret = dsdb_request_add_controls(module, req, dsdb_flags); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + /* Run the new request */ + if (dsdb_flags & DSDB_FLAG_OWN_MODULE) { + const struct ldb_module_ops *ops = ldb_module_get_ops(module); + ret = ops->add(module, req); + } else { + ret = ldb_next_request(module, req); + } + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + talloc_free(tmp_ctx); + return ret; +} + + const struct dsdb_class * get_last_structural_class(const struct dsdb_schema *schema,const struct ldb_message_element *element) { const struct dsdb_class *last_class = NULL; -- cgit From f24011059b8b656eeb32c2724c0350f135dd2309 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 09:19:04 +1100 Subject: s4-dsdb: added dsdb_module_reference_dn() This adds a module callable version of samdb_reference_dn(), which finds a DN via a reference link Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/util.c | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c index 5d66177d8b..16d5ddecd6 100644 --- a/source4/dsdb/samdb/ldb_modules/util.c +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -492,3 +492,46 @@ int dsdb_check_single_valued_link(const struct dsdb_attribute *attr, return LDB_SUCCESS; } + + +/* + find a 'reference' DN that points at another object + (eg. serverReference, rIDManagerReference etc) + */ +int dsdb_module_reference_dn(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn *base, + const char *attribute, struct ldb_dn **dn) +{ + const char *attrs[2]; + struct ldb_result *res; + int ret; + + attrs[0] = attribute; + attrs[1] = NULL; + + ret = dsdb_module_search_dn(module, mem_ctx, &res, base, attrs, 0); + if (ret != LDB_SUCCESS) { + return ret; + } + + *dn = ldb_msg_find_attr_as_dn(ldb_module_get_ctx(module), + mem_ctx, res->msgs[0], attribute); + if (!*dn) { + talloc_free(res); + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + + talloc_free(res); + return LDB_SUCCESS; +} + +/* + find the RID Manager$ DN via the rIDManagerReference attribute in the + base DN + */ +int dsdb_module_rid_manager_dn(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn **dn) +{ + return dsdb_module_reference_dn(module, mem_ctx, + samdb_base_dn(ldb_module_get_ctx(module)), + "rIDManagerReference", dn); +} + -- cgit From e6f14ac2c4f0d1eaae93980b3628250de945e71e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 09:20:35 +1100 Subject: s4-dsdb: added dsdb_module_constrainted_update_integer() This provides a convenient way to update a integer attribute with a constrained delete/add Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/util.c | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c index 16d5ddecd6..f642160397 100644 --- a/source4/dsdb/samdb/ldb_modules/util.c +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -535,3 +535,53 @@ int dsdb_module_rid_manager_dn(struct ldb_module *module, TALLOC_CTX *mem_ctx, s "rIDManagerReference", dn); } + +/* + update an integer attribute safely via a constrained delete/add + */ +int dsdb_module_constrainted_update_integer(struct ldb_module *module, struct ldb_dn *dn, + const char *attr, uint64_t old_val, uint64_t new_val) +{ + struct ldb_message *msg; + struct ldb_message_element *el; + struct ldb_val v1, v2; + int ret; + char *vstring; + + msg = ldb_msg_new(module); + msg->dn = dn; + + ret = ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_DELETE, &el); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return ret; + } + el->num_values = 1; + el->values = &v1; + vstring = talloc_asprintf(msg, "%llu", (unsigned long long)old_val); + if (!vstring) { + ldb_module_oom(module); + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + v1 = data_blob_string_const(vstring); + + ret = ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_ADD, &el); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return ret; + } + el->num_values = 1; + el->values = &v2; + vstring = talloc_asprintf(msg, "%llu", (unsigned long long)new_val); + if (!vstring) { + ldb_module_oom(module); + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + v2 = data_blob_string_const(vstring); + + ret = dsdb_module_modify(module, msg, 0); + talloc_free(msg); + return ret; +} -- cgit From d0bd6e7ea5a6cc760916acd4f549ac7652c46e05 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 09:21:21 +1100 Subject: s4-dsdb: added dsdb_next_callback() This should be used when you create a sub request and just want the parent requests callback to be called when done. Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/util.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c index f642160397..09b41a254b 100644 --- a/source4/dsdb/samdb/ldb_modules/util.c +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -585,3 +585,15 @@ int dsdb_module_constrainted_update_integer(struct ldb_module *module, struct ld talloc_free(msg); return ret; } + +/* + used to chain to the callers callback + */ +int dsdb_next_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct ldb_request *up_req = talloc_get_type(req->context, struct ldb_request); + + talloc_steal(up_req, req); + return up_req->callback(up_req, ares); +} + -- cgit From 439ee5aaaeb9036d2db69d512bcbc7e88f4a601e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 09:23:29 +1100 Subject: s4-dsdb: use dsdb_next_callback() We can't just use the callers callback directly otherwise the ldb_module_done() is never called on the parent request, as the child request is passed to the callback. Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/instancetype.c | 3 ++- source4/dsdb/samdb/ldb_modules/lazy_commit.c | 13 +++++++------ source4/dsdb/samdb/ldb_modules/show_deleted.c | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/instancetype.c b/source4/dsdb/samdb/ldb_modules/instancetype.c index b17f40e82a..0a297d587a 100644 --- a/source4/dsdb/samdb/ldb_modules/instancetype.c +++ b/source4/dsdb/samdb/ldb_modules/instancetype.c @@ -36,6 +36,7 @@ #include "librpc/gen_ndr/ndr_misc.h" #include "dsdb/samdb/samdb.h" #include "../libds/common/flags.h" +#include "dsdb/samdb/ldb_modules/util.h" struct it_context { struct ldb_module *module; @@ -143,7 +144,7 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req) ret = ldb_build_add_req(&down_req, ldb, req, msg, req->controls, - req->context, req->callback, + req, dsdb_next_callback, req); if (ret != LDB_SUCCESS) { return ret; diff --git a/source4/dsdb/samdb/ldb_modules/lazy_commit.c b/source4/dsdb/samdb/ldb_modules/lazy_commit.c index 0502b2efa1..b4eaf50d51 100644 --- a/source4/dsdb/samdb/ldb_modules/lazy_commit.c +++ b/source4/dsdb/samdb/ldb_modules/lazy_commit.c @@ -28,6 +28,7 @@ */ #include "ldb_module.h" +#include "dsdb/samdb/ldb_modules/util.h" static int unlazy_op(struct ldb_module *module, struct ldb_request *req) { @@ -47,28 +48,28 @@ static int unlazy_op(struct ldb_module *module, struct ldb_request *req) req->op.search.tree, req->op.search.attrs, req->controls, - req->context, req->callback, + req, dsdb_next_callback, req); break; case LDB_ADD: ret = ldb_build_add_req(&new_req, ldb_module_get_ctx(module), req, req->op.add.message, req->controls, - req->context, req->callback, + req, dsdb_next_callback, req); break; case LDB_MODIFY: ret = ldb_build_mod_req(&new_req, ldb_module_get_ctx(module), req, req->op.mod.message, req->controls, - req->context, req->callback, + req, dsdb_next_callback, req); break; case LDB_DELETE: ret = ldb_build_del_req(&new_req, ldb_module_get_ctx(module), req, req->op.del.dn, req->controls, - req->context, req->callback, + req, dsdb_next_callback, req); break; case LDB_RENAME: @@ -76,7 +77,7 @@ static int unlazy_op(struct ldb_module *module, struct ldb_request *req) req->op.rename.olddn, req->op.rename.newdn, req->controls, - req->context, req->callback, + req, dsdb_next_callback, req); break; case LDB_EXTENDED: @@ -85,7 +86,7 @@ static int unlazy_op(struct ldb_module *module, struct ldb_request *req) req->op.extended.oid, req->op.extended.data, req->controls, - req->context, req->callback, + req, dsdb_next_callback, req); break; default: diff --git a/source4/dsdb/samdb/ldb_modules/show_deleted.c b/source4/dsdb/samdb/ldb_modules/show_deleted.c index 666d28053c..93463ae95f 100644 --- a/source4/dsdb/samdb/ldb_modules/show_deleted.c +++ b/source4/dsdb/samdb/ldb_modules/show_deleted.c @@ -32,7 +32,7 @@ #include "includes.h" #include "ldb/include/ldb_module.h" #include "dsdb/samdb/samdb.h" - +#include "dsdb/samdb/ldb_modules/util.h" static int show_deleted_search(struct ldb_module *module, struct ldb_request *req) { @@ -83,7 +83,7 @@ static int show_deleted_search(struct ldb_module *module, struct ldb_request *re new_tree, req->op.search.attrs, req->controls, - req->context, req->callback, + req, dsdb_next_callback, req); if (ret != LDB_SUCCESS) { return ret; -- cgit From 1053ce529d2ed833edd9343c36f28b4ba788db96 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 09:24:29 +1100 Subject: s4-dsdb: implement creation of the RID Set object when we are the RID Manager we can create our own RID Set object when the first user is created --- source4/dsdb/samdb/ldb_modules/ridalloc.c | 348 +++++++++++++++++++++++++----- 1 file changed, 289 insertions(+), 59 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index 12318314d8..8715828fd9 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -32,109 +32,339 @@ #include "dsdb/samdb/samdb.h" #include "dsdb/samdb/ldb_modules/util.h" -/* allocate a RID using our RID Set - If we run out of RIDs then allocate a new pool - either locally or by contacting the RID Manager -*/ -int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) + +/* + create a RID Set object for the specified DC + */ +static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *mem_ctx, + struct ldb_dn *rid_manager_dn, + struct ldb_dn *ntds_dn, struct ldb_dn **dn) { - struct ldb_context *ldb; - static const char * const attrs[] = { "rIDAllocationPool", "rIDNextRID" , NULL }; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + struct ldb_dn *server_dn, *machine_dn, *rid_set_dn; int ret; - struct ldb_dn *rid_set_dn; - struct ldb_result *res; - uint64_t alloc_pool; - uint32_t alloc_pool_lo, alloc_pool_hi; - int next_rid; + const char *attrs[] = { "rIDAvailablePool", NULL }; + uint64_t rid_pool, new_rid_pool, dc_pool; + uint32_t rid_pool_lo, rid_pool_hi; struct ldb_message *msg; - TALLOC_CTX *tmp_ctx = talloc_new(module); - struct ldb_message_element *el; - struct ldb_val v1, v2; - char *ridstring; + struct ldb_context *ldb = ldb_module_get_ctx(module); + const unsigned int alloc_size = 500; + struct ldb_result *res; - ldb = ldb_module_get_ctx(module); + /* + steps: - ret = samdb_rid_set_dn(ldb, tmp_ctx, &rid_set_dn); + find the machine object for the DC + construct the RID Set DN + load rIDAvailablePool to find next available set + modify RID Manager object to update rIDAvailablePool + add the RID Set object + link to the RID Set object in machine object + */ + + server_dn = ldb_dn_get_parent(tmp_ctx, ntds_dn); + if (!server_dn) { + ldb_module_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn); if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, __location__ ": No RID Set DN"); + ldb_asprintf_errstring(ldb, "Failed to find serverReference in %s - %s", + ldb_dn_get_linearized(server_dn), ldb_errstring(ldb)); talloc_free(tmp_ctx); return ret; } - ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_set_dn, attrs, 0); + rid_set_dn = ldb_dn_copy(tmp_ctx, machine_dn); + if (rid_set_dn == NULL) { + ldb_module_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (! ldb_dn_add_child_fmt(rid_set_dn, "CN=RID Set")) { + ldb_module_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_manager_dn, attrs, 0); if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, __location__ ": No RID Set %s", - ldb_dn_get_linearized(rid_set_dn)); + ldb_asprintf_errstring(ldb, "Failed to find rIDAvailablePool in %s - %s", + ldb_dn_get_linearized(rid_manager_dn), ldb_errstring(ldb)); talloc_free(tmp_ctx); return ret; } - alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0); - next_rid = ldb_msg_find_attr_as_int(res->msgs[0], "rIDNextRID", -1); - if (next_rid == -1 || alloc_pool == 0) { - ldb_asprintf_errstring(ldb, __location__ ": Bad RID Set %s", - ldb_dn_get_linearized(rid_set_dn)); + rid_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAvailablePool", 0); + rid_pool_lo = rid_pool & 0xFFFFFFFF; + rid_pool_hi = rid_pool >> 32; + if (rid_pool_lo >= rid_pool_hi) { + ldb_asprintf_errstring(ldb, "Out of RIDs in RID Manager - rIDAvailablePool is %u-%u", + rid_pool_lo, rid_pool_hi); talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } - alloc_pool_lo = alloc_pool & 0xFFFFFFFF; - alloc_pool_hi = alloc_pool >> 32; - if (next_rid > alloc_pool_hi) { - /* TODO: add call to RID Manager */ - ldb_asprintf_errstring(ldb, __location__ ": Out of RIDs in RID Set %s", - ldb_dn_get_linearized(rid_set_dn)); - talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } + /* lower part of new pool is the low part of the rIDAvailablePool */ + dc_pool = rid_pool_lo; - /* despite the name, rIDNextRID is the value of the last user - * added by this DC, not the next available RID */ + /* allocate 500 RIDs to this DC */ + rid_pool_lo = MIN(rid_pool_hi, rid_pool_lo + alloc_size); - (*rid) = next_rid + 1; + /* work out upper part of new pool */ + dc_pool |= (((uint64_t)rid_pool_lo-1)<<32); - /* now modify the RID Set to use up this RID using a - * constrained delete/add */ + /* and new rIDAvailablePool value */ + new_rid_pool = rid_pool_lo | (((uint64_t)rid_pool_hi)<<32); + + ret = dsdb_module_constrainted_update_integer(module, rid_manager_dn, "rIDAvailablePool", + rid_pool, new_rid_pool); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to update rIDAvailablePool - %s", + ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + /* create the RID Set object */ msg = ldb_msg_new(tmp_ctx); msg->dn = rid_set_dn; - ret = ldb_msg_add_empty(msg, "rIDNextRID", LDB_FLAG_MOD_DELETE, &el); + ret = ldb_msg_add_string(msg, "objectClass", "top"); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; } - el->num_values = 1; - el->values = &v1; - ridstring = talloc_asprintf(msg, "%u", (unsigned)next_rid); - if (!ridstring) { - ldb_module_oom(module); + ret = ldb_msg_add_string(msg, "objectClass", "rIDSet"); + if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; + return ret; + } + ret = ldb_msg_add_string(msg, "cn", "RID Set"); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + ret = ldb_msg_add_string(msg, "name", "RID Set"); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + ret = ldb_msg_add_fmt(msg, "rIDAllocationPool", "%llu", (unsigned long long)dc_pool); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + ret = ldb_msg_add_fmt(msg, "rIDPreviousAllocationPool", "%llu", (unsigned long long)dc_pool); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + ret = ldb_msg_add_fmt(msg, "rIDUsedPool", "0"); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + ret = ldb_msg_add_fmt(msg, "rIDNextRID", "%lu", (unsigned long)(dc_pool & 0xFFFFFFFF)); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; } - v1 = data_blob_string_const(ridstring); - ret = ldb_msg_add_empty(msg, "rIDNextRID", LDB_FLAG_MOD_ADD, &el); + ret = dsdb_module_add(module, msg, 0); if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to add RID Set %s - %s", + ldb_dn_get_linearized(msg->dn), + ldb_errstring(ldb)); talloc_free(tmp_ctx); return ret; } - el->num_values = 1; - el->values = &v2; - ridstring = talloc_asprintf(msg, "%u", (unsigned)next_rid+1); - if (!ridstring) { - ldb_module_oom(module); + + /* add the rIDSetReferences link */ + msg = ldb_msg_new(tmp_ctx); + msg->dn = machine_dn; + + ret = ldb_msg_add_string(msg, "rIDSetReferences", ldb_dn_get_linearized(rid_set_dn)); + if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } - v2 = data_blob_string_const(ridstring); + msg->elements[0].flags = LDB_FLAG_MOD_ADD; ret = dsdb_module_modify(module, msg, 0); if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to add rIDSetReferences to %s - %s", + ldb_dn_get_linearized(msg->dn), + ldb_errstring(ldb)); talloc_free(tmp_ctx); return ret; } - talloc_free(tmp_ctx); + (*dn) = talloc_steal(mem_ctx, rid_set_dn); + talloc_free(tmp_ctx); return LDB_SUCCESS; } + + +/* + create a RID Set object for this DC + */ +static int ridalloc_create_own_rid_set(struct ldb_module *module, TALLOC_CTX *mem_ctx, + struct ldb_dn **dn) +{ + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + struct ldb_dn *rid_manager_dn, *fsmo_role_dn; + int ret; + struct ldb_context *ldb = ldb_module_get_ctx(module); + + /* work out who is the RID Manager */ + ret = dsdb_module_rid_manager_dn(module, tmp_ctx, &rid_manager_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to find RID Manager object - %s", + ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + /* find the DN of the RID Manager */ + ret = dsdb_module_reference_dn(module, tmp_ctx, rid_manager_dn, "fSMORoleOwner", &fsmo_role_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to find fSMORoleOwner in RID Manager object - %s", + ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) { + ldb_asprintf_errstring(ldb, "Remote RID Set allocation not implemented"); + talloc_free(tmp_ctx); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + ret = ridalloc_create_rid_set_ntds(module, mem_ctx, rid_manager_dn, fsmo_role_dn, dn); + talloc_free(tmp_ctx); + return ret; +} + +/* + refresh a RID Set object for the specified DC + also returns the first RID for the new pool + */ +static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module, + struct ldb_dn *rid_manager_dn, + struct ldb_dn *ntds_dn, uint32_t *first_rid) +{ + ldb_asprintf_errstring(ldb, "Refresh of RID Set not implemented"); + return LDB_ERR_UNWILLING_TO_PERFORM; +} + + + +/* + get a new RID pool for ourselves + also returns the first rid for the new pool + */ +static int ridalloc_refresh_own_pool(struct ldb_module *module, uint32_t *first_rid) +{ + TALLOC_CTX *tmp_ctx = talloc_new(module); + struct ldb_dn *rid_manager_dn, *fsmo_role_dn; + int ret; + struct ldb_context *ldb = ldb_module_get_ctx(module); + + /* work out who is the RID Manager */ + ret = dsdb_module_rid_manager_dn(module, tmp_ctx, &rid_manager_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to find RID Manager object - %s", + ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + /* find the DN of the RID Manager */ + ret = dsdb_module_reference_dn(module, tmp_ctx, rid_manager_dn, "fSMORoleOwner", &fsmo_role_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to find fSMORoleOwner in RID Manager object - %s", + ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) { + ldb_asprintf_errstring(ldb, "Remote RID Set allocation not implemented"); + talloc_free(tmp_ctx); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + ret = ridalloc_refresh_rid_set_ntds(module, rid_manager_dn, fsmo_role_dn, first_rid); + talloc_free(tmp_ctx); + return ret; +} + + +/* allocate a RID using our RID Set + If we run out of RIDs then allocate a new pool + either locally or by contacting the RID Manager +*/ +int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) +{ + struct ldb_context *ldb; + static const char * const attrs[] = { "rIDAllocationPool", "rIDNextRID" , NULL }; + int ret; + struct ldb_dn *rid_set_dn; + struct ldb_result *res; + uint64_t alloc_pool; + uint32_t alloc_pool_lo, alloc_pool_hi; + int prev_rid; + TALLOC_CTX *tmp_ctx = talloc_new(module); + + ldb = ldb_module_get_ctx(module); + + ret = samdb_rid_set_dn(ldb, tmp_ctx, &rid_set_dn); + if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { + ret = ridalloc_create_own_rid_set(module, tmp_ctx, &rid_set_dn); + } + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": No RID Set DN - %s", + ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_set_dn, attrs, 0); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": No RID Set %s", + ldb_dn_get_linearized(rid_set_dn)); + talloc_free(tmp_ctx); + return ret; + } + + alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0); + prev_rid = ldb_msg_find_attr_as_int(res->msgs[0], "rIDNextRID", -1); + if (prev_rid == -1 || alloc_pool == 0) { + ldb_asprintf_errstring(ldb, __location__ ": Bad RID Set %s", + ldb_dn_get_linearized(rid_set_dn)); + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + alloc_pool_lo = alloc_pool & 0xFFFFFFFF; + alloc_pool_hi = alloc_pool >> 32; + if (prev_rid > alloc_pool_hi) { + ret = ridalloc_refresh_own_pool(module, rid); + if (ret != LDB_SUCCESS) { + return ret; + } + } else { + /* despite the name, rIDNextRID is the value of the last user + * added by this DC, not the next available RID */ + (*rid) = prev_rid + 1; + } + + /* now modify the RID Set to use up this RID using a + * constrained delete/add */ + ret = dsdb_module_constrainted_update_integer(module, rid_set_dn, "rIDNextRID", prev_rid, *rid); + talloc_free(tmp_ctx); + + return ret; +} -- cgit From 5136438ad612435ceb11e81e4dc316791bdc003e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 10:27:30 +1100 Subject: s4-dsdb: implement refresh of RID Set pool for a local RID Manager when we run out of RIDs in our RID Set pool then grab a new one from the RID Manager object Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/ridalloc.c | 195 +++++++++++++++++++++++------- 1 file changed, 151 insertions(+), 44 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index 8715828fd9..421929801c 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -33,6 +33,64 @@ #include "dsdb/samdb/ldb_modules/util.h" +/* + allocate a new range of RIDs in the RID Manager object + */ +static int ridalloc_rid_manager_allocate(struct ldb_module *module, struct ldb_dn *rid_manager_dn, uint64_t *new_pool) +{ + int ret; + TALLOC_CTX *tmp_ctx = talloc_new(module); + const char *attrs[] = { "rIDAvailablePool", NULL }; + uint64_t rid_pool, new_rid_pool, dc_pool; + uint32_t rid_pool_lo, rid_pool_hi; + struct ldb_result *res; + struct ldb_context *ldb = ldb_module_get_ctx(module); + const unsigned alloc_size = 500; + + ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_manager_dn, attrs, 0); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to find rIDAvailablePool in %s - %s", + ldb_dn_get_linearized(rid_manager_dn), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + rid_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAvailablePool", 0); + rid_pool_lo = rid_pool & 0xFFFFFFFF; + rid_pool_hi = rid_pool >> 32; + if (rid_pool_lo >= rid_pool_hi) { + ldb_asprintf_errstring(ldb, "Out of RIDs in RID Manager - rIDAvailablePool is %u-%u", + rid_pool_lo, rid_pool_hi); + talloc_free(tmp_ctx); + return ret; + } + + /* lower part of new pool is the low part of the rIDAvailablePool */ + dc_pool = rid_pool_lo; + + /* allocate 500 RIDs to this DC */ + rid_pool_lo = MIN(rid_pool_hi, rid_pool_lo + alloc_size); + + /* work out upper part of new pool */ + dc_pool |= (((uint64_t)rid_pool_lo-1)<<32); + + /* and new rIDAvailablePool value */ + new_rid_pool = rid_pool_lo | (((uint64_t)rid_pool_hi)<<32); + + ret = dsdb_module_constrainted_update_integer(module, rid_manager_dn, "rIDAvailablePool", + rid_pool, new_rid_pool); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to update rIDAvailablePool - %s", + ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + (*new_pool) = dc_pool; + talloc_free(tmp_ctx); + return LDB_SUCCESS; +} + /* create a RID Set object for the specified DC */ @@ -43,13 +101,9 @@ static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *m TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); struct ldb_dn *server_dn, *machine_dn, *rid_set_dn; int ret; - const char *attrs[] = { "rIDAvailablePool", NULL }; - uint64_t rid_pool, new_rid_pool, dc_pool; - uint32_t rid_pool_lo, rid_pool_hi; + uint64_t dc_pool; struct ldb_message *msg; struct ldb_context *ldb = ldb_module_get_ctx(module); - const unsigned int alloc_size = 500; - struct ldb_result *res; /* steps: @@ -87,41 +141,9 @@ static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *m return LDB_ERR_OPERATIONS_ERROR; } - ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_manager_dn, attrs, 0); - if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, "Failed to find rIDAvailablePool in %s - %s", - ldb_dn_get_linearized(rid_manager_dn), ldb_errstring(ldb)); - talloc_free(tmp_ctx); - return ret; - } - - rid_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAvailablePool", 0); - rid_pool_lo = rid_pool & 0xFFFFFFFF; - rid_pool_hi = rid_pool >> 32; - if (rid_pool_lo >= rid_pool_hi) { - ldb_asprintf_errstring(ldb, "Out of RIDs in RID Manager - rIDAvailablePool is %u-%u", - rid_pool_lo, rid_pool_hi); - talloc_free(tmp_ctx); - return ret; - } - - /* lower part of new pool is the low part of the rIDAvailablePool */ - dc_pool = rid_pool_lo; - - /* allocate 500 RIDs to this DC */ - rid_pool_lo = MIN(rid_pool_hi, rid_pool_lo + alloc_size); - - /* work out upper part of new pool */ - dc_pool |= (((uint64_t)rid_pool_lo-1)<<32); - - /* and new rIDAvailablePool value */ - new_rid_pool = rid_pool_lo | (((uint64_t)rid_pool_hi)<<32); - - ret = dsdb_module_constrainted_update_integer(module, rid_manager_dn, "rIDAvailablePool", - rid_pool, new_rid_pool); + /* grab a pool from the RID Manager object */ + ret = ridalloc_rid_manager_allocate(module, rid_manager_dn, &dc_pool); if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, "Failed to update rIDAvailablePool - %s", - ldb_errstring(ldb)); talloc_free(tmp_ctx); return ret; } @@ -252,11 +274,96 @@ static int ridalloc_create_own_rid_set(struct ldb_module *module, TALLOC_CTX *me also returns the first RID for the new pool */ static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module, - struct ldb_dn *rid_manager_dn, - struct ldb_dn *ntds_dn, uint32_t *first_rid) + struct ldb_dn *rid_manager_dn, + struct ldb_dn *ntds_dn, uint32_t *first_rid) { - ldb_asprintf_errstring(ldb, "Refresh of RID Set not implemented"); - return LDB_ERR_UNWILLING_TO_PERFORM; + TALLOC_CTX *tmp_ctx = talloc_new(module); + uint64_t new_pool; + struct ldb_dn *server_dn, *machine_dn, *rid_set_dn; + struct ldb_result *res; + const char *attrs[] = { "rIDAllocationPool", "rIDUsedPool", NULL }; + struct ldb_message *msg; + uint64_t prev_pool; + uint32_t used_pool; + struct ldb_context *ldb = ldb_module_get_ctx(module); + int ret; + + /* grab a pool from the RID Manager object */ + ret = ridalloc_rid_manager_allocate(module, rid_manager_dn, &new_pool); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + server_dn = ldb_dn_get_parent(tmp_ctx, ntds_dn); + if (!server_dn) { + ldb_module_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to find serverReference in %s - %s", + ldb_dn_get_linearized(server_dn), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + ret = dsdb_module_reference_dn(module, tmp_ctx, machine_dn, "rIDSetReferences", &rid_set_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to find rIDSetReferences in %s - %s", + ldb_dn_get_linearized(machine_dn), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_set_dn, attrs, 0); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to load old pool values from %s - %s", + ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + prev_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0); + used_pool = ldb_msg_find_attr_as_uint(res->msgs[0], "rIDUsedPool", 0); + + msg = ldb_msg_new(tmp_ctx); + msg->dn = rid_set_dn; + + ret = ldb_msg_add_fmt(msg, "rIDPreviousAllocationPool", "%llu", (unsigned long long)prev_pool); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; + + ret = ldb_msg_add_fmt(msg, "rIDAllocationPool", "%llu", (unsigned long long)new_pool); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + msg->elements[1].flags = LDB_FLAG_MOD_REPLACE; + + ret = ldb_msg_add_fmt(msg, "rIDUsedPool", "%lu", (unsigned long)used_pool+1); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + msg->elements[2].flags = LDB_FLAG_MOD_REPLACE; + + ret = dsdb_module_modify(module, msg, 0); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to modify RID Set object %s - %s", + ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + (*first_rid) = (new_pool & 0xFFFFFFFF); + + talloc_free(tmp_ctx); + return LDB_SUCCESS; } @@ -350,7 +457,7 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) alloc_pool_lo = alloc_pool & 0xFFFFFFFF; alloc_pool_hi = alloc_pool >> 32; - if (prev_rid > alloc_pool_hi) { + if (prev_rid >= alloc_pool_hi) { ret = ridalloc_refresh_own_pool(module, rid); if (ret != LDB_SUCCESS) { return ret; -- cgit From dd8cb3c7ed1e32fa4073c6e38dafc35fe2cb4f72 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 11:38:38 +1100 Subject: s4-dsdb: fixed usage of rIDAllocationPool and rIDPreviousAllocationPool These are very badly named attributes! See the comments in ridalloc.c for a explanation of what they really seem to mean Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/ridalloc.c | 102 +++++++++++++++++------------- 1 file changed, 58 insertions(+), 44 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index 421929801c..c616da01fe 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -32,6 +32,23 @@ #include "dsdb/samdb/samdb.h" #include "dsdb/samdb/ldb_modules/util.h" +/* + Note: the RID allocation attributes in AD are very badly named. Here + is what we think they really do: + + in RID Set object: + - rIDPreviousAllocationPool: the pool which a DC is currently + pulling RIDs from + - rIDAllocationPool: the pool that the DC will switch to next, + when rIDPreviousAllocationPool is exhausted + - rIDNextRID: the last RID allocated by this DC + + in RID Manager object: + - rIDAvailablePool: the pool where the RID Manager gets new rID + pools from when it gets a EXOP_RID_ALLOC getncchanges call (or + locally when the DC is the RID Manager) + */ + /* allocate a new range of RIDs in the RID Manager object @@ -177,6 +194,8 @@ static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *m talloc_free(tmp_ctx); return ret; } + /* TODO: check if the RID Manager adds these fields, or if the + client DC does it */ ret = ldb_msg_add_fmt(msg, "rIDPreviousAllocationPool", "%llu", (unsigned long long)dc_pool); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); @@ -275,21 +294,16 @@ static int ridalloc_create_own_rid_set(struct ldb_module *module, TALLOC_CTX *me */ static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module, struct ldb_dn *rid_manager_dn, - struct ldb_dn *ntds_dn, uint32_t *first_rid) + struct ldb_dn *ntds_dn, uint64_t *new_pool) { TALLOC_CTX *tmp_ctx = talloc_new(module); - uint64_t new_pool; struct ldb_dn *server_dn, *machine_dn, *rid_set_dn; - struct ldb_result *res; - const char *attrs[] = { "rIDAllocationPool", "rIDUsedPool", NULL }; struct ldb_message *msg; - uint64_t prev_pool; - uint32_t used_pool; struct ldb_context *ldb = ldb_module_get_ctx(module); int ret; /* grab a pool from the RID Manager object */ - ret = ridalloc_rid_manager_allocate(module, rid_manager_dn, &new_pool); + ret = ridalloc_rid_manager_allocate(module, rid_manager_dn, new_pool); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; @@ -317,41 +331,16 @@ static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module, return ret; } - ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_set_dn, attrs, 0); - if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, "Failed to load old pool values from %s - %s", - ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb)); - talloc_free(tmp_ctx); - return ret; - } - - prev_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0); - used_pool = ldb_msg_find_attr_as_uint(res->msgs[0], "rIDUsedPool", 0); - msg = ldb_msg_new(tmp_ctx); msg->dn = rid_set_dn; - ret = ldb_msg_add_fmt(msg, "rIDPreviousAllocationPool", "%llu", (unsigned long long)prev_pool); + ret = ldb_msg_add_fmt(msg, "rIDAllocationPool", "%llu", (unsigned long long)*new_pool); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; } msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; - ret = ldb_msg_add_fmt(msg, "rIDAllocationPool", "%llu", (unsigned long long)new_pool); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return ret; - } - msg->elements[1].flags = LDB_FLAG_MOD_REPLACE; - - ret = ldb_msg_add_fmt(msg, "rIDUsedPool", "%lu", (unsigned long)used_pool+1); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return ret; - } - msg->elements[2].flags = LDB_FLAG_MOD_REPLACE; - ret = dsdb_module_modify(module, msg, 0); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, "Failed to modify RID Set object %s - %s", @@ -360,8 +349,6 @@ static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module, return ret; } - (*first_rid) = (new_pool & 0xFFFFFFFF); - talloc_free(tmp_ctx); return LDB_SUCCESS; } @@ -372,7 +359,7 @@ static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module, get a new RID pool for ourselves also returns the first rid for the new pool */ -static int ridalloc_refresh_own_pool(struct ldb_module *module, uint32_t *first_rid) +static int ridalloc_refresh_own_pool(struct ldb_module *module, uint64_t *new_pool) { TALLOC_CTX *tmp_ctx = talloc_new(module); struct ldb_dn *rid_manager_dn, *fsmo_role_dn; @@ -403,7 +390,7 @@ static int ridalloc_refresh_own_pool(struct ldb_module *module, uint32_t *first_ return LDB_ERR_UNWILLING_TO_PERFORM; } - ret = ridalloc_refresh_rid_set_ntds(module, rid_manager_dn, fsmo_role_dn, first_rid); + ret = ridalloc_refresh_rid_set_ntds(module, rid_manager_dn, fsmo_role_dn, new_pool); talloc_free(tmp_ctx); return ret; } @@ -416,12 +403,13 @@ static int ridalloc_refresh_own_pool(struct ldb_module *module, uint32_t *first_ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) { struct ldb_context *ldb; - static const char * const attrs[] = { "rIDAllocationPool", "rIDNextRID" , NULL }; + static const char * const attrs[] = { "rIDAllocationPool", "rIDPreviousAllocationPool", + "rIDNextRID" , NULL }; int ret; struct ldb_dn *rid_set_dn; struct ldb_result *res; - uint64_t alloc_pool; - uint32_t alloc_pool_lo, alloc_pool_hi; + uint64_t alloc_pool, prev_alloc_pool; + uint32_t prev_alloc_pool_lo, prev_alloc_pool_hi; int prev_rid; TALLOC_CTX *tmp_ctx = talloc_new(module); @@ -446,6 +434,7 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) return ret; } + prev_alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDPreviousAllocationPool", 0); alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0); prev_rid = ldb_msg_find_attr_as_int(res->msgs[0], "rIDNextRID", -1); if (prev_rid == -1 || alloc_pool == 0) { @@ -455,13 +444,38 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) return LDB_ERR_OPERATIONS_ERROR; } - alloc_pool_lo = alloc_pool & 0xFFFFFFFF; - alloc_pool_hi = alloc_pool >> 32; - if (prev_rid >= alloc_pool_hi) { - ret = ridalloc_refresh_own_pool(module, rid); + prev_alloc_pool_lo = prev_alloc_pool & 0xFFFFFFFF; + prev_alloc_pool_hi = prev_alloc_pool >> 32; + if (prev_rid >= prev_alloc_pool_hi) { + ret = dsdb_module_constrainted_update_integer(module, rid_set_dn, "rIDPreviousAllocationPool", + prev_alloc_pool, alloc_pool); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": Failed to update rIDPreviousAllocationPool on %s - %s", + ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + prev_alloc_pool = alloc_pool; + prev_alloc_pool_lo = prev_alloc_pool & 0xFFFFFFFF; + prev_alloc_pool_hi = prev_alloc_pool >> 32; + } + /* see if we are still out of RIDs, and if so then ask + the RID Manager to give us more */ + if (prev_rid >= prev_alloc_pool_hi) { + uint64_t new_pool; + ret = ridalloc_refresh_own_pool(module, &new_pool); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = dsdb_module_constrainted_update_integer(module, rid_set_dn, "rIDPreviousAllocationPool", + prev_alloc_pool, new_pool); if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": Failed to update rIDPreviousAllocationPool on %s - %s", + ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb)); + talloc_free(tmp_ctx); return ret; } + (*rid) = (new_pool & 0xFFFFFFFF); } else { /* despite the name, rIDNextRID is the value of the last user * added by this DC, not the next available RID */ -- cgit From c12b9ab2f2d26147a0878bbb2a1672892599293e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 11:40:05 +1100 Subject: s4-dsdb: clarify who is responsible for each attribute Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/ridalloc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index c616da01fe..87642592c4 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -38,10 +38,12 @@ in RID Set object: - rIDPreviousAllocationPool: the pool which a DC is currently - pulling RIDs from + pulling RIDs from. Managed by client DC + - rIDAllocationPool: the pool that the DC will switch to next, - when rIDPreviousAllocationPool is exhausted - - rIDNextRID: the last RID allocated by this DC + when rIDPreviousAllocationPool is exhausted. Managed by RID Manager. + + - rIDNextRID: the last RID allocated by this DC. Managed by client DC in RID Manager object: - rIDAvailablePool: the pool where the RID Manager gets new rID -- cgit From 45550f83f00f259a64cd70f7b2f741a12ee55854 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 14:48:55 +1100 Subject: s4-dsdb: added dsdb_module_set_integer() This will be used by ridalloc.c Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/util.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c index 09b41a254b..12972eb185 100644 --- a/source4/dsdb/samdb/ldb_modules/util.c +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -597,3 +597,27 @@ int dsdb_next_callback(struct ldb_request *req, struct ldb_reply *ares) return up_req->callback(up_req, ares); } + +/* + set an integer attribute + */ +int dsdb_module_set_integer(struct ldb_module *module, struct ldb_dn *dn, + const char *attr, uint64_t new_val) +{ + struct ldb_message *msg; + int ret; + + msg = ldb_msg_new(module); + msg->dn = dn; + + ret = ldb_msg_add_fmt(msg, attr, "%llu", (unsigned long long)new_val); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return ret; + } + msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; + + ret = dsdb_module_modify(module, msg, 0); + talloc_free(msg); + return ret; +} -- cgit From 37340d5a2e04a194479beb80b96b0bc78df4393a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 14:50:04 +1100 Subject: s4-ridalloc: copy with missing rIDNextRid and rIDAllocationPool The attributes rIDNextRid and rIDAllocationPool are not replicated, so their initial value when we first get a RID Set from the RID Manager is blank. Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/ridalloc.c | 60 ++++++++++++++++++------------- 1 file changed, 36 insertions(+), 24 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index 87642592c4..02737dd88b 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -196,9 +196,9 @@ static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *m talloc_free(tmp_ctx); return ret; } - /* TODO: check if the RID Manager adds these fields, or if the - client DC does it */ - ret = ldb_msg_add_fmt(msg, "rIDPreviousAllocationPool", "%llu", (unsigned long long)dc_pool); + + /* w2k8-r2 sets these to zero when first created */ + ret = ldb_msg_add_fmt(msg, "rIDPreviousAllocationPool", "0"); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; @@ -208,7 +208,7 @@ static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *m talloc_free(tmp_ctx); return ret; } - ret = ldb_msg_add_fmt(msg, "rIDNextRID", "%lu", (unsigned long)(dc_pool & 0xFFFFFFFF)); + ret = ldb_msg_add_fmt(msg, "rIDNextRID", "0"); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; @@ -300,7 +300,6 @@ static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module, { TALLOC_CTX *tmp_ctx = talloc_new(module); struct ldb_dn *server_dn, *machine_dn, *rid_set_dn; - struct ldb_message *msg; struct ldb_context *ldb = ldb_module_get_ctx(module); int ret; @@ -333,17 +332,7 @@ static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module, return ret; } - msg = ldb_msg_new(tmp_ctx); - msg->dn = rid_set_dn; - - ret = ldb_msg_add_fmt(msg, "rIDAllocationPool", "%llu", (unsigned long long)*new_pool); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return ret; - } - msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; - - ret = dsdb_module_modify(module, msg, 0); + ret = dsdb_module_set_integer(module, rid_set_dn, "rIDAllocationPool", *new_pool); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, "Failed to modify RID Set object %s - %s", ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb)); @@ -438,8 +427,8 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) prev_alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDPreviousAllocationPool", 0); alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0); - prev_rid = ldb_msg_find_attr_as_int(res->msgs[0], "rIDNextRID", -1); - if (prev_rid == -1 || alloc_pool == 0) { + prev_rid = ldb_msg_find_attr_as_int(res->msgs[0], "rIDNextRID", 0); + if (alloc_pool == 0) { ldb_asprintf_errstring(ldb, __location__ ": Bad RID Set %s", ldb_dn_get_linearized(rid_set_dn)); talloc_free(tmp_ctx); @@ -449,8 +438,12 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) prev_alloc_pool_lo = prev_alloc_pool & 0xFFFFFFFF; prev_alloc_pool_hi = prev_alloc_pool >> 32; if (prev_rid >= prev_alloc_pool_hi) { - ret = dsdb_module_constrainted_update_integer(module, rid_set_dn, "rIDPreviousAllocationPool", - prev_alloc_pool, alloc_pool); + if (prev_alloc_pool == 0) { + ret = dsdb_module_set_integer(module, rid_set_dn, "rIDPreviousAllocationPool", alloc_pool); + } else { + ret = dsdb_module_constrainted_update_integer(module, rid_set_dn, "rIDPreviousAllocationPool", + prev_alloc_pool, alloc_pool); + } if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, __location__ ": Failed to update rIDPreviousAllocationPool on %s - %s", ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb)); @@ -477,16 +470,35 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) talloc_free(tmp_ctx); return ret; } - (*rid) = (new_pool & 0xFFFFFFFF); + prev_alloc_pool = new_pool; + prev_alloc_pool_lo = prev_alloc_pool & 0xFFFFFFFF; + prev_alloc_pool_hi = prev_alloc_pool >> 32; + (*rid) = prev_alloc_pool_lo; } else { /* despite the name, rIDNextRID is the value of the last user * added by this DC, not the next available RID */ - (*rid) = prev_rid + 1; + if (prev_rid == 0) { + (*rid) = prev_alloc_pool_lo; + } else { + (*rid) = prev_rid + 1; + } + } + + if (*rid < prev_alloc_pool_lo || *rid > prev_alloc_pool_hi) { + ldb_asprintf_errstring(ldb, __location__ ": Bad rid chosen %u from range %u-%u", + (unsigned)*rid, (unsigned)prev_alloc_pool_lo, + (unsigned)prev_alloc_pool_hi); + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; } /* now modify the RID Set to use up this RID using a - * constrained delete/add */ - ret = dsdb_module_constrainted_update_integer(module, rid_set_dn, "rIDNextRID", prev_rid, *rid); + * constrained delete/add if possible */ + if (prev_rid == 0) { + ret = dsdb_module_set_integer(module, rid_set_dn, "rIDNextRID", *rid); + } else { + ret = dsdb_module_constrainted_update_integer(module, rid_set_dn, "rIDNextRID", prev_rid, *rid); + } talloc_free(tmp_ctx); return ret; -- cgit From dc11414f987aa99f286acb1d1ece625d290831f3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 16:47:11 +1100 Subject: s4-dsdb: send a message to the drepl task when we need another RID pool We send the message when the current pool is half gone. We don't wait for a reply. Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/ridalloc.c | 72 ++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 6 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index 02737dd88b..c3d334ff3a 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -31,6 +31,8 @@ #include "ldb_module.h" #include "dsdb/samdb/samdb.h" #include "dsdb/samdb/ldb_modules/util.h" +#include "lib/messaging/irpc.h" +#include "param/param.h" /* Note: the RID allocation attributes in AD are very badly named. Here @@ -280,7 +282,7 @@ static int ridalloc_create_own_rid_set(struct ldb_module *module, TALLOC_CTX *me } if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) { - ldb_asprintf_errstring(ldb, "Remote RID Set allocation not implemented"); + ldb_asprintf_errstring(ldb, "Remote RID Set allocation needs refresh"); talloc_free(tmp_ctx); return LDB_ERR_UNWILLING_TO_PERFORM; } @@ -345,6 +347,43 @@ static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module, } +/* + make a IRPC call to the drepl task to ask it to get the RID + Manager to give us another RID pool. + + This function just sends the message to the drepl task then + returns immediately. It should be called well before we + completely run out of RIDs + */ +static void ridalloc_poke_rid_manager(struct ldb_module *module) +{ + struct messaging_context *msg; + struct server_id *server; + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct loadparm_context *lp_ctx = ldb_get_opaque(ldb, "loadparm"); + TALLOC_CTX *tmp_ctx = talloc_new(module); + + msg = messaging_client_init(tmp_ctx, lp_messaging_path(tmp_ctx, lp_ctx), + lp_iconv_convenience(lp_ctx), + ldb_get_event_context(ldb)); + if (!msg) { + DEBUG(3,(__location__ ": Failed to create messaging context\n")); + talloc_free(tmp_ctx); + return; + } + + server = irpc_servers_byname(msg, msg, "dreplsrv"); + if (!server) { + /* this means the drepl service is not running */ + talloc_free(tmp_ctx); + return; + } + + messaging_send(msg, server[0], MSG_DREPL_ALLOCATE_RID, NULL); + + /* we don't care if the message got through */ + talloc_free(tmp_ctx); +} /* get a new RID pool for ourselves @@ -376,7 +415,7 @@ static int ridalloc_refresh_own_pool(struct ldb_module *module, uint64_t *new_po } if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) { - ldb_asprintf_errstring(ldb, "Remote RID Set allocation not implemented"); + ldb_asprintf_errstring(ldb, "Remote RID Set allocation needs refresh"); talloc_free(tmp_ctx); return LDB_ERR_UNWILLING_TO_PERFORM; } @@ -395,15 +434,17 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) { struct ldb_context *ldb; static const char * const attrs[] = { "rIDAllocationPool", "rIDPreviousAllocationPool", - "rIDNextRID" , NULL }; + "rIDNextRID" , "rIDUsedPool", NULL }; int ret; struct ldb_dn *rid_set_dn; struct ldb_result *res; uint64_t alloc_pool, prev_alloc_pool; uint32_t prev_alloc_pool_lo, prev_alloc_pool_hi; + uint32_t rid_used_pool; int prev_rid; TALLOC_CTX *tmp_ctx = talloc_new(module); + (*rid) = 0; ldb = ldb_module_get_ctx(module); ret = samdb_rid_set_dn(ldb, tmp_ctx, &rid_set_dn); @@ -428,6 +469,7 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) prev_alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDPreviousAllocationPool", 0); alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0); prev_rid = ldb_msg_find_attr_as_int(res->msgs[0], "rIDNextRID", 0); + rid_used_pool = ldb_msg_find_attr_as_int(res->msgs[0], "rIDUsedPool", 0); if (alloc_pool == 0) { ldb_asprintf_errstring(ldb, __location__ ": Bad RID Set %s", ldb_dn_get_linearized(rid_set_dn)); @@ -453,7 +495,19 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) prev_alloc_pool = alloc_pool; prev_alloc_pool_lo = prev_alloc_pool & 0xFFFFFFFF; prev_alloc_pool_hi = prev_alloc_pool >> 32; + + /* update the rIDUsedPool attribute */ + ret = dsdb_module_set_integer(module, rid_set_dn, "rIDUsedPool", rid_used_pool+1); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": Failed to update rIDUsedPool on %s - %s", + ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + (*rid) = prev_alloc_pool_lo; } + /* see if we are still out of RIDs, and if so then ask the RID Manager to give us more */ if (prev_rid >= prev_alloc_pool_hi) { @@ -477,9 +531,7 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) } else { /* despite the name, rIDNextRID is the value of the last user * added by this DC, not the next available RID */ - if (prev_rid == 0) { - (*rid) = prev_alloc_pool_lo; - } else { + if (*rid == 0) { (*rid) = prev_rid + 1; } } @@ -499,7 +551,15 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) } else { ret = dsdb_module_constrainted_update_integer(module, rid_set_dn, "rIDNextRID", prev_rid, *rid); } + + /* if we are half-exhausted then ask the repl task to start + * getting another one */ + if (*rid > (prev_alloc_pool_hi + prev_alloc_pool_lo)/2) { + ridalloc_poke_rid_manager(module); + } + talloc_free(tmp_ctx); + return ret; } -- cgit From 7a40cacbde0dc707ac2d354bfb335312f420da4b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 16:47:36 +1100 Subject: s4-dsdb: the dsdb ldb modules now need messagiing Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 38ea1483e9..7dfe58451f 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -1,7 +1,7 @@ ################################################ # Start SUBSYSTEM DSDB_MODULE_HELPERS [SUBSYSTEM::DSDB_MODULE_HELPERS] -PRIVATE_DEPENDENCIES = LIBLDB LIBNDR SAMDB_SCHEMA +PRIVATE_DEPENDENCIES = LIBLDB LIBNDR SAMDB_SCHEMA MESSAGING DSDB_MODULE_HELPERS_OBJ_FILES = \ $(dsdbsrcdir)/samdb/ldb_modules/util.o \ -- cgit From b1f97b7e60b68429f0a9c12de9cd1cf24b2d8d35 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 19:34:14 +1100 Subject: s4-dsdb: added an extended operation for allocating a new RID pool This will be called by getncchanges when a client asks for a DRSUAPI_EXOP_FSMO_RID_ALLOC operation Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/ridalloc.c | 90 +++++++++++++++++++++++++++++++ source4/dsdb/samdb/ldb_modules/samldb.c | 32 ++++++++++- source4/dsdb/samdb/samdb.h | 8 +++ 3 files changed, 129 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index c3d334ff3a..2d0753f393 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -33,6 +33,7 @@ #include "dsdb/samdb/ldb_modules/util.h" #include "lib/messaging/irpc.h" #include "param/param.h" +#include "librpc/gen_ndr/ndr_misc.h" /* Note: the RID allocation attributes in AD are very badly named. Here @@ -140,6 +141,7 @@ static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *m server_dn = ldb_dn_get_parent(tmp_ctx, ntds_dn); if (!server_dn) { ldb_module_oom(module); + talloc_free(tmp_ctx); return LDB_ERR_OPERATIONS_ERROR; } @@ -315,6 +317,7 @@ static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module, server_dn = ldb_dn_get_parent(tmp_ctx, ntds_dn); if (!server_dn) { ldb_module_oom(module); + talloc_free(tmp_ctx); return LDB_ERR_OPERATIONS_ERROR; } @@ -560,6 +563,93 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) talloc_free(tmp_ctx); + return ret; +} + + +/* + called by DSDB_EXTENDED_ALLOCATE_RID_POOL extended operation in samldb + */ +int ridalloc_allocate_rid_pool_fsmo(struct ldb_module *module, struct dsdb_fsmo_extended_op *exop) +{ + struct ldb_dn *ntds_dn, *server_dn, *machine_dn, *rid_set_dn; + struct ldb_dn *rid_manager_dn; + TALLOC_CTX *tmp_ctx = talloc_new(module); + int ret; + struct ldb_context *ldb = ldb_module_get_ctx(module); + uint64_t new_pool; + + ret = dsdb_module_dn_by_guid(module, tmp_ctx, &exop->destination_dsa_guid, &ntds_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": Unable to find NTDS object for guid %s - %s\n", + GUID_string(tmp_ctx, &exop->destination_dsa_guid), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + server_dn = ldb_dn_get_parent(tmp_ctx, ntds_dn); + if (!server_dn) { + ldb_module_oom(module); + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": Failed to find serverReference in %s - %s", + ldb_dn_get_linearized(server_dn), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + ret = dsdb_module_rid_manager_dn(module, tmp_ctx, &rid_manager_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": Failed to find RID Manager object - %s", + ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + ret = dsdb_module_reference_dn(module, tmp_ctx, machine_dn, "rIDSetReferences", &rid_set_dn); + if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { + ret = ridalloc_create_rid_set_ntds(module, tmp_ctx, rid_manager_dn, ntds_dn, &rid_set_dn); + talloc_free(tmp_ctx); + return ret; + } + + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to find rIDSetReferences in %s - %s", + ldb_dn_get_linearized(machine_dn), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + if (exop->fsmo_info != 0) { + const char *attrs[] = { "rIDAllocationPool", NULL }; + struct ldb_result *res; + uint64_t alloc_pool; + + ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_set_dn, attrs, 0); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": No RID Set %s", + ldb_dn_get_linearized(rid_set_dn)); + talloc_free(tmp_ctx); + return ret; + } + + alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0); + if (alloc_pool != exop->fsmo_info) { + /* it has already been updated */ + DEBUG(2,(__location__ ": rIDAllocationPool fsmo_info mismatch - already changed (0x%llx 0x%llx)\n", + (unsigned long long)exop->fsmo_info, + (unsigned long long)alloc_pool)); + talloc_free(tmp_ctx); + return LDB_SUCCESS; + } + } + + ret = ridalloc_refresh_rid_set_ntds(module, rid_manager_dn, ntds_dn, &new_pool); + talloc_free(tmp_ctx); return ret; } diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index eb83633fe2..79bfc0a15c 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -1860,11 +1860,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_extended(struct ldb_module *module, struct ldb_request *req) +{ + 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", .add = samldb_add, .modify = samldb_modify, - .del = samldb_delete + .del = samldb_delete, + .extended = samldb_extended }; diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h index a05aa00f7a..6df30b2904 100644 --- a/source4/dsdb/samdb/samdb.h +++ b/source4/dsdb/samdb/samdb.h @@ -142,4 +142,12 @@ struct dsdb_extended_dn_store_format { #define DSDB_OPAQUE_PARTITION_MODULE_MSG_OPAQUE_NAME "DSDB_OPAQUE_PARTITION_MODULE_MSG" +/* this takes a struct dsdb_fsmo_extended_op */ +#define DSDB_EXTENDED_ALLOCATE_RID_POOL "1.3.6.1.4.1.7165.4.4.5" + +struct dsdb_fsmo_extended_op { + uint64_t fsmo_info; + struct GUID destination_dsa_guid; +}; + #endif /* __SAMDB_H__ */ -- cgit From c4fa4d116264f661d9eaddc6c4e430de476cff83 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 7 Jan 2010 10:09:09 +1100 Subject: s4-dsdb: improve error messages in schema and pdc_fsmo modules We want to incorporate the error messages from the modules further down the stack. --- source4/dsdb/samdb/ldb_modules/pdc_fsmo.c | 4 ++-- source4/dsdb/samdb/ldb_modules/schema_load.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c b/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c index 796ecaf7bc..00d9a30fd3 100644 --- a/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c @@ -75,8 +75,8 @@ static int pdc_fsmo_init(struct ldb_module *module) return ldb_next_init(module); } else if (ret != LDB_SUCCESS) { ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "pdc_fsmo_init: failed to search the domain object: %d:%s", - ret, ldb_strerror(ret)); + "pdc_fsmo_init: failed to search the domain object: %d:%s: %s", + ret, ldb_strerror(ret), ldb_errstring(ldb)); talloc_free(mem_ctx); return ret; } diff --git a/source4/dsdb/samdb/ldb_modules/schema_load.c b/source4/dsdb/samdb/ldb_modules/schema_load.c index c72911fe89..6c11df21ce 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_load.c +++ b/source4/dsdb/samdb/ldb_modules/schema_load.c @@ -181,8 +181,8 @@ static int schema_load_init(struct ldb_module *module) ret = dsdb_set_schema(ldb, schema); if (ret != LDB_SUCCESS) { ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "schema_load_init: dsdb_set_schema() failed: %d:%s", - ret, ldb_strerror(ret)); + "schema_load_init: dsdb_set_schema() failed: %d:%s: %s", + ret, ldb_strerror(ret), ldb_errstring(ldb)); talloc_free(mem_ctx); return ret; } @@ -240,8 +240,8 @@ static int schema_load_extended(struct ldb_module *module, struct ldb_request *r ret = dsdb_set_schema(ldb, schema); if (ret != LDB_SUCCESS) { ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "schema_load_extended: dsdb_set_schema() failed: %d:%s", - ret, ldb_strerror(ret)); + "schema_load_extended: dsdb_set_schema() failed: %d:%s: %s", + ret, ldb_strerror(ret), ldb_errstring(ldb)); talloc_free(mem_ctx); return ret; } -- cgit From f7756c87bb8bd1eba8d7f92cfbc797db42d3de4a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 7 Jan 2010 10:22:26 +1100 Subject: s4-partition: don't ignore errors from other modules if we get an error code from a lower module, we don't want to ignore it just because something also succeeded --- source4/dsdb/samdb/ldb_modules/partition.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 01ae0a10a7..b879bc4106 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -39,7 +39,6 @@ struct part_request { struct partition_context { struct ldb_module *module; struct ldb_request *req; - bool got_success; struct part_request *part_req; int num_requests; @@ -160,7 +159,7 @@ static int partition_req_callback(struct ldb_request *req, } } - if (ares->error != LDB_SUCCESS && !ac->got_success) { + if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } @@ -182,9 +181,6 @@ static int partition_req_callback(struct ldb_request *req, return ldb_module_send_entry(ac->req, ares->message, ares->controls); case LDB_REPLY_DONE: - if (ares->error == LDB_SUCCESS) { - ac->got_success = true; - } if (ac->req->operation == LDB_EXTENDED) { /* FIXME: check for ares->response, replmd does not fill it ! */ if (ares->response) { @@ -205,7 +201,7 @@ static int partition_req_callback(struct ldb_request *req, /* this was the last one, call callback */ return ldb_module_done(ac->req, ares->controls, ares->response, - ac->got_success?LDB_SUCCESS:ares->error); + ares->error); } /* not the last, now call the next one */ -- cgit From 6247a135c68b592d99a8c1594aebe5ca7e716d7c Mon Sep 17 00:00:00 2001 From: Kamen Mazdrashki Date: Thu, 7 Jan 2010 04:01:14 +0200 Subject: s4/schema: Do not assign msDS-IntId value if LDB_CONTROL_RELAX_OID is passed This way msDS-IntId should not be assigned during provisioning, which is how Windows works --- source4/dsdb/samdb/ldb_modules/schema_data.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/schema_data.c b/source4/dsdb/samdb/ldb_modules/schema_data.c index 2e99113953..8125a46cbb 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_data.c +++ b/source4/dsdb/samdb/ldb_modules/schema_data.c @@ -290,6 +290,11 @@ 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) -- cgit From 5f36f0352e92243aa9f801d69ddc4c4152dfecbc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 7 Jan 2010 17:32:13 +1100 Subject: s4-dsdb: no longer need special invocationID handling for standalone servers They now work the same way as a DC --- source4/dsdb/samdb/ldb_modules/samba_dsdb.c | 77 +---------------------------- 1 file changed, 1 insertion(+), 76 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/samba_dsdb.c b/source4/dsdb/samdb/ldb_modules/samba_dsdb.c index a461a94806..44526128f1 100644 --- a/source4/dsdb/samdb/ldb_modules/samba_dsdb.c +++ b/source4/dsdb/samdb/ldb_modules/samba_dsdb.c @@ -138,53 +138,6 @@ static int prepare_modules_line(struct ldb_context *ldb, -/* - initialise the invocationID for a standalone server - */ -static int initialise_invocation_id(struct ldb_module *module, struct GUID *guid) -{ - struct ldb_message *msg; - struct ldb_context *ldb = ldb_module_get_ctx(module); - int ret; - - *guid = GUID_random(); - - msg = ldb_msg_new(module); - if (msg == NULL) { - ldb_module_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - msg->dn = ldb_dn_new(msg, ldb, "@SAMBA_DSDB"); - if (!msg->dn) { - ldb_module_oom(module); - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = dsdb_msg_add_guid(msg, guid, "invocationID"); - if (ret != LDB_SUCCESS) { - ldb_module_oom(module); - talloc_free(msg); - return ret; - } - msg->elements[0].flags = LDB_FLAG_MOD_ADD; - - ret = ldb_modify(ldb, msg); - if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, "Failed to setup standalone invocationID - %s", - ldb_errstring(ldb)); - talloc_free(msg); - return ret; - } - - DEBUG(1,("Initialised standalone invocationID to %s\n", - GUID_string(msg, guid))); - - talloc_free(msg); - - return LDB_SUCCESS; -} - - static int samba_dsdb_init(struct ldb_module *module) { struct ldb_context *ldb = ldb_module_get_ctx(module); @@ -258,7 +211,7 @@ static int samba_dsdb_init(struct ldb_module *module) static const char *openldap_backend_modules[] = { "entryuuid", "paged_searches", NULL }; - static const char *samba_dsdb_attrs[] = { "backendType", "serverRole", "invocationID", NULL }; + static const char *samba_dsdb_attrs[] = { "backendType", "serverRole", NULL }; const char *backendType, *serverRole; if (!tmp_ctx) { @@ -293,34 +246,6 @@ static int samba_dsdb_init(struct ldb_module *module) return ret; } - if (strcmp(serverRole, "standalone") == 0 || - strcmp(serverRole, "member server") == 0) { - struct GUID *guid; - - guid = talloc(module, struct GUID); - if (!guid) { - ldb_module_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - *guid = samdb_result_guid(res->msgs[0], "invocationID"); - if (GUID_all_zero(guid)) { - ret = initialise_invocation_id(module, guid); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return ret; - } - } - - /* cache the domain_sid in the ldb. See the matching - * code in samdb_ntds_invocation_id() */ - ret = ldb_set_opaque(ldb, "cache.invocation_id", guid); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return ret; - } - } - backend_modules = NULL; if (strcasecmp(backendType, "ldb") == 0) { extended_dn_module = extended_dn_module_ldb; -- cgit From 308a4798b8b6acc7f74ce678a7c04f536a3e4737 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 7 Jan 2010 18:15:34 +1100 Subject: s4-dsdb: added DSDB_FLAG_TOP_MODULE This is used when you want the dsdb_module_*() functions to go to the top of the stack. --- source4/dsdb/samdb/ldb_modules/util.c | 8 ++++++++ source4/dsdb/samdb/ldb_modules/util.h | 1 + 2 files changed, 9 insertions(+) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c index 12972eb185..b4f81978d3 100644 --- a/source4/dsdb/samdb/ldb_modules/util.c +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -214,6 +214,8 @@ int dsdb_module_search(struct ldb_module *module, if (dsdb_flags & DSDB_FLAG_OWN_MODULE) { const struct ldb_module_ops *ops = ldb_module_get_ops(module); ret = ops->search(module, req); + } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) { + ret = ldb_request(ldb_module_get_ctx(module), req); } else { ret = ldb_next_request(module, req); } @@ -332,6 +334,8 @@ int dsdb_module_modify(struct ldb_module *module, if (dsdb_flags & DSDB_FLAG_OWN_MODULE) { const struct ldb_module_ops *ops = ldb_module_get_ops(module); ret = ops->modify(module, mod_req); + } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) { + ret = ldb_request(ldb_module_get_ctx(module), mod_req); } else { ret = ldb_next_request(module, mod_req); } @@ -380,6 +384,8 @@ int dsdb_module_rename(struct ldb_module *module, if (dsdb_flags & DSDB_FLAG_OWN_MODULE) { const struct ldb_module_ops *ops = ldb_module_get_ops(module); ret = ops->rename(module, req); + } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) { + ret = ldb_request(ldb_module_get_ctx(module), req); } else { ret = ldb_next_request(module, req); } @@ -425,6 +431,8 @@ int dsdb_module_add(struct ldb_module *module, if (dsdb_flags & DSDB_FLAG_OWN_MODULE) { const struct ldb_module_ops *ops = ldb_module_get_ops(module); ret = ops->add(module, req); + } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) { + ret = ldb_request(ldb_module_get_ctx(module), req); } else { ret = ldb_next_request(module, req); } diff --git a/source4/dsdb/samdb/ldb_modules/util.h b/source4/dsdb/samdb/ldb_modules/util.h index add39e110a..608d2c26cb 100644 --- a/source4/dsdb/samdb/ldb_modules/util.h +++ b/source4/dsdb/samdb/ldb_modules/util.h @@ -32,3 +32,4 @@ struct dsdb_attribute; #define DSDB_SEARCH_SHOW_EXTENDED_DN 0x0010 #define DSDB_MODIFY_RELAX 0x0020 #define DSDB_FLAG_OWN_MODULE 0x0040 +#define DSDB_FLAG_TOP_MODULE 0x0080 -- cgit From a65823e33c8fab39ea6dde752662c527bcbf818b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 7 Jan 2010 18:16:14 +1100 Subject: s4-dsdb: ensure we will in all the attributes for RID Set We need to go to the top of the module stack so that all the extra attributes get filled in --- source4/dsdb/samdb/ldb_modules/ridalloc.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index 2d0753f393..07b3739f8e 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -175,26 +175,11 @@ static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *m msg = ldb_msg_new(tmp_ctx); msg->dn = rid_set_dn; - ret = ldb_msg_add_string(msg, "objectClass", "top"); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return ret; - } ret = ldb_msg_add_string(msg, "objectClass", "rIDSet"); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; } - ret = ldb_msg_add_string(msg, "cn", "RID Set"); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return ret; - } - ret = ldb_msg_add_string(msg, "name", "RID Set"); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return ret; - } ret = ldb_msg_add_fmt(msg, "rIDAllocationPool", "%llu", (unsigned long long)dc_pool); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); @@ -218,7 +203,10 @@ static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *m return ret; } - ret = dsdb_module_add(module, msg, 0); + /* we need this to go all the way to the top of the module + * stack, as we need all the extra attributes added (including + * complex ones like ntsecuritydescriptor) */ + ret = dsdb_module_add(module, msg, DSDB_FLAG_TOP_MODULE | DSDB_MODIFY_RELAX); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, "Failed to add RID Set %s - %s", ldb_dn_get_linearized(msg->dn), -- cgit From 2d10f3a84197a20fa7a6ff8305a69ac57ddd44e3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 7 Jan 2010 18:38:16 +1100 Subject: s4-dsdb: poke the RID Manager when completely out of RIDs too --- source4/dsdb/samdb/ldb_modules/ridalloc.c | 79 ++++++++++++++++--------------- 1 file changed, 41 insertions(+), 38 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index 07b3739f8e..a64062fcdc 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -55,6 +55,45 @@ */ +/* + make a IRPC call to the drepl task to ask it to get the RID + Manager to give us another RID pool. + + This function just sends the message to the drepl task then + returns immediately. It should be called well before we + completely run out of RIDs + */ +static void ridalloc_poke_rid_manager(struct ldb_module *module) +{ + struct messaging_context *msg; + struct server_id *server; + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct loadparm_context *lp_ctx = ldb_get_opaque(ldb, "loadparm"); + TALLOC_CTX *tmp_ctx = talloc_new(module); + + msg = messaging_client_init(tmp_ctx, lp_messaging_path(tmp_ctx, lp_ctx), + lp_iconv_convenience(lp_ctx), + ldb_get_event_context(ldb)); + if (!msg) { + DEBUG(3,(__location__ ": Failed to create messaging context\n")); + talloc_free(tmp_ctx); + return; + } + + server = irpc_servers_byname(msg, msg, "dreplsrv"); + if (!server) { + /* this means the drepl service is not running */ + talloc_free(tmp_ctx); + return; + } + + messaging_send(msg, server[0], MSG_DREPL_ALLOCATE_RID, NULL); + + /* we don't care if the message got through */ + talloc_free(tmp_ctx); +} + + /* allocate a new range of RIDs in the RID Manager object */ @@ -272,6 +311,7 @@ static int ridalloc_create_own_rid_set(struct ldb_module *module, TALLOC_CTX *me } if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) { + ridalloc_poke_rid_manager(module); ldb_asprintf_errstring(ldb, "Remote RID Set allocation needs refresh"); talloc_free(tmp_ctx); return LDB_ERR_UNWILLING_TO_PERFORM; @@ -338,44 +378,6 @@ static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module, } -/* - make a IRPC call to the drepl task to ask it to get the RID - Manager to give us another RID pool. - - This function just sends the message to the drepl task then - returns immediately. It should be called well before we - completely run out of RIDs - */ -static void ridalloc_poke_rid_manager(struct ldb_module *module) -{ - struct messaging_context *msg; - struct server_id *server; - struct ldb_context *ldb = ldb_module_get_ctx(module); - struct loadparm_context *lp_ctx = ldb_get_opaque(ldb, "loadparm"); - TALLOC_CTX *tmp_ctx = talloc_new(module); - - msg = messaging_client_init(tmp_ctx, lp_messaging_path(tmp_ctx, lp_ctx), - lp_iconv_convenience(lp_ctx), - ldb_get_event_context(ldb)); - if (!msg) { - DEBUG(3,(__location__ ": Failed to create messaging context\n")); - talloc_free(tmp_ctx); - return; - } - - server = irpc_servers_byname(msg, msg, "dreplsrv"); - if (!server) { - /* this means the drepl service is not running */ - talloc_free(tmp_ctx); - return; - } - - messaging_send(msg, server[0], MSG_DREPL_ALLOCATE_RID, NULL); - - /* we don't care if the message got through */ - talloc_free(tmp_ctx); -} - /* get a new RID pool for ourselves also returns the first rid for the new pool @@ -406,6 +408,7 @@ static int ridalloc_refresh_own_pool(struct ldb_module *module, uint64_t *new_po } if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) { + ridalloc_poke_rid_manager(module); ldb_asprintf_errstring(ldb, "Remote RID Set allocation needs refresh"); talloc_free(tmp_ctx); return LDB_ERR_UNWILLING_TO_PERFORM; -- cgit From 5d6032eb4b3e77240d2eccf7c644d1a30da89c78 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 09:00:15 +1100 Subject: s4-partition: fixed selection of partitions on exact match When a search is on the root of a partition on the global catalog, don't search partitions above that one. --- source4/dsdb/samdb/ldb_modules/partition.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index b879bc4106..59e7fab393 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -524,9 +524,7 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) */ if (ldb_dn_compare(data->partitions[i]->ctrl->dn, req->op.search.base) == 0) { match = true; - if (req->op.search.scope == LDB_SCOPE_BASE) { - stop = true; - } + stop = true; } if (!match && (ldb_dn_compare_base(req->op.search.base, data->partitions[i]->ctrl->dn) == 0 && -- cgit From d22a9e5d3bee44ac59922a2a602ad235bf450d5d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 09:28:38 +1100 Subject: s4-dsdb: squash some unknown structure warnings --- source4/dsdb/samdb/ldb_modules/util.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/util.h b/source4/dsdb/samdb/ldb_modules/util.h index 608d2c26cb..53ed9bd48e 100644 --- a/source4/dsdb/samdb/ldb_modules/util.h +++ b/source4/dsdb/samdb/ldb_modules/util.h @@ -19,9 +19,11 @@ along with this program. If not, see . */ -struct dsdb_schema; /* predeclare schema struct */ +/* predeclare some structures used by utility functions */ +struct dsdb_schema; struct GUID; struct dsdb_attribute; +struct dsdb_fsmo_extended_op; #include "dsdb/samdb/ldb_modules/util_proto.h" -- cgit From f118f54ee783a97ed2bc5415213f3145710e0b4c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 09:29:01 +1100 Subject: s4-dsdb: added dsdb_module_am_system() better than each module inventing their own --- source4/dsdb/samdb/ldb_modules/util.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c index b4f81978d3..46252cb279 100644 --- a/source4/dsdb/samdb/ldb_modules/util.c +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -26,6 +26,7 @@ #include "dsdb/samdb/ldb_modules/util.h" #include "dsdb/samdb/samdb.h" #include "util.h" +#include "libcli/security/security.h" /* add a set of controls to a ldb_request structure based on a set of @@ -629,3 +630,11 @@ int dsdb_module_set_integer(struct ldb_module *module, struct ldb_dn *dn, talloc_free(msg); return ret; } + +bool dsdb_module_am_system(struct ldb_module *module) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct auth_session_info *session_info + = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo"); + return security_session_user_level(session_info) == SECURITY_SYSTEM; +} -- cgit From 595fad2b34b6f67b130344bc741ff0ddffb0db4f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 09:29:32 +1100 Subject: s4-dsdb: allow specification of a SID if we are system needed for samba3sam test --- source4/dsdb/samdb/ldb_modules/samldb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 79bfc0a15c..edaf7251b8 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -901,7 +901,8 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type) /* 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)) { + 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; -- cgit From baa8793a94a05bd5fde0f2770d9a16959e01b60b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 09:30:31 +1100 Subject: s4-dsdb: use dsdb_module_am_system() in acl module --- source4/dsdb/samdb/ldb_modules/acl.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c index a3298362f3..aa66ec0d68 100644 --- a/source4/dsdb/samdb/ldb_modules/acl.c +++ b/source4/dsdb/samdb/ldb_modules/acl.c @@ -53,7 +53,7 @@ struct acl_private { struct acl_context { struct ldb_module *module; struct ldb_request *req; - enum security_user_level user_type; + bool am_system; bool allowedAttributes; bool allowedAttributesEffective; bool allowedChildClasses; @@ -70,14 +70,6 @@ bool is_root_base_dn(struct ldb_context *ldb, struct ldb_dn *dn_to_check) return (result==0); } -static enum security_user_level what_is_user(struct ldb_module *module) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - struct auth_session_info *session_info - = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo"); - return security_session_user_level(session_info); -} - static struct security_token *acl_user_token(struct ldb_module *module) { struct ldb_context *ldb = ldb_module_get_ctx(module); @@ -450,7 +442,7 @@ static int acl_allowedAttributes(struct ldb_module *module, struct ldb_control *as_system = ldb_request_get_control(ac->req, LDB_CONTROL_AS_SYSTEM_OID); ldb_msg_remove_attr(msg, "allowedAttributesEffective"); - if (ac->user_type == SECURITY_SYSTEM || as_system) { + if (ac->am_system || as_system) { for (i=0; attr_list && attr_list[i]; i++) { ldb_msg_add_string(msg, "allowedAttributesEffective", attr_list[i]); } @@ -566,7 +558,7 @@ static int acl_childClassesEffective(struct ldb_module *module, struct dom_sid *sid = NULL; int i, j, ret; - if (ac->user_type == SECURITY_SYSTEM || as_system) { + if (ac->am_system || as_system) { return acl_childClasses(module, sd_msg, msg, "allowedChildClassesEffective"); } @@ -650,7 +642,7 @@ static int acl_sDRightsEffective(struct ldb_module *module, if (ret != LDB_SUCCESS) { return ret; } - if (ac->user_type == SECURITY_SYSTEM || as_system) { + if (ac->am_system || as_system) { flags = SECINFO_OWNER | SECINFO_GROUP | SECINFO_SACL | SECINFO_DACL; } else { @@ -707,7 +699,7 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req) struct object_tree *new_node = NULL; struct ldb_control *as_system = ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID); - if (what_is_user(module) == SECURITY_SYSTEM || as_system) { + if (dsdb_module_am_system(module) || as_system) { return ldb_next_request(module, req); } @@ -773,7 +765,7 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) { DEBUG(10, ("ldb:acl_modify: %s\n", req->op.mod.message->elements[0].name)); } - if (what_is_user(module) == SECURITY_SYSTEM || as_system) { + if (dsdb_module_am_system(module) || as_system) { return ldb_next_request(module, req); } if (ldb_dn_is_special(req->op.mod.message->dn)) { @@ -901,7 +893,7 @@ static int acl_delete(struct ldb_module *module, struct ldb_request *req) struct ldb_control *as_system = ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID); DEBUG(10, ("ldb:acl_delete: %s\n", ldb_dn_get_linearized(req->op.del.dn))); - if (what_is_user(module) == SECURITY_SYSTEM || as_system) { + if (dsdb_module_am_system(module) || as_system) { return ldb_next_request(module, req); } @@ -955,7 +947,7 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req) }; DEBUG(10, ("ldb:acl_rename: %s\n", ldb_dn_get_linearized(req->op.rename.olddn))); - if (what_is_user(module) == SECURITY_SYSTEM || as_system) { + if (dsdb_module_am_system(module) || as_system) { return ldb_next_request(module, req); } if (ldb_dn_is_special(req->op.rename.olddn)) { @@ -1135,7 +1127,7 @@ static int acl_search_callback(struct ldb_request *req, struct ldb_reply *ares) } } if (data && data->password_attrs) { - if (ac->user_type != SECURITY_SYSTEM) { + if (!ac->am_system) { for (i = 0; data->password_attrs[i]; i++) { ldb_msg_remove_attr(ares->message, data->password_attrs[i]); } @@ -1173,7 +1165,7 @@ static int acl_search(struct ldb_module *module, struct ldb_request *req) ac->module = module; ac->req = req; - ac->user_type = what_is_user(module); + ac->am_system = dsdb_module_am_system(module); ac->allowedAttributes = ldb_attr_in_list(req->op.search.attrs, "allowedAttributes"); ac->allowedAttributesEffective = ldb_attr_in_list(req->op.search.attrs, "allowedAttributesEffective"); ac->allowedChildClasses = ldb_attr_in_list(req->op.search.attrs, "allowedChildClasses"); @@ -1183,7 +1175,7 @@ static int acl_search(struct ldb_module *module, struct ldb_request *req) /* replace any attributes in the parse tree that are private, so we don't allow a search for 'userPassword=penguin', just as we would not allow that attribute to be returned */ - if (ac->user_type != SECURITY_SYSTEM) { + if (ac->am_system) { /* FIXME: We should copy the tree and keep the original unmodified. */ /* remove password attributes */ if (data && data->password_attrs) { -- cgit From 8b8bb15a54a80b8a568f9da955a33ff8336168ee Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 09:30:59 +1100 Subject: s4-dsdb: fixed const misuse in acl module --- source4/dsdb/samdb/ldb_modules/acl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c index aa66ec0d68..a779821107 100644 --- a/source4/dsdb/samdb/ldb_modules/acl.c +++ b/source4/dsdb/samdb/ldb_modules/acl.c @@ -35,10 +35,10 @@ #include "ldb_module.h" #include "auth/auth.h" #include "libcli/security/security.h" -#include "librpc/gen_ndr/ndr_security.h" #include "dsdb/samdb/samdb.h" #include "librpc/gen_ndr/ndr_security.h" #include "param/param.h" +#include "dsdb/samdb/ldb_modules/util.h" struct extended_access_check_attribute { const char *oa_name; @@ -301,7 +301,7 @@ static int acl_check_access_on_attribute(struct ldb_module *module, struct security_descriptor *sd, struct dom_sid *rp_sid, uint32_t access, - struct dsdb_attribute *attr) + const struct dsdb_attribute *attr) { int ret; NTSTATUS status; @@ -362,7 +362,7 @@ static int acl_check_access_on_class(struct ldb_module *module, uint32_t access_granted; struct object_tree *root = NULL; struct object_tree *new_node = NULL; - struct GUID *guid; + const struct GUID *guid; const struct dsdb_schema *schema = dsdb_get_schema(ldb); TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); struct security_token *token = acl_user_token(module); @@ -460,7 +460,7 @@ static int acl_allowedAttributes(struct ldb_module *module, return ret; } for (i=0; attr_list && attr_list[i]; i++) { - struct dsdb_attribute *attr = dsdb_attribute_by_lDAPDisplayName(schema, + const struct dsdb_attribute *attr = dsdb_attribute_by_lDAPDisplayName(schema, attr_list[i]); if (!attr) { return LDB_ERR_OPERATIONS_ERROR; -- cgit From 43a815c67ac7b7406b047b488393fa42617a5884 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 09:31:23 +1100 Subject: s4-samba3samtest: use system credentials for creating users --- source4/dsdb/samdb/ldb_modules/tests/samba3sam.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py index 2478043eb4..a46afb1a72 100644 --- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py +++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py @@ -29,6 +29,7 @@ from samba import Ldb, substitute_var from samba.tests import LdbTestCase, TestCaseInTempDir, cmdline_loadparm import samba.dcerpc.security import samba.ndr +from samba.auth import system_session datadir = os.path.join(os.path.dirname(__file__), "../../../../../testdata/samba3") @@ -75,7 +76,7 @@ class MapBaseTestCase(TestCaseInTempDir): """Simple helper class that contains data for a specific SAM connection.""" def __init__(self, basedn, dn): - self.db = Ldb(lp=cmdline_loadparm) + self.db = Ldb(lp=cmdline_loadparm, session_info=system_session()) self.basedn = basedn self.basedn_casefold = ldb.Dn(self.db, basedn).get_casefold() self.substvars = {"BASEDN": self.basedn} @@ -124,13 +125,13 @@ class Samba3SamTestCase(MapBaseTestCase): def setUp(self): super(Samba3SamTestCase, self).setUp() - ldb = Ldb(self.ldburl, lp=cmdline_loadparm) + ldb = Ldb(self.ldburl, lp=cmdline_loadparm, session_info=system_session()) self.samba3.setup_data("samba3.ldif") ldif = read_datafile("provision_samba3sam.ldif") ldb.add_ldif(self.samba4.subst(ldif)) self.setup_modules(ldb, self.samba3, self.samba4) del ldb - self.ldb = Ldb(self.ldburl, lp=cmdline_loadparm) + self.ldb = Ldb(self.ldburl, lp=cmdline_loadparm, session_info=system_session()) def test_search_non_mapped(self): """Looking up by non-mapped attribute""" @@ -291,12 +292,12 @@ class MapTestCase(MapBaseTestCase): def setUp(self): super(MapTestCase, self).setUp() - ldb = Ldb(self.ldburl, lp=cmdline_loadparm) + ldb = Ldb(self.ldburl, lp=cmdline_loadparm, session_info=system_session()) ldif = read_datafile("provision_samba3sam.ldif") ldb.add_ldif(self.samba4.subst(ldif)) self.setup_modules(ldb, self.samba3, self.samba4) del ldb - self.ldb = Ldb(self.ldburl, lp=cmdline_loadparm) + self.ldb = Ldb(self.ldburl, lp=cmdline_loadparm, session_info=system_session()) def test_map_search(self): """Running search tests on mapped data.""" -- cgit From dd61336165396f8aaccde1320de26bae789fb324 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 12:14:39 +1100 Subject: s4-dsdb: added a samba3sid module This module allocates SIDs using the Samba3 algorithm, for use with the samba3sam module. Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/config.mk | 15 ++- source4/dsdb/samdb/ldb_modules/samba3sid.c | 194 +++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 source4/dsdb/samdb/ldb_modules/samba3sid.c (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 7dfe58451f..f9f1714358 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -137,12 +137,25 @@ SUBSYSTEM = LIBLDB INIT_FUNCTION = LDB_MODULE(samba3sam) PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBLDB SMBPASSWD \ NSS_WRAPPER LIBSECURITY NDR_SECURITY -# End MODULE ldb_samldb +# End MODULE ldb_samba3sam ################################################ ldb_samba3sam_OBJ_FILES = \ $(dsdbsrcdir)/samdb/ldb_modules/samba3sam.o +################################################ +# Start MODULE ldb_samba3sid +[MODULE::ldb_samba3sid] +SUBSYSTEM = LIBLDB +INIT_FUNCTION = LDB_MODULE(samba3sid) +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBLDB SMBPASSWD \ + NSS_WRAPPER LIBSECURITY NDR_SECURITY +# End MODULE ldb_samba3sid +################################################ + +ldb_samba3sid_OBJ_FILES = \ + $(dsdbsrcdir)/samdb/ldb_modules/samba3sid.o + ################################################ # Start MODULE ldb_simple_ldap_map [MODULE::ldb_simple_ldap_map] diff --git a/source4/dsdb/samdb/ldb_modules/samba3sid.c b/source4/dsdb/samdb/ldb_modules/samba3sid.c new file mode 100644 index 0000000000..6ea5742e6d --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/samba3sid.c @@ -0,0 +1,194 @@ +/* + samba3sid module + + Copyright (C) Andrew Bartlett 2010 + Copyright (C) Andrew Tridgell 2010 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + add objectSID to users and groups using samba3 nextRid method + */ + +#include "includes.h" +#include "libcli/ldap/ldap_ndr.h" +#include "ldb_module.h" +#include "dsdb/samdb/samdb.h" +#include "dsdb/samdb/ldb_modules/util.h" +#include "libcli/security/security.h" +#include "librpc/gen_ndr/ndr_security.h" +#include "../lib/util/util_ldb.h" +#include "ldb_wrap.h" +#include "param/param.h" + +/* + RID algorithm from pdb_ldap.c in source3/passdb/ + (loosely based on Volkers code) + */ +static int samba3sid_next_sid(struct ldb_module *module, + TALLOC_CTX *mem_ctx, char **sid) +{ + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + struct ldb_result *res; + const char *attrs[] = { "sambaNextRid", "sambaNextUserRid", + "sambaNextGroupRid", "sambaSID", NULL }; + int ret; + struct ldb_context *ldb = ldb_module_get_ctx(module); + int sambaNextRid, sambaNextGroupRid, sambaNextUserRid; + struct ldb_message *msg; + uint32_t rid; + const char *sambaSID; + + ret = dsdb_module_search(module, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE, + attrs, DSDB_SEARCH_SEARCH_ALL_PARTITIONS, + "(&(objectClass=sambaDomain)(sambaDomainName=%s))", + lp_sam_name(ldb_get_opaque(ldb, "loadparm"))); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + __location__ + ": Failed to find domain object - %s", + ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + if (res->count != 1) { + ldb_asprintf_errstring(ldb, + __location__ + ": Expected exactly 1 domain object - got %u", + res->count); + talloc_free(tmp_ctx); + return ret; + } + msg = res->msgs[0]; + + sambaNextRid = ldb_msg_find_attr_as_uint(msg, "sambaNextRid", -1); + sambaNextUserRid = ldb_msg_find_attr_as_uint(msg, "sambaNextUserRid", -1); + sambaNextGroupRid = ldb_msg_find_attr_as_uint(msg, "sambaNextGroupRid", -1); + sambaSID = ldb_msg_find_attr_as_string(msg, "sambaSID", NULL); + + if (sambaSID == NULL) { + ldb_asprintf_errstring(ldb, + __location__ + ": No sambaSID in %s", + ldb_dn_get_linearized(msg->dn)); + talloc_free(tmp_ctx); + return ret; + } + + /* choose the highest of the 3 - see pdb_ldap.c for an + * explanation */ + rid = sambaNextRid; + if (sambaNextUserRid > rid) { + rid = sambaNextUserRid; + } + if (sambaNextGroupRid > rid) { + rid = sambaNextGroupRid; + } + if (rid == -1) { + ldb_asprintf_errstring(ldb, + __location__ + ": No sambaNextRid in %s", + ldb_dn_get_linearized(msg->dn)); + talloc_free(tmp_ctx); + return ret; + } + + (*sid) = talloc_asprintf(tmp_ctx, "%s-%u", sambaSID, rid); + if (!*sid) { + ldb_module_oom(module); + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = dsdb_module_constrainted_update_integer(module, msg->dn, + "sambaNextRid", + sambaNextRid, rid+1); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + __location__ + ": Failed to update sambaNextRid - %s", + ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + talloc_steal(mem_ctx, *sid); + talloc_free(tmp_ctx); + return LDB_SUCCESS; +} + + + +/* add */ +static int samba3sid_add(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + int ret; + const struct ldb_message *msg = req->op.add.message; + struct ldb_message *new_msg; + char *sid; + struct ldb_request *new_req; + + ldb = ldb_module_get_ctx(module); + + /* do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.add.message->dn)) { + return ldb_next_request(module, req); + } + + if (!samdb_find_attribute(ldb, msg, "objectclass", "posixAccount") && + !samdb_find_attribute(ldb, msg, "objectclass", "posixGroup")) { + /* its not a user or a group */ + return ldb_next_request(module, req); + } + + if (ldb_msg_find_element(msg, "sambaSID")) { + /* a SID was supplied */ + return ldb_next_request(module, req); + } + + new_msg = ldb_msg_copy_shallow(req, req->op.add.message); + if (!new_msg) { + ldb_module_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = samba3sid_next_sid(module, new_msg, &sid); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_msg_add_steal_string(new_msg, "sambaSID", sid); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_build_add_req(&new_req, ldb, req, + new_msg, + req->controls, + req, dsdb_next_callback, + req); + if (ret != LDB_SUCCESS) { + return ret; + } + + return ldb_next_request(module, new_req); +} + +_PUBLIC_ const struct ldb_module_ops ldb_samba3sid_module_ops = { + .name = "samba3sid", + .add = samba3sid_add, +}; + -- cgit From d6f92db456162571e7d9273afe371103da72e6b0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 12:15:01 +1100 Subject: s4-samba3sam: use samba3sid module Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/tests/samba3sam.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py index a46afb1a72..8d4047b0b8 100644 --- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py +++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py @@ -30,6 +30,7 @@ from samba.tests import LdbTestCase, TestCaseInTempDir, cmdline_loadparm import samba.dcerpc.security import samba.ndr from samba.auth import system_session +from samba import param datadir = os.path.join(os.path.dirname(__file__), "../../../../../testdata/samba3") @@ -50,7 +51,7 @@ class MapBaseTestCase(TestCaseInTempDir): "@TO": "sambaDomainName=TESTS," + s3.basedn}) ldb.add({"dn": "@MODULES", - "@LIST": "rootdse,paged_results,server_sort,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,partition"}) + "@LIST": "rootdse,paged_results,server_sort,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,samba3sid,partition"}) ldb.add({"dn": "@PARTITION", "partition": ["%s" % (s4.basedn_casefold), @@ -59,6 +60,7 @@ class MapBaseTestCase(TestCaseInTempDir): "modules": "*:"}) def setUp(self): + cmdline_loadparm.set("sid generator", "backend") super(MapBaseTestCase, self).setUp() def make_dn(basedn, rdn): -- cgit From f68c43e80338921be8145f8b3a3b391a941715a2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 12:45:29 +1100 Subject: s4-samba3sid: the sambaNextRid attribute is actually the previous RID Not well named .... though same mistake that MS made with rIDNextRid --- source4/dsdb/samdb/ldb_modules/samba3sid.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/samba3sid.c b/source4/dsdb/samdb/ldb_modules/samba3sid.c index 6ea5742e6d..bb4b58be3f 100644 --- a/source4/dsdb/samdb/ldb_modules/samba3sid.c +++ b/source4/dsdb/samdb/ldb_modules/samba3sid.c @@ -48,7 +48,7 @@ static int samba3sid_next_sid(struct ldb_module *module, struct ldb_context *ldb = ldb_module_get_ctx(module); int sambaNextRid, sambaNextGroupRid, sambaNextUserRid; struct ldb_message *msg; - uint32_t rid; + int rid; const char *sambaSID; ret = dsdb_module_search(module, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE, @@ -105,7 +105,10 @@ static int samba3sid_next_sid(struct ldb_module *module, return ret; } - (*sid) = talloc_asprintf(tmp_ctx, "%s-%u", sambaSID, rid); + /* sambaNextRid is actually the previous RID .... */ + rid += 1; + + (*sid) = talloc_asprintf(tmp_ctx, "%s-%d", sambaSID, rid); if (!*sid) { ldb_module_oom(module); talloc_free(tmp_ctx); @@ -114,7 +117,7 @@ static int samba3sid_next_sid(struct ldb_module *module, ret = dsdb_module_constrainted_update_integer(module, msg->dn, "sambaNextRid", - sambaNextRid, rid+1); + sambaNextRid, rid); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, __location__ -- cgit From 9aed0993624ecd42ad68b3b080668fa07a9bc1b9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 12:45:49 +1100 Subject: s4-samba3samtest: force workgroup so the domain is right the samba3sid backend looks at lp_sam_name() which is based on the workgroup --- source4/dsdb/samdb/ldb_modules/tests/samba3sam.py | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py index 8d4047b0b8..78b7eca077 100644 --- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py +++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py @@ -61,6 +61,7 @@ class MapBaseTestCase(TestCaseInTempDir): def setUp(self): cmdline_loadparm.set("sid generator", "backend") + cmdline_loadparm.set("workgroup", "TESTS") super(MapBaseTestCase, self).setUp() def make_dn(basedn, rdn): -- cgit From dde2b66341d5addbb80a239b8ccab58af1f3fc24 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 12:54:42 +1100 Subject: s4-samba3sid: fixed error returns when res->count != 1 and oom --- source4/dsdb/samdb/ldb_modules/samba3sid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/samba3sid.c b/source4/dsdb/samdb/ldb_modules/samba3sid.c index bb4b58be3f..76848eb258 100644 --- a/source4/dsdb/samdb/ldb_modules/samba3sid.c +++ b/source4/dsdb/samdb/ldb_modules/samba3sid.c @@ -69,7 +69,7 @@ static int samba3sid_next_sid(struct ldb_module *module, ": Expected exactly 1 domain object - got %u", res->count); talloc_free(tmp_ctx); - return ret; + return LDB_ERR_OPERATIONS_ERROR; } msg = res->msgs[0]; @@ -84,7 +84,7 @@ static int samba3sid_next_sid(struct ldb_module *module, ": No sambaSID in %s", ldb_dn_get_linearized(msg->dn)); talloc_free(tmp_ctx); - return ret; + return LDB_ERR_OPERATIONS_ERROR; } /* choose the highest of the 3 - see pdb_ldap.c for an @@ -102,7 +102,7 @@ static int samba3sid_next_sid(struct ldb_module *module, ": No sambaNextRid in %s", ldb_dn_get_linearized(msg->dn)); talloc_free(tmp_ctx); - return ret; + return LDB_ERR_OPERATIONS_ERROR; } /* sambaNextRid is actually the previous RID .... */ -- cgit From 5ccf8ae37385bd401910e7c31c63fad43dcc89ae Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Jan 2010 12:55:21 +1100 Subject: s4-samba3samtest: we need to force netbios name as well needed for when run in CLIENT context --- source4/dsdb/samdb/ldb_modules/tests/samba3sam.py | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py index 78b7eca077..cc1a86ed4a 100644 --- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py +++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py @@ -62,6 +62,7 @@ class MapBaseTestCase(TestCaseInTempDir): def setUp(self): cmdline_loadparm.set("sid generator", "backend") cmdline_loadparm.set("workgroup", "TESTS") + cmdline_loadparm.set("netbios name", "TESTS") super(MapBaseTestCase, self).setUp() def make_dn(basedn, rdn): -- cgit From 93fefefea85808eeeb58294133bd608490a89c86 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 9 Jan 2010 20:58:07 +1100 Subject: s4-samldb: fixed primaryGroupID when promoting a machine to a DC The machine gets a primaryGroupID of DOMAIN_RID_DCS. This is done without changing the member attributes of its groups. --- source4/dsdb/samdb/ldb_modules/samldb.c | 47 +++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index edaf7251b8..ccf76aaef2 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -786,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; @@ -1782,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; @@ -1809,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"); -- cgit From c03a101e6d410df68454f46c9e4d88f46fc2fa1a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 9 Jan 2010 22:08:25 +1100 Subject: s4-drs: instanceType is always sent, regardless of UDV values --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 890eb91d6d..394ce3e637 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -2667,10 +2667,12 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar) break; } - DEBUG(1,("Discarding older DRS attribute update to %s on %s from %s\n", - msg->elements[i-removed_attrs].name, - ldb_dn_get_linearized(msg->dn), - GUID_string(ar, &rmd->ctr.ctr1.array[i].originating_invocation_id))); + if (rmd->ctr.ctr1.array[i].attid != DRSUAPI_ATTRIBUTE_instanceType) { + DEBUG(1,("Discarding older DRS attribute update to %s on %s from %s\n", + msg->elements[i-removed_attrs].name, + ldb_dn_get_linearized(msg->dn), + GUID_string(ar, &rmd->ctr.ctr1.array[i].originating_invocation_id))); + } /* we don't want to apply this change so remove the attribute */ ldb_msg_remove_element(msg, &msg->elements[i-removed_attrs]); -- cgit From 601ea3a442ba20fe16797953e946d7a113c9b635 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Sun, 10 Jan 2010 19:49:40 +0100 Subject: s4:repl_meta_data - Transform a "1" into a "true" on a boolean variable --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 394ce3e637..b4caac4c8d 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -672,7 +672,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) /* check if there's a show relax control (used by provision to say 'I know what I'm doing') */ control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); if (control) { - allow_add_guid = 1; + allow_add_guid = true; } /* do not manipulate our control entries */ -- cgit