From dd4b91f2f49d5b3908f3659d44fd65d5b1216043 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 14 Jan 2007 17:04:15 +0000 Subject: r20771: add an ldb module which will force the Schema FSMO Role Owner constraints and it also loads the dsdb_schema at startup. currently it only loads the dsdb_schema metze (This used to be commit d78de0fb68f8b4ef4c5372f3c3ed171e44cf2037) --- source4/dsdb/samdb/ldb_modules/schema_fsmo.c | 225 +++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 source4/dsdb/samdb/ldb_modules/schema_fsmo.c (limited to 'source4/dsdb/samdb/ldb_modules/schema_fsmo.c') diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c new file mode 100644 index 0000000000..1a83e3a9bf --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c @@ -0,0 +1,225 @@ +/* + Unix SMB/CIFS mplementation. + + The module that handles the Schema FSMO Role Owner + checkings, it also loads the dsdb_schema. + + Copyright (C) Stefan Metzmacher 2007 + + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "includes.h" +#include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" +#include "lib/ldb/include/ldb_private.h" +#include "dsdb/samdb/samdb.h" +#include "librpc/gen_ndr/ndr_misc.h" +#include "librpc/gen_ndr/ndr_drsuapi.h" +#include "librpc/gen_ndr/ndr_drsblobs.h" +#include "lib/util/dlinklist.h" + +static int schema_fsmo_init(struct ldb_module *module) +{ + WERROR status; + TALLOC_CTX *mem_ctx; + struct ldb_dn *schema_dn; + struct dsdb_schema *schema; + struct ldb_result *schema_res; + const struct ldb_val *prefix_val; + const struct ldb_val *info_val; + struct ldb_result *a_res; + struct ldb_result *c_res; + uint32_t i; + int ret; + static const char *schema_attrs[] = { + "prefixMap", + "schemaInfo", + NULL + }; + + schema_dn = samdb_schema_dn(module->ldb); + if (!schema_dn) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, + "schema_fsmo_init: no schema dn present: (skip schema loading)"); + return ldb_next_init(module); + } + + mem_ctx = talloc_new(module); + if (!mem_ctx) { + ldb_oom(module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + schema = talloc_zero(mem_ctx, struct dsdb_schema); + if (!schema) { + ldb_oom(module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* + * setup the prefix mappings and schema info + */ + ret = ldb_search(module->ldb, schema_dn, + LDB_SCOPE_BASE, + NULL, schema_attrs, + &schema_res); + if (ret != LDB_SUCCESS) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "schema_fsmo_init: failed to search the schema head: %d:%s", + ret, ldb_strerror(ret)); + talloc_free(mem_ctx); + return ret; + } + talloc_steal(mem_ctx, schema_res); + if (schema_res->count == 0) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, + "schema_fsmo_init: no schema head present: (skip schema loading)"); + talloc_free(mem_ctx); + return ldb_next_init(module); + } else if (schema_res->count > 1) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "schema_fsmo_init: [%u] schema heads found on a base search", + schema_res->count); + talloc_free(mem_ctx); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + prefix_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "prefixMap"); + if (!prefix_val) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "schema_fsmo_init: no prefixMap attribute found"); + talloc_free(mem_ctx); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + info_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "schemaInfo"); + if (!info_val) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "schema_fsmo_init: no schemaInfo attribute found"); + talloc_free(mem_ctx); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + status = dsdb_load_oid_mappings_ldb(schema, prefix_val, info_val); + if (!W_ERROR_IS_OK(status)) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "schema_fsmo_init: failed to load oid mappings: %s", + win_errstr(status)); + talloc_free(mem_ctx); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + /* + * load the attribute definitions + */ + ret = ldb_search(module->ldb, schema_dn, + LDB_SCOPE_ONELEVEL, + "(objectClass=attributeSchema)", NULL, + &a_res); + if (ret != LDB_SUCCESS) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "schema_fsmo_init: failed to search attributeSchema objects: %d:%s", + ret, ldb_strerror(ret)); + talloc_free(mem_ctx); + return ret; + } + talloc_steal(mem_ctx, a_res); + + for (i=0; i < a_res->count; i++) { + struct dsdb_attribute *sa; + + sa = talloc_zero(schema, struct dsdb_attribute); + if (!sa) { + ldb_oom(module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + status = dsdb_attribute_from_ldb(schema, a_res->msgs[i], sa, sa); + if (!W_ERROR_IS_OK(status)) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "schema_fsmo_init: failed to load attriute definition: %s:%s", + ldb_dn_get_linearized(a_res->msgs[i]->dn), + win_errstr(status)); + talloc_free(mem_ctx); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + DLIST_ADD_END(schema->attributes, sa, struct dsdb_attribute *); + } + talloc_free(a_res); + + /* + * load the objectClass definitions + */ + ret = ldb_search(module->ldb, schema_dn, + LDB_SCOPE_ONELEVEL, + "(objectClass=classSchema)", NULL, + &c_res); + if (ret != LDB_SUCCESS) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "schema_fsmo_init: failed to search classSchema objects: %d:%s", + ret, ldb_strerror(ret)); + talloc_free(mem_ctx); + return ret; + } + talloc_steal(mem_ctx, c_res); + + for (i=0; i < c_res->count; i++) { + struct dsdb_class *sc; + + sc = talloc_zero(schema, struct dsdb_class); + if (!sc) { + ldb_oom(module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + status = dsdb_class_from_ldb(schema, c_res->msgs[i], sc, sc); + if (!W_ERROR_IS_OK(status)) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "schema_fsmo_init: failed to load class definition: %s:%s", + ldb_dn_get_linearized(c_res->msgs[i]->dn), + win_errstr(status)); + talloc_free(mem_ctx); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + DLIST_ADD_END(schema->classes, sc, struct dsdb_class *); + } + talloc_free(c_res); + + ret = dsdb_set_schema(module->ldb, schema); + if (ret != LDB_SUCCESS) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "schema_fsmo_init: dsdb_set_schema() failed: %d:%s", + ret, ldb_strerror(ret)); + talloc_free(mem_ctx); + return ret; + } + + talloc_steal(module, schema); + talloc_free(mem_ctx); + return ldb_next_init(module); +} + +static const struct ldb_module_ops schema_fsmo_ops = { + .name = "schema_fsmo", + .init_context = schema_fsmo_init +}; + +int schema_fsmo_module_init(void) +{ + return ldb_register_module(&schema_fsmo_ops); +} -- cgit