1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

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 <abartlet@samba.org>
This commit is contained in:
Andrew Tridgell 2010-01-05 18:23:46 +11:00
parent 7f90a05c66
commit 226460d543
3 changed files with 148 additions and 89 deletions

View File

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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/*
* 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;
}

View File

@ -344,108 +344,25 @@ 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;
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
ldb = ldb_module_get_ctx(ac->module);
ret = samdb_rid_set_dn(ldb, tmp_ctx, &rid_set_dn);
ret = ridalloc_allocate_rid(ac->module, &rid);
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb, __location__ ": No RID Set DN");
talloc_free(tmp_ctx);
return ret;
}
ret = dsdb_module_search_dn(ac->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 */
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);
ldb_module_oom(ac->module);
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);
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);
}