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:
parent
7f90a05c66
commit
226460d543
@ -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)))
|
||||
|
||||
|
140
source4/dsdb/samdb/ldb_modules/ridalloc.c
Normal file
140
source4/dsdb/samdb/ldb_modules/ridalloc.c
Normal 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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user