X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source4%2Fdsdb%2Fsamdb%2Fldb_modules%2Fextended_dn_in.c;h=3d29b7554b4cffe98c506e3b159daed261bc2842;hb=ba06cdb413de29fe3e33ef9891dcf61c25cfbbbe;hp=c3db4fa588916f6f474499a4c53c2992737c0221;hpb=5076c64d43c68a028ac944c336715b4cb277365f;p=nivanova%2Fsamba.git diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c index c3db4fa5889..3d29b7554b4 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c @@ -32,7 +32,12 @@ #include "includes.h" #include "ldb/include/ldb.h" #include "ldb/include/ldb_errors.h" -#include "ldb/include/ldb_private.h" +#include "ldb/include/ldb_module.h" + +/* + TODO: if relax is not set then we need to reject the fancy RMD_* and + DELETED extended DN codes + */ /* search */ struct extended_search_context { @@ -80,7 +85,7 @@ static int extended_base_callback(struct ldb_request *req, struct ldb_reply *are struct ldb_request *down_req; struct ldb_message_element *el; int ret; - size_t i; + unsigned int i; size_t wkn_len = 0; char *valstr = NULL; const char *found = NULL; @@ -116,7 +121,7 @@ static int extended_base_callback(struct ldb_request *req, struct ldb_reply *are (const char *)el->values[i].data, el->values[i].length); if (!valstr) { - ldb_oom(ac->module->ldb); + ldb_oom(ldb_module_get_ctx(ac->module)); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } @@ -134,10 +139,10 @@ static int extended_base_callback(struct ldb_request *req, struct ldb_reply *are break; } - ac->basedn = ldb_dn_new(ac, ac->module->ldb, found); + ac->basedn = ldb_dn_new(ac, ldb_module_get_ctx(ac->module), found); talloc_free(valstr); if (!ac->basedn) { - ldb_oom(ac->module->ldb); + ldb_oom(ldb_module_get_ctx(ac->module)); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } @@ -151,8 +156,8 @@ static int extended_base_callback(struct ldb_request *req, struct ldb_reply *are if (!ac->basedn) { const char *str = talloc_asprintf(req, "Base-DN '%s' not found", - ldb_dn_get_linearized(ac->req->op.search.base)); - ldb_set_errstring(ac->module->ldb, str); + ldb_dn_get_extended_linearized(req, ac->req->op.search.base, 1)); + ldb_set_errstring(ldb_module_get_ctx(ac->module), str); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_NO_SUCH_OBJECT); } @@ -160,7 +165,7 @@ static int extended_base_callback(struct ldb_request *req, struct ldb_reply *are switch (ac->req->operation) { case LDB_SEARCH: ret = ldb_build_search_req_ex(&down_req, - ac->module->ldb, ac->req, + ldb_module_get_ctx(ac->module), ac->req, ac->basedn, ac->req->op.search.scope, ac->req->op.search.tree, @@ -168,12 +173,14 @@ static int extended_base_callback(struct ldb_request *req, struct ldb_reply *are ac->req->controls, ac, extended_final_callback, ac->req); + ldb_req_mark_trusted(down_req); + LDB_REQ_SET_LOCATION(down_req); break; case LDB_ADD: { struct ldb_message *add_msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message); if (!add_msg) { - ldb_oom(ac->module->ldb); + ldb_oom(ldb_module_get_ctx(ac->module)); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } @@ -181,18 +188,19 @@ static int extended_base_callback(struct ldb_request *req, struct ldb_reply *are add_msg->dn = ac->basedn; ret = ldb_build_add_req(&down_req, - ac->module->ldb, ac->req, + ldb_module_get_ctx(ac->module), ac->req, add_msg, ac->req->controls, ac, extended_final_callback, ac->req); + LDB_REQ_SET_LOCATION(down_req); break; } case LDB_MODIFY: { struct ldb_message *mod_msg = ldb_msg_copy_shallow(ac, ac->req->op.mod.message); if (!mod_msg) { - ldb_oom(ac->module->ldb); + ldb_oom(ldb_module_get_ctx(ac->module)); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } @@ -200,29 +208,32 @@ static int extended_base_callback(struct ldb_request *req, struct ldb_reply *are mod_msg->dn = ac->basedn; ret = ldb_build_mod_req(&down_req, - ac->module->ldb, ac->req, + ldb_module_get_ctx(ac->module), ac->req, mod_msg, ac->req->controls, ac, extended_final_callback, ac->req); + LDB_REQ_SET_LOCATION(down_req); break; } case LDB_DELETE: ret = ldb_build_del_req(&down_req, - ac->module->ldb, ac->req, + ldb_module_get_ctx(ac->module), ac->req, ac->basedn, ac->req->controls, ac, extended_final_callback, ac->req); + LDB_REQ_SET_LOCATION(down_req); break; case LDB_RENAME: ret = ldb_build_rename_req(&down_req, - ac->module->ldb, ac->req, + ldb_module_get_ctx(ac->module), ac->req, ac->basedn, ac->req->op.rename.newdn, ac->req->controls, ac, extended_final_callback, ac->req); + LDB_REQ_SET_LOCATION(down_req); break; default: return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); @@ -255,6 +266,7 @@ static int extended_dn_in_fix(struct ldb_module *module, struct ldb_request *req "wellKnownObjects", NULL }; + bool all_partitions = false; if (!ldb_dn_has_extended(dn)) { /* Move along there isn't anything to see here */ @@ -262,32 +274,55 @@ static int extended_dn_in_fix(struct ldb_module *module, struct ldb_request *req } else { /* It looks like we need to map the DN */ const struct ldb_val *sid_val, *guid_val, *wkguid_val; + int num_components = ldb_dn_get_comp_num(dn); + int num_ex_components = ldb_dn_get_extended_comp_num(dn); + + /* + windows ldap searchs don't allow a baseDN with more + than one extended component, or an extended + component and a string DN + + We only enforce this over ldap, not for internal + use, as there are just too many places where we + internally want to use a DN that has come from a + search with extended DN enabled, or comes from a DRS + naming context. + + Enforcing this would also make debugging samba much + harder, as we'd need to use ldb_dn_minimise() in a + lot of places, and that would lose the DN string + which is so useful for working out what a request is + for + */ + if ((num_components != 0 || num_ex_components != 1) && + ldb_req_is_untrusted(req)) { + return ldb_error(ldb_module_get_ctx(module), + LDB_ERR_INVALID_DN_SYNTAX, "invalid number of DN components"); + } sid_val = ldb_dn_get_extended_component(dn, "SID"); guid_val = ldb_dn_get_extended_component(dn, "GUID"); wkguid_val = ldb_dn_get_extended_component(dn, "WKGUID"); if (sid_val) { - /* TODO: do a search over all partitions */ - base_dn = ldb_get_default_basedn(module->ldb); + all_partitions = true; + base_dn = ldb_get_default_basedn(ldb_module_get_ctx(module)); base_dn_filter = talloc_asprintf(req, "(objectSid=%s)", ldb_binary_encode(req, *sid_val)); if (!base_dn_filter) { - ldb_oom(module->ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ldb_oom(ldb_module_get_ctx(module)); } base_dn_scope = LDB_SCOPE_SUBTREE; base_dn_attrs = no_attr; } else if (guid_val) { - /* TODO: do a search over all partitions */ - base_dn = ldb_get_default_basedn(module->ldb); + all_partitions = true; + base_dn = ldb_get_default_basedn(ldb_module_get_ctx(module)); base_dn_filter = talloc_asprintf(req, "(objectGUID=%s)", ldb_binary_encode(req, *guid_val)); if (!base_dn_filter) { - ldb_oom(module->ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ldb_oom(ldb_module_get_ctx(module)); } base_dn_scope = LDB_SCOPE_SUBTREE; base_dn_attrs = no_attr; @@ -302,7 +337,8 @@ static int extended_dn_in_fix(struct ldb_module *module, struct ldb_request *req p = strchr(wkguid_dup, ','); if (!p) { - return LDB_ERR_INVALID_DN_SYNTAX; + return ldb_error(ldb_module_get_ctx(module), LDB_ERR_INVALID_DN_SYNTAX, + "Invalid WKGUID format"); } p[0] = '\0'; @@ -310,33 +346,30 @@ static int extended_dn_in_fix(struct ldb_module *module, struct ldb_request *req wellknown_object = talloc_asprintf(req, "B:32:%s:", wkguid_dup); if (!wellknown_object) { - ldb_oom(module->ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ldb_oom(ldb_module_get_ctx(module)); } tail_str = p; - base_dn = ldb_dn_new(req, module->ldb, tail_str); + base_dn = ldb_dn_new(req, ldb_module_get_ctx(module), tail_str); talloc_free(wkguid_dup); if (!base_dn) { - ldb_oom(module->ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ldb_oom(ldb_module_get_ctx(module)); } base_dn_filter = talloc_strdup(req, "(objectClass=*)"); if (!base_dn_filter) { - ldb_oom(module->ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ldb_oom(ldb_module_get_ctx(module)); } base_dn_scope = LDB_SCOPE_BASE; base_dn_attrs = wkattr; } else { - return LDB_ERR_INVALID_DN_SYNTAX; + return ldb_error(ldb_module_get_ctx(module), LDB_ERR_INVALID_DN_SYNTAX, + "Invalid extended DN component"); } ac = talloc_zero(req, struct extended_search_context); if (ac == NULL) { - ldb_oom(module->ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ldb_oom(ldb_module_get_ctx(module)); } ac->module = module; @@ -348,16 +381,30 @@ static int extended_dn_in_fix(struct ldb_module *module, struct ldb_request *req * GUID) then search for that, so we can proceed with the original operation */ ret = ldb_build_search_req(&down_req, - module->ldb, ac, + ldb_module_get_ctx(module), ac, base_dn, base_dn_scope, base_dn_filter, base_dn_attrs, - NULL, + req->controls, ac, extended_base_callback, req); + LDB_REQ_SET_LOCATION(down_req); if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; + return ldb_operr(ldb_module_get_ctx(module)); + } + + if (all_partitions) { + struct ldb_search_options_control *control; + control = talloc(down_req, struct ldb_search_options_control); + control->search_options = 2; + ret = ldb_request_replace_control(down_req, + LDB_CONTROL_SEARCH_OPTIONS_OID, + true, control); + if (ret != LDB_SUCCESS) { + ldb_oom(ldb_module_get_ctx(module)); + return ret; + } } /* perform the search */ @@ -385,10 +432,16 @@ static int extended_dn_in_rename(struct ldb_module *module, struct ldb_request * return extended_dn_in_fix(module, req, req->op.rename.olddn); } -_PUBLIC_ const struct ldb_module_ops ldb_extended_dn_in_module_ops = { +static const struct ldb_module_ops ldb_extended_dn_in_module_ops = { .name = "extended_dn_in", .search = extended_dn_in_search, .modify = extended_dn_in_modify, .del = extended_dn_in_del, .rename = extended_dn_in_rename, }; + +int ldb_extended_dn_in_module_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_extended_dn_in_module_ops); +}