2 RID allocation helper functions
4 Copyright (C) Andrew Bartlett 2010
5 Copyright (C) Andrew Tridgell 2010
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 * Component: RID allocation logic
26 * Description: manage RID Set and RID Manager objects
31 #include "ldb_module.h"
32 #include "dsdb/samdb/samdb.h"
33 #include "dsdb/samdb/ldb_modules/util.h"
34 #include "lib/messaging/irpc.h"
35 #include "param/param.h"
36 #include "librpc/gen_ndr/ndr_misc.h"
39 Note: the RID allocation attributes in AD are very badly named. Here
40 is what we think they really do:
43 - rIDPreviousAllocationPool: the pool which a DC is currently
44 pulling RIDs from. Managed by client DC
46 - rIDAllocationPool: the pool that the DC will switch to next,
47 when rIDPreviousAllocationPool is exhausted. Managed by RID Manager.
49 - rIDNextRID: the last RID allocated by this DC. Managed by client DC
51 in RID Manager object:
52 - rIDAvailablePool: the pool where the RID Manager gets new rID
53 pools from when it gets a EXOP_RID_ALLOC getncchanges call (or
54 locally when the DC is the RID Manager)
59 make a IRPC call to the drepl task to ask it to get the RID
60 Manager to give us another RID pool.
62 This function just sends the message to the drepl task then
63 returns immediately. It should be called well before we
64 completely run out of RIDs
66 static void ridalloc_poke_rid_manager(struct ldb_module *module)
68 struct messaging_context *msg;
69 struct server_id *server;
70 struct ldb_context *ldb = ldb_module_get_ctx(module);
71 struct loadparm_context *lp_ctx =
72 (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm");
73 TALLOC_CTX *tmp_ctx = talloc_new(module);
75 msg = messaging_client_init(tmp_ctx, lp_messaging_path(tmp_ctx, lp_ctx),
76 ldb_get_event_context(ldb));
78 DEBUG(3,(__location__ ": Failed to create messaging context\n"));
83 server = irpc_servers_byname(msg, msg, "dreplsrv");
85 /* this means the drepl service is not running */
90 messaging_send(msg, server[0], MSG_DREPL_ALLOCATE_RID, NULL);
92 /* we don't care if the message got through */
97 static const char * const ridalloc_ridset_attrs[] = {
99 "rIDPreviousAllocationPool",
105 struct ridalloc_ridset_values {
112 static void ridalloc_get_ridset_values(struct ldb_message *msg, struct ridalloc_ridset_values *v)
114 v->alloc_pool = ldb_msg_find_attr_as_uint64(msg, "rIDAllocationPool", UINT64_MAX);
115 v->prev_pool = ldb_msg_find_attr_as_uint64(msg, "rIDPreviousAllocationPool", UINT64_MAX);
116 v->next_rid = ldb_msg_find_attr_as_uint(msg, "rIDNextRID", UINT32_MAX);
117 v->used_pool = ldb_msg_find_attr_as_uint(msg, "rIDUsedPool", UINT32_MAX);
120 static int ridalloc_set_ridset_values(struct ldb_module *module,
121 struct ldb_message *msg,
122 const struct ridalloc_ridset_values *o,
123 const struct ridalloc_ridset_values *n)
125 const uint32_t *o32, *n32;
126 const uint64_t *o64, *n64;
129 #define SETUP_PTRS(field, optr, nptr, max) do { \
132 if (o->field == max) { \
135 if (n->field == max) { \
138 if (o->field == n->field) { \
144 SETUP_PTRS(alloc_pool, o64, n64, UINT64_MAX);
145 ret = dsdb_msg_constrainted_update_uint64(module, msg,
148 if (ret != LDB_SUCCESS) {
152 SETUP_PTRS(prev_pool, o64, n64, UINT64_MAX);
153 ret = dsdb_msg_constrainted_update_uint64(module, msg,
154 "rIDPreviousAllocationPool",
156 if (ret != LDB_SUCCESS) {
160 SETUP_PTRS(next_rid, o32, n32, UINT32_MAX);
161 ret = dsdb_msg_constrainted_update_uint32(module, msg,
164 if (ret != LDB_SUCCESS) {
168 SETUP_PTRS(used_pool, o32, n32, UINT32_MAX);
169 ret = dsdb_msg_constrainted_update_uint32(module, msg,
172 if (ret != LDB_SUCCESS) {
181 allocate a new range of RIDs in the RID Manager object
183 static int ridalloc_rid_manager_allocate(struct ldb_module *module, struct ldb_dn *rid_manager_dn, uint64_t *new_pool)
186 TALLOC_CTX *tmp_ctx = talloc_new(module);
187 const char *attrs[] = { "rIDAvailablePool", NULL };
188 uint64_t rid_pool, new_rid_pool, dc_pool;
189 uint32_t rid_pool_lo, rid_pool_hi;
190 struct ldb_result *res;
191 struct ldb_context *ldb = ldb_module_get_ctx(module);
192 const unsigned alloc_size = 500;
194 ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_manager_dn,
195 attrs, DSDB_FLAG_NEXT_MODULE);
196 if (ret != LDB_SUCCESS) {
197 ldb_asprintf_errstring(ldb, "Failed to find rIDAvailablePool in %s - %s",
198 ldb_dn_get_linearized(rid_manager_dn), ldb_errstring(ldb));
199 talloc_free(tmp_ctx);
203 rid_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAvailablePool", 0);
204 rid_pool_lo = rid_pool & 0xFFFFFFFF;
205 rid_pool_hi = rid_pool >> 32;
206 if (rid_pool_lo >= rid_pool_hi) {
207 ldb_asprintf_errstring(ldb, "Out of RIDs in RID Manager - rIDAvailablePool is %u-%u",
208 rid_pool_lo, rid_pool_hi);
209 talloc_free(tmp_ctx);
213 /* lower part of new pool is the low part of the rIDAvailablePool */
214 dc_pool = rid_pool_lo;
216 /* allocate 500 RIDs to this DC */
217 rid_pool_lo = MIN(rid_pool_hi, rid_pool_lo + alloc_size);
219 /* work out upper part of new pool */
220 dc_pool |= (((uint64_t)rid_pool_lo-1)<<32);
222 /* and new rIDAvailablePool value */
223 new_rid_pool = rid_pool_lo | (((uint64_t)rid_pool_hi)<<32);
225 ret = dsdb_module_constrainted_update_uint64(module, rid_manager_dn, "rIDAvailablePool",
226 &rid_pool, &new_rid_pool);
227 if (ret != LDB_SUCCESS) {
228 ldb_asprintf_errstring(ldb, "Failed to update rIDAvailablePool - %s",
230 talloc_free(tmp_ctx);
234 (*new_pool) = dc_pool;
235 talloc_free(tmp_ctx);
240 create a RID Set object for the specified DC
242 static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *mem_ctx,
243 struct ldb_dn *rid_manager_dn,
244 struct ldb_dn *ntds_dn, struct ldb_dn **dn)
246 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
247 struct ldb_dn *server_dn, *machine_dn, *rid_set_dn;
250 struct ldb_message *msg;
251 struct ldb_context *ldb = ldb_module_get_ctx(module);
256 find the machine object for the DC
257 construct the RID Set DN
258 load rIDAvailablePool to find next available set
259 modify RID Manager object to update rIDAvailablePool
260 add the RID Set object
261 link to the RID Set object in machine object
264 server_dn = ldb_dn_get_parent(tmp_ctx, ntds_dn);
266 talloc_free(tmp_ctx);
267 return ldb_module_oom(module);
270 ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn);
271 if (ret != LDB_SUCCESS) {
272 ldb_asprintf_errstring(ldb, "Failed to find serverReference in %s - %s",
273 ldb_dn_get_linearized(server_dn), ldb_errstring(ldb));
274 talloc_free(tmp_ctx);
278 rid_set_dn = ldb_dn_copy(tmp_ctx, machine_dn);
279 if (rid_set_dn == NULL) {
280 talloc_free(tmp_ctx);
281 return ldb_module_oom(module);
284 if (! ldb_dn_add_child_fmt(rid_set_dn, "CN=RID Set")) {
285 talloc_free(tmp_ctx);
286 return ldb_module_oom(module);
289 /* grab a pool from the RID Manager object */
290 ret = ridalloc_rid_manager_allocate(module, rid_manager_dn, &dc_pool);
291 if (ret != LDB_SUCCESS) {
292 talloc_free(tmp_ctx);
296 /* create the RID Set object */
297 msg = ldb_msg_new(tmp_ctx);
298 msg->dn = rid_set_dn;
300 ret = ldb_msg_add_string(msg, "objectClass", "rIDSet");
301 if (ret != LDB_SUCCESS) {
302 talloc_free(tmp_ctx);
305 ret = ldb_msg_add_fmt(msg, "rIDAllocationPool", "%llu", (unsigned long long)dc_pool);
306 if (ret != LDB_SUCCESS) {
307 talloc_free(tmp_ctx);
311 /* w2k8-r2 sets these to zero when first created */
312 ret = ldb_msg_add_fmt(msg, "rIDPreviousAllocationPool", "0");
313 if (ret != LDB_SUCCESS) {
314 talloc_free(tmp_ctx);
317 ret = ldb_msg_add_fmt(msg, "rIDUsedPool", "0");
318 if (ret != LDB_SUCCESS) {
319 talloc_free(tmp_ctx);
322 ret = ldb_msg_add_fmt(msg, "rIDNextRID", "0");
323 if (ret != LDB_SUCCESS) {
324 talloc_free(tmp_ctx);
328 /* we need this to go all the way to the top of the module
329 * stack, as we need all the extra attributes added (including
330 * complex ones like ntsecuritydescriptor) */
331 ret = dsdb_module_add(module, msg, DSDB_FLAG_TOP_MODULE | DSDB_MODIFY_RELAX);
332 if (ret != LDB_SUCCESS) {
333 ldb_asprintf_errstring(ldb, "Failed to add RID Set %s - %s",
334 ldb_dn_get_linearized(msg->dn),
336 talloc_free(tmp_ctx);
340 /* add the rIDSetReferences link */
341 msg = ldb_msg_new(tmp_ctx);
342 msg->dn = machine_dn;
344 ret = ldb_msg_add_string(msg, "rIDSetReferences", ldb_dn_get_linearized(rid_set_dn));
345 if (ret != LDB_SUCCESS) {
346 talloc_free(tmp_ctx);
349 msg->elements[0].flags = LDB_FLAG_MOD_ADD;
351 ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE);
352 if (ret != LDB_SUCCESS) {
353 ldb_asprintf_errstring(ldb, "Failed to add rIDSetReferences to %s - %s",
354 ldb_dn_get_linearized(msg->dn),
356 talloc_free(tmp_ctx);
360 (*dn) = talloc_steal(mem_ctx, rid_set_dn);
362 talloc_free(tmp_ctx);
368 create a RID Set object for this DC
370 static int ridalloc_create_own_rid_set(struct ldb_module *module, TALLOC_CTX *mem_ctx,
373 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
374 struct ldb_dn *rid_manager_dn, *fsmo_role_dn;
376 struct ldb_context *ldb = ldb_module_get_ctx(module);
378 /* work out who is the RID Manager */
379 ret = dsdb_module_rid_manager_dn(module, tmp_ctx, &rid_manager_dn);
380 if (ret != LDB_SUCCESS) {
381 ldb_asprintf_errstring(ldb, "Failed to find RID Manager object - %s",
383 talloc_free(tmp_ctx);
387 /* find the DN of the RID Manager */
388 ret = dsdb_module_reference_dn(module, tmp_ctx, rid_manager_dn, "fSMORoleOwner", &fsmo_role_dn);
389 if (ret != LDB_SUCCESS) {
390 ldb_asprintf_errstring(ldb, "Failed to find fSMORoleOwner in RID Manager object - %s",
392 talloc_free(tmp_ctx);
396 if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) {
397 ridalloc_poke_rid_manager(module);
398 ldb_asprintf_errstring(ldb, "Remote RID Set allocation needs refresh");
399 talloc_free(tmp_ctx);
400 return LDB_ERR_UNWILLING_TO_PERFORM;
403 ret = ridalloc_create_rid_set_ntds(module, mem_ctx, rid_manager_dn, fsmo_role_dn, dn);
404 talloc_free(tmp_ctx);
409 refresh a RID Set object for the specified DC
410 also returns the first RID for the new pool
412 static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module,
413 struct ldb_dn *rid_manager_dn,
414 struct ldb_dn *ntds_dn, uint64_t *new_pool)
416 TALLOC_CTX *tmp_ctx = talloc_new(module);
417 struct ldb_dn *server_dn, *machine_dn, *rid_set_dn;
418 struct ldb_context *ldb = ldb_module_get_ctx(module);
421 /* grab a pool from the RID Manager object */
422 ret = ridalloc_rid_manager_allocate(module, rid_manager_dn, new_pool);
423 if (ret != LDB_SUCCESS) {
424 talloc_free(tmp_ctx);
428 server_dn = ldb_dn_get_parent(tmp_ctx, ntds_dn);
430 talloc_free(tmp_ctx);
431 return ldb_module_oom(module);
434 ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn);
435 if (ret != LDB_SUCCESS) {
436 ldb_asprintf_errstring(ldb, "Failed to find serverReference in %s - %s",
437 ldb_dn_get_linearized(server_dn), ldb_errstring(ldb));
438 talloc_free(tmp_ctx);
442 ret = dsdb_module_reference_dn(module, tmp_ctx, machine_dn, "rIDSetReferences", &rid_set_dn);
443 if (ret != LDB_SUCCESS) {
444 ldb_asprintf_errstring(ldb, "Failed to find rIDSetReferences in %s - %s",
445 ldb_dn_get_linearized(machine_dn), ldb_errstring(ldb));
446 talloc_free(tmp_ctx);
450 ret = dsdb_module_set_integer(module, rid_set_dn, "rIDAllocationPool", *new_pool);
451 if (ret != LDB_SUCCESS) {
452 ldb_asprintf_errstring(ldb, "Failed to modify RID Set object %s - %s",
453 ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb));
454 talloc_free(tmp_ctx);
458 talloc_free(tmp_ctx);
464 get a new RID pool for ourselves
465 also returns the first rid for the new pool
467 static int ridalloc_refresh_own_pool(struct ldb_module *module, uint64_t *new_pool)
469 TALLOC_CTX *tmp_ctx = talloc_new(module);
470 struct ldb_dn *rid_manager_dn, *fsmo_role_dn;
472 struct ldb_context *ldb = ldb_module_get_ctx(module);
474 /* work out who is the RID Manager */
475 ret = dsdb_module_rid_manager_dn(module, tmp_ctx, &rid_manager_dn);
476 if (ret != LDB_SUCCESS) {
477 ldb_asprintf_errstring(ldb, "Failed to find RID Manager object - %s",
479 talloc_free(tmp_ctx);
483 /* find the DN of the RID Manager */
484 ret = dsdb_module_reference_dn(module, tmp_ctx, rid_manager_dn, "fSMORoleOwner", &fsmo_role_dn);
485 if (ret != LDB_SUCCESS) {
486 ldb_asprintf_errstring(ldb, "Failed to find fSMORoleOwner in RID Manager object - %s",
488 talloc_free(tmp_ctx);
492 if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) {
493 ridalloc_poke_rid_manager(module);
494 ldb_asprintf_errstring(ldb, "Remote RID Set allocation needs refresh");
495 talloc_free(tmp_ctx);
496 return LDB_ERR_UNWILLING_TO_PERFORM;
499 ret = ridalloc_refresh_rid_set_ntds(module, rid_manager_dn, fsmo_role_dn, new_pool);
500 talloc_free(tmp_ctx);
505 /* allocate a RID using our RID Set
506 If we run out of RIDs then allocate a new pool
507 either locally or by contacting the RID Manager
509 int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid)
511 struct ldb_context *ldb;
512 static const char * const attrs[] = { "rIDAllocationPool", "rIDPreviousAllocationPool",
513 "rIDNextRID" , "rIDUsedPool", NULL };
515 struct ldb_dn *rid_set_dn;
516 struct ldb_result *res;
517 uint64_t alloc_pool, prev_alloc_pool;
518 uint32_t prev_alloc_pool_lo, prev_alloc_pool_hi;
519 uint32_t rid_used_pool;
521 TALLOC_CTX *tmp_ctx = talloc_new(module);
524 ldb = ldb_module_get_ctx(module);
526 ret = samdb_rid_set_dn(ldb, tmp_ctx, &rid_set_dn);
527 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
528 ret = ridalloc_create_own_rid_set(module, tmp_ctx, &rid_set_dn);
530 if (ret != LDB_SUCCESS) {
531 ldb_asprintf_errstring(ldb, __location__ ": No RID Set DN - %s",
533 talloc_free(tmp_ctx);
537 ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_set_dn,
538 attrs, DSDB_FLAG_NEXT_MODULE);
539 if (ret != LDB_SUCCESS) {
540 ldb_asprintf_errstring(ldb, __location__ ": No RID Set %s",
541 ldb_dn_get_linearized(rid_set_dn));
542 talloc_free(tmp_ctx);
546 prev_alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDPreviousAllocationPool", 0);
547 alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0);
548 prev_rid = ldb_msg_find_attr_as_int(res->msgs[0], "rIDNextRID", 0);
549 rid_used_pool = ldb_msg_find_attr_as_int(res->msgs[0], "rIDUsedPool", 0);
550 if (alloc_pool == 0) {
551 ldb_asprintf_errstring(ldb, __location__ ": Bad RID Set %s",
552 ldb_dn_get_linearized(rid_set_dn));
553 talloc_free(tmp_ctx);
554 return LDB_ERR_OPERATIONS_ERROR;
557 prev_alloc_pool_lo = prev_alloc_pool & 0xFFFFFFFF;
558 prev_alloc_pool_hi = prev_alloc_pool >> 32;
559 if (prev_rid >= prev_alloc_pool_hi) {
560 if (prev_alloc_pool == 0) {
561 ret = dsdb_module_set_integer(module, rid_set_dn, "rIDPreviousAllocationPool", alloc_pool);
563 ret = dsdb_module_constrainted_update_integer(module, rid_set_dn, "rIDPreviousAllocationPool",
564 prev_alloc_pool, alloc_pool);
566 if (ret != LDB_SUCCESS) {
567 ldb_asprintf_errstring(ldb, __location__ ": Failed to update rIDPreviousAllocationPool on %s - %s",
568 ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb));
569 talloc_free(tmp_ctx);
572 prev_alloc_pool = alloc_pool;
573 prev_alloc_pool_lo = prev_alloc_pool & 0xFFFFFFFF;
574 prev_alloc_pool_hi = prev_alloc_pool >> 32;
577 * update the rIDUsedPool attribute
579 * Note: w2k8r2 doesn't update this attribute,
580 * at least if it's itself the rid master.
582 ret = dsdb_module_set_integer(module, rid_set_dn, "rIDUsedPool", rid_used_pool+1);
583 if (ret != LDB_SUCCESS) {
584 ldb_asprintf_errstring(ldb, __location__ ": Failed to update rIDUsedPool on %s - %s",
585 ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb));
586 talloc_free(tmp_ctx);
590 (*rid) = prev_alloc_pool_lo;
593 /* see if we are still out of RIDs, and if so then ask
594 the RID Manager to give us more */
595 if (prev_rid >= prev_alloc_pool_hi) {
597 ret = ridalloc_refresh_own_pool(module, &new_pool);
598 if (ret != LDB_SUCCESS) {
599 talloc_free(tmp_ctx);
602 ret = dsdb_module_constrainted_update_integer(module, rid_set_dn, "rIDPreviousAllocationPool",
603 prev_alloc_pool, new_pool);
604 if (ret != LDB_SUCCESS) {
605 ldb_asprintf_errstring(ldb, __location__ ": Failed to update rIDPreviousAllocationPool on %s - %s",
606 ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb));
607 talloc_free(tmp_ctx);
610 prev_alloc_pool = new_pool;
611 prev_alloc_pool_lo = prev_alloc_pool & 0xFFFFFFFF;
612 prev_alloc_pool_hi = prev_alloc_pool >> 32;
613 (*rid) = prev_alloc_pool_lo;
615 /* despite the name, rIDNextRID is the value of the last user
616 * added by this DC, not the next available RID */
618 (*rid) = prev_rid + 1;
622 if (*rid < prev_alloc_pool_lo || *rid > prev_alloc_pool_hi) {
623 ldb_asprintf_errstring(ldb, __location__ ": Bad rid chosen %u from range %u-%u",
624 (unsigned)*rid, (unsigned)prev_alloc_pool_lo,
625 (unsigned)prev_alloc_pool_hi);
626 talloc_free(tmp_ctx);
627 return LDB_ERR_OPERATIONS_ERROR;
630 /* now modify the RID Set to use up this RID using a
631 * constrained delete/add if possible */
633 ret = dsdb_module_set_integer(module, rid_set_dn, "rIDNextRID", *rid);
635 ret = dsdb_module_constrainted_update_integer(module, rid_set_dn, "rIDNextRID", prev_rid, *rid);
638 /* if we are half-exhausted then ask the repl task to start
639 * getting another one */
640 if (*rid > (prev_alloc_pool_hi + prev_alloc_pool_lo)/2) {
641 ridalloc_poke_rid_manager(module);
644 talloc_free(tmp_ctx);
651 called by DSDB_EXTENDED_ALLOCATE_RID_POOL extended operation in samldb
653 int ridalloc_allocate_rid_pool_fsmo(struct ldb_module *module, struct dsdb_fsmo_extended_op *exop)
655 struct ldb_dn *ntds_dn, *server_dn, *machine_dn, *rid_set_dn;
656 struct ldb_dn *rid_manager_dn;
657 TALLOC_CTX *tmp_ctx = talloc_new(module);
659 struct ldb_context *ldb = ldb_module_get_ctx(module);
662 ret = dsdb_module_dn_by_guid(module, tmp_ctx, &exop->destination_dsa_guid, &ntds_dn);
663 if (ret != LDB_SUCCESS) {
664 ldb_asprintf_errstring(ldb, __location__ ": Unable to find NTDS object for guid %s - %s\n",
665 GUID_string(tmp_ctx, &exop->destination_dsa_guid), ldb_errstring(ldb));
666 talloc_free(tmp_ctx);
670 server_dn = ldb_dn_get_parent(tmp_ctx, ntds_dn);
672 talloc_free(tmp_ctx);
673 return ldb_module_oom(module);
676 ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn);
677 if (ret != LDB_SUCCESS) {
678 ldb_asprintf_errstring(ldb, __location__ ": Failed to find serverReference in %s - %s",
679 ldb_dn_get_linearized(server_dn), ldb_errstring(ldb));
680 talloc_free(tmp_ctx);
685 ret = dsdb_module_rid_manager_dn(module, tmp_ctx, &rid_manager_dn);
686 if (ret != LDB_SUCCESS) {
687 ldb_asprintf_errstring(ldb, __location__ ": Failed to find RID Manager object - %s",
689 talloc_free(tmp_ctx);
693 ret = dsdb_module_reference_dn(module, tmp_ctx, machine_dn, "rIDSetReferences", &rid_set_dn);
694 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
695 ret = ridalloc_create_rid_set_ntds(module, tmp_ctx, rid_manager_dn, ntds_dn, &rid_set_dn);
696 talloc_free(tmp_ctx);
700 if (ret != LDB_SUCCESS) {
701 ldb_asprintf_errstring(ldb, "Failed to find rIDSetReferences in %s - %s",
702 ldb_dn_get_linearized(machine_dn), ldb_errstring(ldb));
703 talloc_free(tmp_ctx);
707 if (exop->fsmo_info != 0) {
708 const char *attrs[] = { "rIDAllocationPool", NULL };
709 struct ldb_result *res;
712 ret = dsdb_module_search_dn(module, tmp_ctx, &res, rid_set_dn,
713 attrs, DSDB_FLAG_NEXT_MODULE);
714 if (ret != LDB_SUCCESS) {
715 ldb_asprintf_errstring(ldb, __location__ ": No RID Set %s",
716 ldb_dn_get_linearized(rid_set_dn));
717 talloc_free(tmp_ctx);
721 alloc_pool = ldb_msg_find_attr_as_uint64(res->msgs[0], "rIDAllocationPool", 0);
722 if (alloc_pool != exop->fsmo_info) {
723 /* it has already been updated */
724 DEBUG(2,(__location__ ": rIDAllocationPool fsmo_info mismatch - already changed (0x%llx 0x%llx)\n",
725 (unsigned long long)exop->fsmo_info,
726 (unsigned long long)alloc_pool));
727 talloc_free(tmp_ctx);
732 ret = ridalloc_refresh_rid_set_ntds(module, rid_manager_dn, ntds_dn, &new_pool);
733 talloc_free(tmp_ctx);