summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb/ldb_modules/ridalloc.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2010-01-05 18:23:46 +1100
committerAndrew Tridgell <tridge@samba.org>2010-01-08 13:02:58 +1100
commit226460d543892fcfcb569297bc450648f4fc4f0f (patch)
tree0689f2dec05d6f54b35beabf0fdf0447b38f74c3 /source4/dsdb/samdb/ldb_modules/ridalloc.c
parent7f90a05c66df5483e949b109b9018ee70b9c5d27 (diff)
downloadsamba-226460d543892fcfcb569297bc450648f4fc4f0f.tar.gz
samba-226460d543892fcfcb569297bc450648f4fc4f0f.tar.bz2
samba-226460d543892fcfcb569297bc450648f4fc4f0f.zip
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>
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules/ridalloc.c')
-rw-r--r--source4/dsdb/samdb/ldb_modules/ridalloc.c140
1 files changed, 140 insertions, 0 deletions
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 <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;
+}