*/
+/*
+ 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 =
+ (struct loadparm_context *)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),
+ 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);
+}
+
+
+static const char * const ridalloc_ridset_attrs[] = {
+ "rIDAllocationPool",
+ "rIDPreviousAllocationPool",
+ "rIDNextRID",
+ "rIDUsedPool",
+ NULL
+};
+
+struct ridalloc_ridset_values {
+ uint64_t alloc_pool;
+ uint64_t prev_pool;
+ uint32_t next_rid;
+ uint32_t used_pool;
+};
+
+static void ridalloc_get_ridset_values(struct ldb_message *msg, struct ridalloc_ridset_values *v)
+{
+ v->alloc_pool = ldb_msg_find_attr_as_uint64(msg, "rIDAllocationPool", UINT64_MAX);
+ v->prev_pool = ldb_msg_find_attr_as_uint64(msg, "rIDPreviousAllocationPool", UINT64_MAX);
+ v->next_rid = ldb_msg_find_attr_as_uint(msg, "rIDNextRID", UINT32_MAX);
+ v->used_pool = ldb_msg_find_attr_as_uint(msg, "rIDUsedPool", UINT32_MAX);
+}
+
+static int ridalloc_set_ridset_values(struct ldb_module *module,
+ struct ldb_message *msg,
+ const struct ridalloc_ridset_values *o,
+ const struct ridalloc_ridset_values *n)
+{
+ const uint32_t *o32, *n32;
+ const uint64_t *o64, *n64;
+ int ret;
+
+#define SETUP_PTRS(field, optr, nptr, max) do { \
+ optr = &o->field; \
+ nptr = &n->field; \
+ if (o->field == max) { \
+ optr = NULL; \
+ } \
+ if (n->field == max) { \
+ nptr = NULL; \
+ } \
+ if (o->field == n->field) { \
+ optr = NULL; \
+ nptr = NULL; \
+ } \
+} while(0)
+
+ SETUP_PTRS(alloc_pool, o64, n64, UINT64_MAX);
+ ret = dsdb_msg_constrainted_update_uint64(module, msg,
+ "rIDAllocationPool",
+ o64, n64);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ SETUP_PTRS(prev_pool, o64, n64, UINT64_MAX);
+ ret = dsdb_msg_constrainted_update_uint64(module, msg,
+ "rIDPreviousAllocationPool",
+ o64, n64);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ SETUP_PTRS(next_rid, o32, n32, UINT32_MAX);
+ ret = dsdb_msg_constrainted_update_uint32(module, msg,
+ "rIDNextRID",
+ o32, n32);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ SETUP_PTRS(used_pool, o32, n32, UINT32_MAX);
+ ret = dsdb_msg_constrainted_update_uint32(module, msg,
+ "rIDUsedPool",
+ o32, n32);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+#undef SETUP_PTRS
+
+ return LDB_SUCCESS;
+}
+
/*
allocate a new range of RIDs in the RID Manager object
*/
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);
+ ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_manager_dn,
+ attrs, DSDB_FLAG_NEXT_MODULE);
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));
/* 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);
+ ret = dsdb_module_constrainted_update_uint64(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));
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;
+ return ldb_module_oom(module);
}
ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn);
rid_set_dn = ldb_dn_copy(tmp_ctx, machine_dn);
if (rid_set_dn == NULL) {
- ldb_module_oom(module);
- return LDB_ERR_OPERATIONS_ERROR;
+ talloc_free(tmp_ctx);
+ return ldb_module_oom(module);
}
if (! ldb_dn_add_child_fmt(rid_set_dn, "CN=RID Set")) {
- ldb_module_oom(module);
- return LDB_ERR_OPERATIONS_ERROR;
+ talloc_free(tmp_ctx);
+ return ldb_module_oom(module);
}
/* grab a pool from the RID Manager object */
}
msg->elements[0].flags = LDB_FLAG_MOD_ADD;
- ret = dsdb_module_modify(module, msg, 0);
+ ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE);
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb, "Failed to add rIDSetReferences to %s - %s",
ldb_dn_get_linearized(msg->dn),
}
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;
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;
+ return ldb_module_oom(module);
}
ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn);
}
-/*
- 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
}
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;
return ret;
}
- ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_set_dn, attrs, 0);
+ ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_set_dn,
+ attrs, DSDB_FLAG_NEXT_MODULE);
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb, __location__ ": No RID Set %s",
ldb_dn_get_linearized(rid_set_dn));
prev_alloc_pool_lo = prev_alloc_pool & 0xFFFFFFFF;
prev_alloc_pool_hi = prev_alloc_pool >> 32;
- /* update the rIDUsedPool attribute */
+ /*
+ * update the rIDUsedPool attribute
+ *
+ * Note: w2k8r2 doesn't update this attribute,
+ * at least if it's itself the rid master.
+ */
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",
uint64_t new_pool;
ret = ridalloc_refresh_own_pool(module, &new_pool);
if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
return ret;
}
ret = dsdb_module_constrainted_update_integer(module, rid_set_dn, "rIDPreviousAllocationPool",
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;
+ return ldb_module_oom(module);
}
ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn);
struct ldb_result *res;
uint64_t alloc_pool;
- ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_set_dn, attrs, 0);
+ ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_set_dn,
+ attrs, DSDB_FLAG_NEXT_MODULE);
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb, __location__ ": No RID Set %s",
ldb_dn_get_linearized(rid_set_dn));