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') 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