returns immediately. It should be called well before we
completely run out of RIDs
*/
-static void ridalloc_poke_rid_manager(struct ldb_module *module)
+static int ridalloc_poke_rid_manager(struct ldb_module *module)
{
struct imessaging_context *msg;
- struct server_id *server;
+ unsigned num_servers;
+ struct server_id *servers;
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);
+ NTSTATUS status;
msg = imessaging_client_init(tmp_ctx, lp_ctx,
ldb_get_event_context(ldb));
if (!msg) {
+ ldb_asprintf_errstring(ldb_module_get_ctx(module),
+ "Failed to send MSG_DREPL_ALLOCATE_RID, "
+ "unable init client messaging context");
DEBUG(3,(__location__ ": Failed to create messaging context\n"));
talloc_free(tmp_ctx);
- return;
+ return LDB_ERR_UNWILLING_TO_PERFORM;
}
- server = irpc_servers_byname(msg, msg, "dreplsrv");
- if (!server) {
+ status = irpc_servers_byname(msg, msg, "dreplsrv",
+ &num_servers, &servers);
+ if (!NT_STATUS_IS_OK(status)) {
+ ldb_asprintf_errstring(ldb_module_get_ctx(module),
+ "Failed to send MSG_DREPL_ALLOCATE_RID, "
+ "unable to locate dreplsrv");
/* this means the drepl service is not running */
talloc_free(tmp_ctx);
- return;
+ return LDB_ERR_UNWILLING_TO_PERFORM;
}
- imessaging_send(msg, server[0], MSG_DREPL_ALLOCATE_RID, NULL);
+ status = imessaging_send(msg, servers[0], MSG_DREPL_ALLOCATE_RID, NULL);
+
+ /* Only error out if an error happened, not on STATUS_MORE_ENTRIES, ie a delayed message */
+ if (NT_STATUS_IS_ERR(status)) {
+ struct server_id_buf idbuf;
+ ldb_asprintf_errstring(ldb_module_get_ctx(module),
+ "Failed to send MSG_DREPL_ALLOCATE_RID to dreplsrv at %s: %s",
+ server_id_str_buf(*servers, &idbuf),
+ nt_errstr(status));
+ talloc_free(tmp_ctx);
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
- /* we don't care if the message got through */
talloc_free(tmp_ctx);
+ return LDB_SUCCESS;
}
struct ldb_dn *rid_manager_dn, *fsmo_role_dn;
int ret;
struct ldb_context *ldb = ldb_module_get_ctx(module);
+ struct GUID fsmo_role_guid;
+ const struct GUID *our_ntds_guid;
+ NTSTATUS status;
/* work out who is the RID Manager */
ret = dsdb_module_rid_manager_dn(module, tmp_ctx, &rid_manager_dn, parent);
return ret;
}
- 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");
+ status = dsdb_get_extended_dn_guid(fsmo_role_dn, &fsmo_role_guid, "GUID");
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(tmp_ctx);
+ return ldb_operr(ldb_module_get_ctx(module));
+ }
+
+ our_ntds_guid = samdb_ntds_objectGUID(ldb_module_get_ctx(module));
+ if (!our_ntds_guid) {
+ talloc_free(tmp_ctx);
+ return ldb_operr(ldb_module_get_ctx(module));
+ }
+
+ if (!GUID_equal(&fsmo_role_guid, our_ntds_guid)) {
+ ret = ridalloc_poke_rid_manager(module);
+ if (ret != LDB_SUCCESS) {
+ ldb_asprintf_errstring(ldb,
+ "Request for remote creation of "
+ "RID Set for this DC failed: %s",
+ ldb_errstring(ldb));
+ } else {
+ ldb_asprintf_errstring(ldb,
+ "Remote RID Set creation needed");
+ }
talloc_free(tmp_ctx);
return LDB_ERR_UNWILLING_TO_PERFORM;
}
struct ldb_dn *rid_manager_dn, *fsmo_role_dn;
int ret;
struct ldb_context *ldb = ldb_module_get_ctx(module);
+ bool is_us;
/* work out who is the RID Manager */
ret = dsdb_module_rid_manager_dn(module, tmp_ctx, &rid_manager_dn, parent);
return ret;
}
- 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");
+ ret = samdb_dn_is_our_ntdsa(ldb, fsmo_role_dn, &is_us);
+ if (ret != LDB_SUCCESS) {
+ ldb_asprintf_errstring(ldb, "Failed to confirm if our ntdsDsa is %s: %s",
+ ldb_dn_get_linearized(fsmo_role_dn), ldb_errstring(ldb));
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ if (!is_us) {
+ ret = ridalloc_poke_rid_manager(module);
+ if (ret != LDB_SUCCESS) {
+ ldb_asprintf_errstring(ldb, "Request for remote refresh of RID Set allocation failed: %s",
+ ldb_errstring(ldb));
+ } else {
+ ldb_asprintf_errstring(ldb, "Remote RID Set refresh needed");
+ }
talloc_free(tmp_ctx);
return LDB_ERR_UNWILLING_TO_PERFORM;
}
* ask async for a new pool.
*/
ret = ridalloc_new_own_pool(module, &nridset.alloc_pool, parent);
- if (ret == LDB_ERR_UNWILLING_TO_PERFORM) {
- ridalloc_poke_rid_manager(module);
- talloc_free(tmp_ctx);
- return ret;
- }
if (ret != LDB_SUCCESS) {
+ ldb_asprintf_errstring(ldb, "NO RID values available: %s",
+ ldb_errstring(ldb));
talloc_free(tmp_ctx);
return ret;
}
/*
* if we are half-exhausted then try to get a new pool.
*/
- if (nridset.next_rid > (prev_pool_hi + prev_pool_lo)/2) {
+ if (nridset.next_rid > (prev_pool_hi + prev_pool_lo)/2 &&
+ nridset.alloc_pool == nridset.prev_pool) {
/*
* if we are the RID Manager,
* we can get a new pool localy.
*/
ret = ridalloc_new_own_pool(module, &nridset.alloc_pool, parent);
if (ret == LDB_ERR_UNWILLING_TO_PERFORM) {
- ridalloc_poke_rid_manager(module);
+ ldb_reset_err_string(ldb);
ret = LDB_SUCCESS;
}
if (ret != LDB_SUCCESS) {