diff options
Diffstat (limited to 'source4/lib/ldb/modules/rdn_name.c')
-rw-r--r-- | source4/lib/ldb/modules/rdn_name.c | 453 |
1 files changed, 0 insertions, 453 deletions
diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c deleted file mode 100644 index 50b63aee13..0000000000 --- a/source4/lib/ldb/modules/rdn_name.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Bartlett 2005-2009 - Copyright (C) Simo Sorce 2006-2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -/* - * Name: rdn_name - * - * Component: ldb rdn name module - * - * Description: keep a consistent name attribute on objects manpulations - * - * Author: Andrew Bartlett - * - * Modifications: - * - made the module async - * Simo Sorce Mar 2006 - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -struct rename_context { - struct ldb_module *module; - struct ldb_request *req; - - struct ldb_reply *ares; -}; - -static int rdn_name_add_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct rename_context *ac; - - ac = talloc_get_type(req->context, struct rename_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - if (ares->type == LDB_REPLY_REFERRAL) { - return ldb_module_send_referral(ac->req, ares->referral); - } - - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - if (ares->type != LDB_REPLY_DONE) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return ldb_module_done(ac->req, ares->controls, - ares->response, LDB_SUCCESS); -} - -static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct ldb_request *down_req; - struct rename_context *ac; - struct ldb_message *msg; - struct ldb_message_element *attribute; - const struct ldb_schema_attribute *a; - const char *rdn_name; - const struct ldb_val *rdn_val_p; - struct ldb_val rdn_val; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.add.message->dn)) { - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct rename_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - msg = ldb_msg_copy_shallow(req, req->op.add.message); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_name = ldb_dn_get_rdn_name(msg->dn); - if (rdn_name == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_val_p = ldb_dn_get_rdn_val(msg->dn); - if (rdn_val_p == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (rdn_val_p->length == 0) { - ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", - ldb_dn_get_linearized(req->op.add.message->dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - rdn_val = ldb_val_dup(msg, rdn_val_p); - - /* Perhaps someone above us tried to set this? Then ignore it */ - ldb_msg_remove_attr(msg, "name"); - - ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); - if (ret != LDB_SUCCESS) { - return ret; - } - - a = ldb_schema_attribute_by_name(ldb, rdn_name); - if (a == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - attribute = ldb_msg_find_element(msg, rdn_name); - if (!attribute) { - /* add entry with normalised RDN information if possible */ - if (a->name != NULL) { - ret = ldb_msg_add_value(msg, a->name, &rdn_val, NULL); - } else { - ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); - } - if (ret != LDB_SUCCESS) { - return ret; - } - } else { - /* normalise attribute name if possible */ - if (a->name != NULL) { - attribute->name = a->name; - } - /* normalise attribute value */ - for (i = 0; i < attribute->num_values; i++) { - bool matched; - if (a->syntax->operator_fn) { - ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, - &rdn_val, &attribute->values[i], &matched); - if (ret != LDB_SUCCESS) return ret; - } else { - matched = (a->syntax->comparison_fn(ldb, msg, - &rdn_val, &attribute->values[i]) == 0); - } - if (matched) { - /* overwrite so it matches in case */ - attribute->values[i] = rdn_val; - break; - } - } - if (i == attribute->num_values) { - char *rdn_errstring = talloc_asprintf(ac, - "RDN mismatch on %s: %s (%.*s) should match one of:", - ldb_dn_get_linearized(msg->dn), rdn_name, - (int)rdn_val.length, (const char *)rdn_val.data); - for (i = 0; i < attribute->num_values; i++) { - rdn_errstring = talloc_asprintf_append( - rdn_errstring, " (%.*s)", - (int)attribute->values[i].length, - (const char *)attribute->values[i].data); - } - ldb_set_errstring(ldb, rdn_errstring); - /* Match AD's error here */ - return LDB_ERR_INVALID_DN_SYNTAX; - } - } - - ret = ldb_build_add_req(&down_req, ldb, req, - msg, - req->controls, - ac, rdn_name_add_callback, - req); - if (ret != LDB_SUCCESS) { - return ret; - } - - talloc_steal(down_req, msg); - - /* go on with the call chain */ - return ldb_next_request(module, down_req); -} - -static int rdn_modify_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct rename_context *ac; - - ac = talloc_get_type(req->context, struct rename_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - if (ares->type == LDB_REPLY_REFERRAL) { - return ldb_module_send_referral(ac->req, ares->referral); - } - - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - /* the only supported reply right now is a LDB_REPLY_DONE */ - if (ares->type != LDB_REPLY_DONE) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* send saved controls eventually */ - return ldb_module_done(ac->req, ac->ares->controls, - ac->ares->response, LDB_SUCCESS); -} - -static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct rename_context *ac; - struct ldb_request *mod_req; - const char *rdn_name; - const struct ldb_val *rdn_val_p; - struct ldb_val rdn_val; - struct ldb_message *msg; - int ret; - - ac = talloc_get_type(req->context, struct rename_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - goto error; - } - - if (ares->type == LDB_REPLY_REFERRAL) { - return ldb_module_send_referral(ac->req, ares->referral); - } - - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - /* the only supported reply right now is a LDB_REPLY_DONE */ - if (ares->type != LDB_REPLY_DONE) { - goto error; - } - - /* save reply for caller */ - ac->ares = talloc_steal(ac, ares); - - msg = ldb_msg_new(ac); - if (msg == NULL) { - goto error; - } - msg->dn = ldb_dn_copy(msg, ac->req->op.rename.newdn); - if (msg->dn == NULL) { - goto error; - } - - rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn); - if (rdn_name == NULL) { - goto error; - } - - rdn_val_p = ldb_dn_get_rdn_val(msg->dn); - if (rdn_val_p == NULL) { - goto error; - } - if (rdn_val_p->length == 0) { - ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", - ldb_dn_get_linearized(req->op.rename.olddn)); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_NAMING_VIOLATION); - } - rdn_val = ldb_val_dup(msg, rdn_val_p); - - if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { - goto error; - } - if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { - goto error; - } - if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { - goto error; - } - if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { - goto error; - } - - ret = ldb_build_mod_req(&mod_req, ldb, - ac, msg, NULL, - ac, rdn_modify_callback, - req); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - talloc_steal(mod_req, msg); - - /* go on with the call chain */ - return ldb_next_request(ac->module, mod_req); - -error: - return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); -} - -static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct rename_context *ac; - struct ldb_request *down_req; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.rename.newdn)) { - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct rename_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - ret = ldb_build_rename_req(&down_req, - ldb, - ac, - req->op.rename.olddn, - req->op.rename.newdn, - req->controls, - ac, - rdn_rename_callback, - req); - - if (ret != LDB_SUCCESS) { - return ret; - } - - /* rename first, modify "name" if rename is ok */ - return ldb_next_request(module, down_req); -} - -static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - const struct ldb_val *rdn_val_p; - - ldb = ldb_module_get_ctx(module); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.mod.message->dn)) { - return ldb_next_request(module, req); - } - - rdn_val_p = ldb_dn_get_rdn_val(req->op.mod.message->dn); - if (rdn_val_p == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (rdn_val_p->length == 0) { - ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", - ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - if (ldb_msg_find_element(req->op.mod.message, "distinguishedName")) { - ldb_asprintf_errstring(ldb, "Modify of 'distinguishedName' on %s not permitted, must use 'rename' operation instead", - ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - if (ldb_msg_find_element(req->op.mod.message, "name")) { - ldb_asprintf_errstring(ldb, "Modify of 'name' on %s not permitted, must use 'rename' operation instead", - ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_NOT_ALLOWED_ON_RDN; - } - - if (ldb_msg_find_element(req->op.mod.message, ldb_dn_get_rdn_name(req->op.mod.message->dn))) { - ldb_asprintf_errstring(ldb, "Modify of RDN '%s' on %s not permitted, must use 'rename' operation instead", - ldb_dn_get_rdn_name(req->op.mod.message->dn), ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_NOT_ALLOWED_ON_RDN; - } - - /* All OK, they kept their fingers out of the special attributes */ - return ldb_next_request(module, req); -} - -static int rdn_name_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - const char *rdn_name; - const struct ldb_val *rdn_val_p; - - ldb = ldb_module_get_ctx(module); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.search.base)) { - return ldb_next_request(module, req); - } - - rdn_name = ldb_dn_get_rdn_name(req->op.search.base); - rdn_val_p = ldb_dn_get_rdn_val(req->op.search.base); - if ((rdn_name != NULL) && (rdn_val_p == NULL)) { - return LDB_ERR_OPERATIONS_ERROR; - } - if ((rdn_val_p != NULL) && (rdn_val_p->length == 0)) { - ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", - ldb_dn_get_linearized(req->op.search.base)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - return ldb_next_request(module, req); -} - -static const struct ldb_module_ops ldb_rdn_name_module_ops = { - .name = "rdn_name", - .add = rdn_name_add, - .modify = rdn_name_modify, - .rename = rdn_name_rename, - .search = rdn_name_search -}; - -int ldb_rdn_name_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_rdn_name_module_ops); -} |