From b1f97b7e60b68429f0a9c12de9cd1cf24b2d8d35 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jan 2010 19:34:14 +1100 Subject: s4-dsdb: added an extended operation for allocating a new RID pool This will be called by getncchanges when a client asks for a DRSUAPI_EXOP_FSMO_RID_ALLOC operation Pair-Programmed-With: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/ridalloc.c | 90 +++++++++++++++++++++++++++++++ source4/dsdb/samdb/ldb_modules/samldb.c | 32 ++++++++++- source4/dsdb/samdb/samdb.h | 8 +++ 3 files changed, 129 insertions(+), 1 deletion(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index c3d334ff3a..2d0753f393 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -33,6 +33,7 @@ #include "dsdb/samdb/ldb_modules/util.h" #include "lib/messaging/irpc.h" #include "param/param.h" +#include "librpc/gen_ndr/ndr_misc.h" /* Note: the RID allocation attributes in AD are very badly named. Here @@ -140,6 +141,7 @@ static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *m 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; } @@ -315,6 +317,7 @@ static int ridalloc_refresh_rid_set_ntds(struct ldb_module *module, 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; } @@ -560,6 +563,93 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid) talloc_free(tmp_ctx); + return ret; +} + + +/* + called by DSDB_EXTENDED_ALLOCATE_RID_POOL extended operation in samldb + */ +int ridalloc_allocate_rid_pool_fsmo(struct ldb_module *module, struct dsdb_fsmo_extended_op *exop) +{ + struct ldb_dn *ntds_dn, *server_dn, *machine_dn, *rid_set_dn; + struct ldb_dn *rid_manager_dn; + TALLOC_CTX *tmp_ctx = talloc_new(module); + int ret; + struct ldb_context *ldb = ldb_module_get_ctx(module); + uint64_t new_pool; + + ret = dsdb_module_dn_by_guid(module, tmp_ctx, &exop->destination_dsa_guid, &ntds_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": Unable to find NTDS object for guid %s - %s\n", + GUID_string(tmp_ctx, &exop->destination_dsa_guid), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + 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; + } + + ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": Failed to find serverReference in %s - %s", + ldb_dn_get_linearized(server_dn), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + ret = dsdb_module_rid_manager_dn(module, tmp_ctx, &rid_manager_dn); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, __location__ ": Failed to find RID Manager object - %s", + ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + ret = dsdb_module_reference_dn(module, tmp_ctx, machine_dn, "rIDSetReferences", &rid_set_dn); + if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { + ret = ridalloc_create_rid_set_ntds(module, tmp_ctx, rid_manager_dn, ntds_dn, &rid_set_dn); + talloc_free(tmp_ctx); + return ret; + } + + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "Failed to find rIDSetReferences in %s - %s", + ldb_dn_get_linearized(machine_dn), ldb_errstring(ldb)); + talloc_free(tmp_ctx); + return ret; + } + + if (exop->fsmo_info != 0) { + const char *attrs[] = { "rIDAllocationPool", NULL }; + struct ldb_result *res; + uint64_t alloc_pool; + + 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); + if (alloc_pool != exop->fsmo_info) { + /* it has already been updated */ + DEBUG(2,(__location__ ": rIDAllocationPool fsmo_info mismatch - already changed (0x%llx 0x%llx)\n", + (unsigned long long)exop->fsmo_info, + (unsigned long long)alloc_pool)); + talloc_free(tmp_ctx); + return LDB_SUCCESS; + } + } + + ret = ridalloc_refresh_rid_set_ntds(module, rid_manager_dn, ntds_dn, &new_pool); + talloc_free(tmp_ctx); return ret; } diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index eb83633fe2..79bfc0a15c 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -1860,11 +1860,41 @@ static int samldb_delete(struct ldb_module *module, struct ldb_request *req) return samldb_prim_group_users_check(ac); } +static int samldb_extended_allocate_rid_pool(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct dsdb_fsmo_extended_op *exop; + int ret; + + exop = talloc_get_type(req->op.extended.data, struct dsdb_fsmo_extended_op); + if (!exop) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "samldb_extended_allocate_rid_pool: invalid extended data\n"); + return LDB_ERR_PROTOCOL_ERROR; + } + + ret = ridalloc_allocate_rid_pool_fsmo(module, exop); + if (ret != LDB_SUCCESS) { + return ret; + } + + return ldb_module_done(req, NULL, NULL, LDB_SUCCESS); +} + +static int samldb_extended(struct ldb_module *module, struct ldb_request *req) +{ + if (strcmp(req->op.extended.oid, DSDB_EXTENDED_ALLOCATE_RID_POOL) == 0) { + return samldb_extended_allocate_rid_pool(module, req); + } + + return ldb_next_request(module, req); +} + _PUBLIC_ const struct ldb_module_ops ldb_samldb_module_ops = { .name = "samldb", .add = samldb_add, .modify = samldb_modify, - .del = samldb_delete + .del = samldb_delete, + .extended = samldb_extended }; diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h index a05aa00f7a..6df30b2904 100644 --- a/source4/dsdb/samdb/samdb.h +++ b/source4/dsdb/samdb/samdb.h @@ -142,4 +142,12 @@ struct dsdb_extended_dn_store_format { #define DSDB_OPAQUE_PARTITION_MODULE_MSG_OPAQUE_NAME "DSDB_OPAQUE_PARTITION_MODULE_MSG" +/* this takes a struct dsdb_fsmo_extended_op */ +#define DSDB_EXTENDED_ALLOCATE_RID_POOL "1.3.6.1.4.1.7165.4.4.5" + +struct dsdb_fsmo_extended_op { + uint64_t fsmo_info; + struct GUID destination_dsa_guid; +}; + #endif /* __SAMDB_H__ */ -- cgit