diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/dsdb/common/util.c | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/config.mk | 20 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/naming_fsmo.c | 26 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/objectclass.c | 9 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/password_hash.c | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/pdc_fsmo.c | 20 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samldb.c | 11 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/schema_fsmo.c | 113 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/util.c | 128 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/util.h | 22 | ||||
-rw-r--r-- | source4/dsdb/schema/schema_inferiors.c | 27 | ||||
-rw-r--r-- | source4/dsdb/schema/schema_init.c | 115 | ||||
-rw-r--r-- | source4/dsdb/schema/schema_set.c | 5 | ||||
-rw-r--r-- | source4/lib/ldb/common/ldb.c | 8 | ||||
-rw-r--r-- | source4/lib/ldb/common/ldb_modules.c | 8 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_tdb.c | 9 | ||||
-rw-r--r-- | source4/scripting/python/samba/provision.py | 30 | ||||
-rw-r--r-- | source4/setup/provision_basedn.ldif | 2 | ||||
-rw-r--r-- | source4/setup/schema_samba4.ldif | 43 |
19 files changed, 370 insertions, 230 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 9a8b59e55d..f86a842fb4 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -1531,7 +1531,7 @@ int samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, while ((sdn = ldb_dn_get_parent(local_ctx, sdn))) { ret = ldb_search(ldb, local_ctx, &res, sdn, LDB_SCOPE_BASE, attrs, - "(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))"); + "(|(objectClass=domain)(objectClass=builtinDomain))"); if (ret == LDB_SUCCESS) { if (res->count == 1) { break; diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 456ff5756c..ea4e722822 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -1,4 +1,14 @@ ################################################ +# Start SUBSYSTEM DSDB_MODULE_HELPERS +[SUBSYSTEM::DSDB_MODULE_HELPERS] +PRIVATE_DEPENDENCIES = LIBLDB + +DSDB_MODULE_HELPERS_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/util.o + +$(eval $(call proto_header_template,$(dsdbsrcdir)/samdb/ldb_modules/util_proto.h,$(DSDB_MODULE_HELPERS_OBJ_FILES:.o=.c))) + + +################################################ # Start MODULE ldb_objectguid [MODULE::ldb_objectguid] SUBSYSTEM = LIBLDB @@ -15,7 +25,7 @@ ldb_objectguid_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/objectguid.o SUBSYSTEM = LIBLDB PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS \ LIBNDR NDR_DRSUAPI \ - NDR_DRSBLOBS LIBNDR + NDR_DRSBLOBS LIBNDR DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(repl_meta_data) # End MODULE ldb_repl_meta_data ################################################ @@ -39,7 +49,7 @@ ldb_dsdb_cache_OBJ_FILES = \ # Start MODULE ldb_schema_fsmo [MODULE::ldb_schema_fsmo] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS +PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(schema_fsmo) # End MODULE ldb_schema_fsmo ################################################ @@ -51,7 +61,7 @@ ldb_schema_fsmo_OBJ_FILES = \ # Start MODULE ldb_naming_fsmo [MODULE::ldb_naming_fsmo] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS +PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(naming_fsmo) # End MODULE ldb_naming_fsmo ################################################ @@ -63,7 +73,7 @@ ldb_naming_fsmo_OBJ_FILES = \ # Start MODULE ldb_pdc_fsmo [MODULE::ldb_pdc_fsmo] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS +PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(pdc_fsmo) # End MODULE ldb_pdc_fsmo ################################################ @@ -220,7 +230,7 @@ ldb_show_deleted_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/show_deleted.o # Start MODULE ldb_partition [MODULE::ldb_partition] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SAMDB +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SAMDB DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(partition) # End MODULE ldb_partition ################################################ diff --git a/source4/dsdb/samdb/ldb_modules/naming_fsmo.c b/source4/dsdb/samdb/ldb_modules/naming_fsmo.c index 607bf054d2..15cad259ce 100644 --- a/source4/dsdb/samdb/ldb_modules/naming_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/naming_fsmo.c @@ -28,6 +28,7 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "../lib/util/dlinklist.h" +#include "dsdb/samdb/ldb_modules/util.h" static int naming_fsmo_init(struct ldb_module *module) { @@ -65,34 +66,15 @@ static int naming_fsmo_init(struct ldb_module *module) } ldb_module_set_private(module, naming_fsmo); - ret = ldb_search(ldb, mem_ctx, &naming_res, - naming_dn, LDB_SCOPE_BASE, - naming_attrs, NULL); + ret = dsdb_module_search_dn(module, mem_ctx, &naming_res, + naming_dn, + naming_attrs); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_debug(ldb, LDB_DEBUG_WARNING, "naming_fsmo_init: no partitions dn present: (skip loading of naming contexts details)\n"); talloc_free(mem_ctx); return ldb_next_init(module); } - if (ret != LDB_SUCCESS) { - ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "naming_fsmo_init: failed to search the cross-ref container: %s: %s", - ldb_strerror(ret), ldb_errstring(ldb)); - talloc_free(mem_ctx); - return ret; - } - if (naming_res->count == 0) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - "naming_fsmo_init: no cross-ref container present: (skip loading of naming contexts details)\n"); - talloc_free(mem_ctx); - return ldb_next_init(module); - } else if (naming_res->count > 1) { - ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "naming_fsmo_init: [%u] cross-ref containers found on a base search", - naming_res->count); - talloc_free(mem_ctx); - return LDB_ERR_CONSTRAINT_VIOLATION; - } naming_fsmo->master_dn = ldb_msg_find_attr_as_dn(ldb, naming_fsmo, naming_res->msgs[0], "fSMORoleOwner"); if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), naming_fsmo->master_dn) == 0) { diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index b6f1a1aa23..b5e058df0b 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -706,7 +706,13 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req if (!schema) { return ldb_next_request(module, req); } - objectclass_element = ldb_msg_find_element(req->op.mod.message, "objectClass"); + + /* As with the "real" AD we don't accept empty messages */ + if (req->op.mod.message->num_elements == 0) { + ldb_set_errstring(ldb, "objectclass: modify message must have " + "elements/attributes!"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } ac = oc_init_context(module, req); if (ac == NULL) { @@ -715,6 +721,7 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req /* If no part of this touches the objectClass, then we don't * need to make any changes. */ + objectclass_element = ldb_msg_find_element(req->op.mod.message, "objectClass"); /* If the only operation is the deletion of the objectClass * then go on with just fixing the attribute case */ diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index fdb044198b..adb62d3544 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -1673,7 +1673,7 @@ static int build_domain_data_request(struct ph_context *ac) ldb = ldb_module_get_ctx(ac->module); filter = talloc_asprintf(ac, - "(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))", + "(&(objectSid=%s)(|(objectClass=domain)(objectClass=builtinDomain)))", ldap_encode_ndr_dom_sid(ac, ac->domain_sid)); if (filter == NULL) { ldb_oom(ldb); diff --git a/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c b/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c index 950f87eb74..6d814f9334 100644 --- a/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c @@ -27,6 +27,7 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "../lib/util/dlinklist.h" +#include "dsdb/samdb/ldb_modules/util.h" static int pdc_fsmo_init(struct ldb_module *module) { @@ -64,9 +65,9 @@ static int pdc_fsmo_init(struct ldb_module *module) } ldb_module_set_private(module, pdc_fsmo); - ret = ldb_search(ldb, mem_ctx, &pdc_res, - pdc_dn, LDB_SCOPE_BASE, - pdc_attrs, NULL); + ret = dsdb_module_search_dn(module, mem_ctx, &pdc_res, + pdc_dn, + pdc_attrs); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_debug(ldb, LDB_DEBUG_WARNING, "pdc_fsmo_init: no domain object present: (skip loading of domain details)\n"); @@ -79,19 +80,6 @@ static int pdc_fsmo_init(struct ldb_module *module) talloc_free(mem_ctx); return ret; } - if (pdc_res->count == 0) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - "pdc_fsmo_init: no domain object present: (skip loading of domain details)\n"); - talloc_free(mem_ctx); - return ldb_next_init(module); - } else if (pdc_res->count > 1) { - ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "pdc_fsmo_init: [%u] domain objects found on a base search", - pdc_res->count); - DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb))); - talloc_free(mem_ctx); - return LDB_ERR_CONSTRAINT_VIOLATION; - } pdc_fsmo->master_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, pdc_res->msgs[0], "fSMORoleOwner"); if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), pdc_fsmo->master_dn) == 0) { diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 2d87a017fd..2a0bb2dfe6 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -284,8 +284,7 @@ static int samldb_get_parent_domain(struct samldb_ctx *ac) ret = ldb_build_search_req(&req, ldb, ac, dn, LDB_SCOPE_BASE, "(|(objectClass=domain)" - "(objectClass=builtinDomain)" - "(objectClass=samba4LocalDomain))", + "(objectClass=builtinDomain))", attrs, NULL, ac, samldb_get_parent_domain_callback, @@ -559,10 +558,10 @@ static int samldb_get_sid_domain(struct samldb_ctx *ac) /* get the domain component part of the provided SID */ ac->domain_sid->num_auths--; - filter = talloc_asprintf(ac, "(&(objectSid=%s)" - "(|(objectClass=domain)" - "(objectClass=builtinDomain)" - "(objectClass=samba4LocalDomain)))", + filter = talloc_asprintf(ac, + "(&(objectSid=%s)" + "(|(objectClass=domain)" + "(objectClass=builtinDomain)))", ldap_encode_ndr_dom_sid(ac, ac->domain_sid)); if (filter == NULL) { return LDB_ERR_OPERATIONS_ERROR; diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c index c482ab57df..2b6606c147 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c @@ -5,6 +5,7 @@ checkings, it also loads the dsdb_schema. Copyright (C) Stefan Metzmacher <metze@samba.org> 2007 + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009 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 @@ -28,6 +29,7 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "param/param.h" +#include "dsdb/samdb/ldb_modules/util.h" static int generate_objectClasses(struct ldb_context *ldb, struct ldb_message *msg, const struct dsdb_schema *schema); @@ -90,13 +92,107 @@ struct schema_fsmo_search_data { const struct dsdb_schema *schema; }; +/* + Given an LDB module (pointing at the schema DB), and the DN, set the populated schema +*/ + +static int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_module *module, + struct smb_iconv_convenience *iconv_convenience, + struct ldb_dn *schema_dn, + struct dsdb_schema **schema) +{ + TALLOC_CTX *tmp_ctx; + char *error_string; + int ret; + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct ldb_result *schema_res; + struct ldb_result *a_res; + struct ldb_result *c_res; + static const char *schema_attrs[] = { + "prefixMap", + "schemaInfo", + "fSMORoleOwner", + NULL + }; + unsigned flags; + + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* we don't want to trace the schema load */ + flags = ldb_get_flags(ldb); + ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING); + + /* + * setup the prefix mappings and schema info + */ + ret = dsdb_module_search_dn(module, tmp_ctx, &schema_res, + schema_dn, schema_attrs); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + goto failed; + } else if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + "dsdb_schema: failed to search the schema head: %s", + ldb_errstring(ldb)); + goto failed; + } + + /* + * load the attribute definitions + */ + ret = dsdb_module_search(module, tmp_ctx, &a_res, + schema_dn, LDB_SCOPE_ONELEVEL, NULL, + "(objectClass=attributeSchema)"); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + "dsdb_schema: failed to search attributeSchema objects: %s", + ldb_errstring(ldb)); + goto failed; + } + + /* + * load the objectClass definitions + */ + ret = dsdb_module_search(module, tmp_ctx, &c_res, + schema_dn, LDB_SCOPE_ONELEVEL, NULL, + "(objectClass=classSchema)"); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + "dsdb_schema: failed to search attributeSchema objects: %s", + ldb_errstring(ldb)); + goto failed; + } + + ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb, + lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), + schema_res, a_res, c_res, schema, &error_string); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + "dsdb_schema load failed: %s", + error_string); + goto failed; + } + talloc_steal(mem_ctx, *schema); + +failed: + if (flags & LDB_FLG_ENABLE_TRACING) { + flags = ldb_get_flags(ldb); + ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING); + } + talloc_free(tmp_ctx); + return ret; +} + + static int schema_fsmo_init(struct ldb_module *module) { struct ldb_context *ldb; TALLOC_CTX *mem_ctx; struct ldb_dn *schema_dn; struct dsdb_schema *schema; - char *error_string = NULL; int ret; struct schema_fsmo_private_data *data; @@ -134,9 +230,9 @@ static int schema_fsmo_init(struct ldb_module *module) return LDB_ERR_OPERATIONS_ERROR; } - ret = dsdb_schema_from_schema_dn(mem_ctx, ldb, + ret = dsdb_schema_from_schema_dn(mem_ctx, module, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), - schema_dn, &schema, &error_string); + schema_dn, &schema); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_reset_err_string(ldb); @@ -147,9 +243,6 @@ static int schema_fsmo_init(struct ldb_module *module) } if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, - "schema_fsmo_init: dsdb_schema load failed: %s", - error_string); talloc_free(mem_ctx); return ret; } @@ -246,7 +339,6 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r struct ldb_context *ldb; struct ldb_dn *schema_dn; struct dsdb_schema *schema; - char *error_string = NULL; int ret; TALLOC_CTX *mem_ctx; @@ -270,9 +362,9 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r return LDB_ERR_OPERATIONS_ERROR; } - ret = dsdb_schema_from_schema_dn(mem_ctx, ldb, + ret = dsdb_schema_from_schema_dn(mem_ctx, module, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), - schema_dn, &schema, &error_string); + schema_dn, &schema); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_reset_err_string(ldb); @@ -283,9 +375,6 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r } if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, - "schema_fsmo_extended: dsdb_schema load failed: %s", - error_string); talloc_free(mem_ctx); return ldb_next_request(module, req); } diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c new file mode 100644 index 0000000000..476eb08ed0 --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -0,0 +1,128 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + + Copyright (C) Andrew Tridgell 2009 + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009 + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +#include "ldb.h" +#include "ldb_module.h" + +/* + search for attrs on one DN, in the modules below + */ +int dsdb_module_search_dn(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_result **_res, + struct ldb_dn *basedn, + const char * const *attrs) +{ + int ret; + struct ldb_request *req; + TALLOC_CTX *tmp_ctx; + struct ldb_result *res; + + tmp_ctx = talloc_new(mem_ctx); + + res = talloc_zero(tmp_ctx, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx, + basedn, + LDB_SCOPE_BASE, + NULL, + attrs, + NULL, + res, + ldb_search_default_callback, + NULL); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + ret = ldb_next_request(module, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + if (res->count != 1) { + /* we may be reading a DB that does not have the 'check base on search' option... */ + ret = LDB_ERR_NO_SUCH_OBJECT; + } else { + *_res = talloc_steal(mem_ctx, res); + } + talloc_free(tmp_ctx); + return ret; +} + +/* + search for attrs in the modules below + */ +int dsdb_module_search(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_result **_res, + struct ldb_dn *basedn, enum ldb_scope scope, + const char * const *attrs, + const char *expression) +{ + int ret; + struct ldb_request *req; + TALLOC_CTX *tmp_ctx; + struct ldb_result *res; + + tmp_ctx = talloc_new(mem_ctx); + + res = talloc_zero(tmp_ctx, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx, + basedn, + scope, + expression, + attrs, + NULL, + res, + ldb_search_default_callback, + NULL); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + ret = ldb_next_request(module, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + talloc_free(req); + if (ret == LDB_SUCCESS) { + *_res = talloc_steal(mem_ctx, res); + } + talloc_free(tmp_ctx); + return ret; +} + diff --git a/source4/dsdb/samdb/ldb_modules/util.h b/source4/dsdb/samdb/ldb_modules/util.h new file mode 100644 index 0000000000..0a1ab83c6d --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/util.h @@ -0,0 +1,22 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + + Copyright (C) Andrew Tridgell 2009 + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009 + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +#include "dsdb/samdb/ldb_modules/util_proto.h" diff --git a/source4/dsdb/schema/schema_inferiors.c b/source4/dsdb/schema/schema_inferiors.c index 3be97b6b83..ecac74a954 100644 --- a/source4/dsdb/schema/schema_inferiors.c +++ b/source4/dsdb/schema/schema_inferiors.c @@ -149,19 +149,22 @@ void schema_subclasses_order_recurse(struct dsdb_schema *schema, struct dsdb_cla return; } -static void schema_create_subclasses(struct dsdb_schema *schema) +static int schema_create_subclasses(struct dsdb_schema *schema) { - struct dsdb_class *schema_class; + struct dsdb_class *schema_class, *top; for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) { struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf); if (schema_class2 == NULL) { DEBUG(0,("ERROR: no subClassOf for '%s'\n", schema_class->lDAPDisplayName)); - continue; + return LDB_ERR_OPERATIONS_ERROR; } if (schema_class2 && schema_class != schema_class2) { if (schema_class2->subclasses_direct == NULL) { schema_class2->subclasses_direct = str_list_make_empty(schema_class2); + if (!schema_class2->subclasses_direct) { + return LDB_ERR_OPERATIONS_ERROR; + } } schema_class2->subclasses_direct = str_list_add_const(schema_class2->subclasses_direct, schema_class->lDAPDisplayName); @@ -175,7 +178,14 @@ static void schema_create_subclasses(struct dsdb_schema *schema) schema_class->subClass_order = 0; } - schema_subclasses_order_recurse(schema, dsdb_class_by_lDAPDisplayName(schema, "top"), 1); + top = dsdb_class_by_lDAPDisplayName(schema, "top"); + if (!top) { + DEBUG(0,("ERROR: no 'top' class in loaded schema\n")); + return LDB_ERR_OPERATIONS_ERROR; + } + + schema_subclasses_order_recurse(schema, top, 1); + return LDB_SUCCESS; } static void schema_fill_possible_inferiors(struct dsdb_schema *schema, struct dsdb_class *schema_class) @@ -294,13 +304,17 @@ static void schema_fill_from_ids(struct dsdb_schema *schema) } } -void schema_fill_constructed(struct dsdb_schema *schema) +int schema_fill_constructed(struct dsdb_schema *schema) { + int ret; struct dsdb_class *schema_class; schema_fill_from_ids(schema); - schema_create_subclasses(schema); + ret = schema_create_subclasses(schema); + if (ret != LDB_SUCCESS) { + return ret; + } for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) { schema_fill_possible_inferiors(schema, schema_class); @@ -318,4 +332,5 @@ void schema_fill_constructed(struct dsdb_schema *schema) schema_class->subclasses = NULL; schema_class->posssuperiors = NULL; } + return LDB_SUCCESS; } diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index b876ab09fc..9dd3ce0ccc 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -30,6 +30,8 @@ #include "param/param.h" #include "lib/ldb/include/ldb_module.h" +static WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes); + struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience) { struct dsdb_schema *schema = talloc_zero(mem_ctx, struct dsdb_schema); @@ -519,7 +521,7 @@ WERROR dsdb_write_prefixes_from_schema_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_co return WERR_OK; } -WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes) +static WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes) { struct prefixMapBlob *blob; enum ndr_err_code ndr_err; @@ -906,7 +908,7 @@ WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema, /* Create a DSDB schema from the ldb results provided. This is called directly when the schema is provisioned from an on-disk LDIF file, or - from dsdb_schema_from_schema_dn below + from dsdb_schema_from_schema_dn in schema_fsmo */ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, @@ -1013,115 +1015,6 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, return LDB_SUCCESS; } -/* - Given an LDB, and the DN, return a populated schema -*/ - -int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, - struct smb_iconv_convenience *iconv_convenience, - struct ldb_dn *schema_dn, - struct dsdb_schema **schema, - char **error_string_out) -{ - TALLOC_CTX *tmp_ctx; - char *error_string; - int ret; - - struct ldb_result *schema_res; - struct ldb_result *a_res; - struct ldb_result *c_res; - static const char *schema_attrs[] = { - "prefixMap", - "schemaInfo", - "fSMORoleOwner", - NULL - }; - unsigned flags; - - tmp_ctx = talloc_new(mem_ctx); - if (!tmp_ctx) { - dsdb_oom(error_string_out, mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* we don't want to trace the schema load */ - flags = ldb_get_flags(ldb); - ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING); - - /* - * setup the prefix mappings and schema info - */ - ret = ldb_search(ldb, tmp_ctx, &schema_res, - schema_dn, LDB_SCOPE_BASE, schema_attrs, NULL); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - goto failed; - } else if (ret != LDB_SUCCESS) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema: failed to search the schema head: %s", - ldb_errstring(ldb)); - goto failed; - } - if (schema_res->count != 1) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema: [%u] schema heads found on a base search", - schema_res->count); - goto failed; - } - - /* - * load the attribute definitions - */ - ret = ldb_search(ldb, tmp_ctx, &a_res, - schema_dn, LDB_SCOPE_ONELEVEL, NULL, - "(objectClass=attributeSchema)"); - if (ret != LDB_SUCCESS) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema: failed to search attributeSchema objects: %s", - ldb_errstring(ldb)); - goto failed; - } - - /* - * load the objectClass definitions - */ - ret = ldb_search(ldb, tmp_ctx, &c_res, - schema_dn, LDB_SCOPE_ONELEVEL, NULL, - "(objectClass=classSchema)"); - if (ret != LDB_SUCCESS) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema: failed to search attributeSchema objects: %s", - ldb_errstring(ldb)); - goto failed; - } - - ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb, - lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), - schema_res, a_res, c_res, schema, &error_string); - if (ret != LDB_SUCCESS) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema load failed: %s", - error_string); - goto failed; - } - talloc_steal(mem_ctx, *schema); - talloc_free(tmp_ctx); - - if (flags & LDB_FLG_ENABLE_TRACING) { - flags = ldb_get_flags(ldb); - ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING); - } - - return LDB_SUCCESS; - -failed: - if (flags & LDB_FLG_ENABLE_TRACING) { - flags = ldb_get_flags(ldb); - ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING); - } - talloc_free(tmp_ctx); - return ret; -} - static const struct { const char *name; diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c index 6f09f63596..9f22b32334 100644 --- a/source4/dsdb/schema/schema_set.c +++ b/source4/dsdb/schema/schema_set.c @@ -346,7 +346,10 @@ int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema) return ret; } - schema_fill_constructed(schema); + ret = schema_fill_constructed(schema); + if (ret != LDB_SUCCESS) { + return ret; + } ret = ldb_set_opaque(ldb, "dsdb_schema", schema); if (ret != LDB_SUCCESS) { diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 4c27de7cb7..e9c924583e 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -1358,14 +1358,6 @@ int ldb_modify(struct ldb_context *ldb, return ret; } - if (message->num_elements == 0) { - /* this needs also to be returned when the specified object - doesn't exist. Therefore this test is located here. */ - ldb_asprintf_errstring(ldb, "LDB message has to have elements/attributes (%s)!", - ldb_dn_get_linearized(message->dn)); - return LDB_ERR_UNWILLING_TO_PERFORM; - } - ret = ldb_build_mod_req(&req, ldb, ldb, message, NULL, diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index ea29a09a2a..69b8ed0bf4 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -96,6 +96,12 @@ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *m } talloc_steal(modules, modstr); + if (modstr[0] == '\0') { + modules[0] = NULL; + m = (const char **)modules; + return m; + } + i = 0; /* The str*r*chr walks backwards: This is how we get the inverse order mentioned above */ while ((p = strrchr(modstr, ',')) != NULL) { @@ -331,7 +337,7 @@ int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, str module = backend; - for (i = 0; module_list[i] != NULL; i++) { + for (i = 0; module_list && module_list[i] != NULL; i++) { struct ldb_module *current; const struct ldb_module_ops *ops; diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 7693ffeb81..4943f81df5 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -179,6 +179,8 @@ static int ltdb_check_special_dn(struct ldb_module *module, /* we have @ATTRIBUTES, let's check attributes are fine */ /* should we check that we deny multivalued attributes ? */ for (i = 0; i < msg->num_elements; i++) { + if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) continue; + for (j = 0; j < msg->elements[i].num_values; j++) { if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) { ldb_set_errstring(ldb, "Invalid attribute value in an @ATTRIBUTES entry"); @@ -205,12 +207,19 @@ static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn) ret = ltdb_reindex(module); } + /* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */ if (ret == LDB_SUCCESS && !(ldb_dn_is_special(dn) && ldb_dn_check_special(dn, LTDB_BASEINFO)) ) { ret = ltdb_increase_sequence_number(module); } + /* If the modify was to @OPTIONS, reload the cache */ + if (ldb_dn_is_special(dn) && + (ldb_dn_check_special(dn, LTDB_OPTIONS)) ) { + ret = ltdb_cache_reload(module); + } + return ret; } diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 869cd75465..bf2e22046a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -429,7 +429,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, hostname = hostname.lower() if dnsdomain is None: - dnsdomain = lp.get("realm") + dnsdomain = lp.get("realm").lower() if serverrole is None: serverrole = lp.get("server role") @@ -441,8 +441,6 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, raise Exception("realm '%s' in %s must match chosen realm '%s'" % (lp.get("realm"), lp.configfile, realm)) - dnsdomain = dnsdomain.lower() - if serverrole == "domain controller": if domain is None: domain = lp.get("workgroup") @@ -454,20 +452,21 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, else: domain = netbiosname if domaindn is None: - domaindn = "CN=" + netbiosname + domaindn = "DC=" + netbiosname assert domain is not None domain = domain.upper() + if not valid_netbios_name(domain): raise InvalidNetbiosName(domain) - if netbiosname.upper() == realm.upper(): + if netbiosname.upper() == realm: raise Exception("realm %s must not be equal to netbios domain name %s", realm, netbiosname) - if hostname.upper() == realm.upper(): + if hostname.upper() == realm: raise Exception("realm %s must not be equal to hostname %s", realm, hostname) - if domain.upper() == realm.upper(): + if domain.upper() == realm: raise Exception("realm %s must not be equal to domain name %s", realm, domain) if rootdn is None: @@ -883,9 +882,9 @@ def setup_self_join(samdb, names, """Join a host to its own domain.""" assert isinstance(invocationid, str) if ntdsguid is not None: - ntdsguid_mod = "objectGUID: %s\n"%ntdsguid + ntdsguid_line = "objectGUID: %s\n"%ntdsguid else: - ntdsguid_mod = "" + ntdsguid_line = "" setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, @@ -901,7 +900,7 @@ def setup_self_join(samdb, names, "DOMAIN": names.domain, "DNSDOMAIN": names.dnsdomain, "SAMBA_VERSION_STRING": version, - "NTDSGUID": ntdsguid_mod, + "NTDSGUID": ntdsguid_line, "DOMAIN_CONTROLLER_FUNCTIONALITY": str(domainControllerFunctionality)}) setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { @@ -1010,22 +1009,17 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, samdb.set_invocation_id(invocationid) message("Adding DomainDN: %s" % names.domaindn) - if serverrole == "domain controller": - domain_oc = "domainDNS" - else: - domain_oc = "samba4LocalDomain" #impersonate domain admin admin_session_info = admin_session(lp, str(domainsid)) samdb.set_session_info(admin_session_info) if domainguid is not None: - domainguid_mod = "objectGUID: %s\n-" % domainguid + domainguid_line = "objectGUID: %s\n-" % domainguid else: - domainguid_mod = "" + domainguid_line = "" setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { "DOMAINDN": names.domaindn, - "DOMAIN_OC": domain_oc, - "DOMAINGUID": domainguid_mod + "DOMAINGUID": domainguid_line }) diff --git a/source4/setup/provision_basedn.ldif b/source4/setup/provision_basedn.ldif index 0a5f618e84..eea8d4f148 100644 --- a/source4/setup/provision_basedn.ldif +++ b/source4/setup/provision_basedn.ldif @@ -3,6 +3,6 @@ ################################ dn: ${DOMAINDN} objectClass: top -objectClass: ${DOMAIN_OC} +objectClass: domaindns instanceType: 5 ${DOMAINGUID} diff --git a/source4/setup/schema_samba4.ldif b/source4/setup/schema_samba4.ldif index f447bf5617..ba867499d7 100644 --- a/source4/setup/schema_samba4.ldif +++ b/source4/setup/schema_samba4.ldif @@ -197,26 +197,29 @@ oMSyntax: 20 # Based on domainDNS, but without the DNS bits. # -dn: CN=Samba4-Local-Domain,${SCHEMADN} -objectClass: top -objectClass: classSchema -cn: Samba4-Local-Domain -subClassOf: top -governsID: 1.3.6.1.4.1.7165.4.2.2 -rDNAttID: cn -adminDisplayName: Samba4-Local-Domain -adminDescription: Samba4-Local-Domain -systemMayContain: msDS-Behavior-Version -systemMayContain: managedBy -objectClassCategory: 1 -lDAPDisplayName: samba4LocalDomain -schemaIDGUID: 07be1647-8310-4fba-91ae-34e55d5a8293 -systemOnly: FALSE -systemAuxiliaryClass: samDomain -defaultSecurityDescriptor: D:(A;;RPLCLORC;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU) -systemFlags: 16 -defaultHidingValue: TRUE -defaultObjectCategory: CN=Samba4-Local-Domain,${SCHEMADN} +# +# Not used anymore +# +#dn: CN=Samba4-Local-Domain,${SCHEMADN} +#objectClass: top +#objectClass: classSchema +#cn: Samba4-Local-Domain +#subClassOf: top +#governsID: 1.3.6.1.4.1.7165.4.2.2 +#rDNAttID: cn +#adminDisplayName: Samba4-Local-Domain +#adminDescription: Samba4-Local-Domain +#systemMayContain: msDS-Behavior-Version +#systemMayContain: managedBy +#objectClassCategory: 1 +#lDAPDisplayName: samba4LocalDomain +#schemaIDGUID: 07be1647-8310-4fba-91ae-34e55d5a8293 +#systemOnly: FALSE +#systemAuxiliaryClass: samDomain +#defaultSecurityDescriptor: D:(A;;RPLCLORC;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU) +#systemFlags: 16 +#defaultHidingValue: TRUE +#defaultObjectCategory: CN=Samba4-Local-Domain,${SCHEMADN} dn: CN=Samba4Top,${SCHEMADN} |