diff options
Diffstat (limited to 'source4/dsdb')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/config.mk | 11 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/extended_dn.c | 308 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/objectguid.c | 4 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/password_hash.c | 7 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/proxy.c | 5 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/rootdse.c | 56 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samba3sam.c | 4 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samldb.c | 4 |
8 files changed, 392 insertions, 7 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index a18d2c4359..7fc0522034 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -69,3 +69,14 @@ REQUIRED_SUBSYSTEMS = \ # End MODULE libldb_rootdse ################################################ +################################################ +# Start MODULE libldb_extended_dn +[MODULE::libldb_extended_dn] +SUBSYSTEM = LIBLDB +OUTPUT_TYPE = MERGEDOBJ +OBJ_FILES = \ + extended_dn.o +# +# End MODULE libldb_extended_dn +################################################ + diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn.c b/source4/dsdb/samdb/ldb_modules/extended_dn.c new file mode 100644 index 0000000000..49af8604d5 --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/extended_dn.c @@ -0,0 +1,308 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005 + + ** 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * Name: ldb + * + * Component: ldb extended dn control module + * + * Description: this module builds a special dn + * + * Author: Simo Sorce + */ + +#include "includes.h" +#include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" +#include "ldb/include/ldb_private.h" +#include "dsdb/samdb/samdb.h" + +#include <time.h> + +static BOOL is_attr_in_list(const char * const * attrs, const char *attr) +{ + int i; + + for (i = 0; attrs[i]; i++) { + if (strcasecmp(attrs[i], attr) == 0) + return True; + } + + return False; +} + +static char **copy_attrs(void *mem_ctx, const char * const * attrs) +{ + char **new; + int i, num; + + for (num = 0; attrs[num]; num++); + + new = talloc_array(mem_ctx, char *, num + 1); + if (!new) return NULL; + + for(i = 0; i < num; i++) { + new[i] = talloc_strdup(new, attrs[i]); + if (!new[i]) { + talloc_free(new); + return NULL; + } + } + new[i] = NULL; + + return new; +} + +static BOOL add_attrs(void *mem_ctx, char ***attrs, const char *attr) +{ + char **new; + int num; + + for (num = 0; (*attrs)[num]; num++); + + new = talloc_realloc(mem_ctx, *attrs, char *, num + 2); + if (!new) return False; + + *attrs = new; + + new[num] = talloc_strdup(new, attr); + if (!new[num]) return False; + + new[num + 1] = NULL; + + return True; +} + +static BOOL inject_extended_dn(struct ldb_message *msg, + int type, + BOOL remove_guid, + BOOL remove_sid) +{ + const struct ldb_val *val; + struct GUID guid; + struct dom_sid *sid; + char *object_guid; + char *object_sid; + char *new_dn, *dn; + + dn = ldb_dn_linearize(msg, msg->dn); + if (!dn) + return False; + + /* retrieve object_guid */ + guid = samdb_result_guid(msg, "objectGUID"); + object_guid = GUID_string(msg, &guid); + if (!object_guid) + return False; + + if (remove_guid) + ldb_msg_remove_attr(msg, "objectGUID"); + + /* retrieve object_sid */ + object_sid = NULL; + sid = samdb_result_dom_sid(msg, msg, "objectSID"); + if (sid) { + object_sid = dom_sid_string(msg, sid); + if (!object_sid) + return False; + + if (remove_sid) + ldb_msg_remove_attr(msg, "objectSID"); + } + + /* TODO: handle type */ + switch (type) { + case 0: + case 1: + if (object_sid) { + new_dn = talloc_asprintf(msg, "<GUID=%s>;<SID=%s>;%s", + object_guid, object_sid, dn); + } else { + new_dn = talloc_asprintf(msg, "<GUID=%s>;%s", + object_guid, dn); + } + break; + default: + return False; + } + + if (!new_dn) + return False; + + msg->dn = ldb_dn_explode_or_special(msg, new_dn); + if (!msg->dn) + return False; + + val = ldb_msg_find_ldb_val(msg, "distinguishedName"); + if (val) { + ldb_msg_remove_attr(msg, "distinguishedName"); + if (ldb_msg_add_string(msg, "distinguishedName", new_dn)) + return False; + } + + return True; +} + +/* search */ +static int extended_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_result *extended_result; + struct ldb_control *control; + struct ldb_control **saved_controls; + struct ldb_extended_dn_control *extended_ctrl; + int i, ret; + const char * const *saved_attrs = NULL; + char **new_attrs; + BOOL remove_guid = False; + BOOL remove_sid = False; + + /* check if there's a paged request control */ + control = get_control_from_list(req->controls, LDB_CONTROL_EXTENDED_DN_OID); + if (control == NULL) { + /* not found go on */ + return ldb_next_request(module, req); + } + + extended_ctrl = talloc_get_type(control->data, struct ldb_extended_dn_control); + + /* save it locally and remove it from the list */ + if (!save_controls(control, req, &saved_controls)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* check if attrs only is specified, in that case check wether we need to modify them */ + if (req->op.search.attrs) { + if (! is_attr_in_list(req->op.search.attrs, "objectGUID")) { + remove_guid = True; + } + if (! is_attr_in_list(req->op.search.attrs, "objectSID")) { + remove_sid = True; + } + if (remove_guid || remove_sid) { + new_attrs = copy_attrs(req, req->op.search.attrs); + if (!new_attrs) + return LDB_ERR_OPERATIONS_ERROR; + + saved_attrs = req->op.search.attrs; + + if (remove_guid) { + if (!add_attrs(req, &new_attrs, "objectGUID")) + return LDB_ERR_OPERATIONS_ERROR; + } + if (remove_sid) { + if (!add_attrs(req, &new_attrs, "objectSID")) + return LDB_ERR_OPERATIONS_ERROR; + } + + req->op.search.attrs = (const char * const *)new_attrs; + } + } + + ret = ldb_next_request(module, req); + + /* put request back into original shape */ + /* TODO: build a new req and don't touch the original one */ + + if (req->controls) talloc_free(req->controls); + req->controls = saved_controls; + + if (saved_attrs) { + talloc_free(new_attrs); + req->op.search.attrs = saved_attrs; + } + + if (ret != LDB_SUCCESS) { + return ret; + } + + extended_result = req->op.search.res; + + for (i = 0; i < extended_result->count; i++) { + /* TODO: the following funtion updates only dn and + * distinguishedName. We still need to address other + * DN entries like objectCategory + */ + if (!inject_extended_dn(extended_result->msgs[i], + extended_ctrl->type, + remove_guid, remove_sid)) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + return LDB_SUCCESS; +} + +static int extended_request(struct ldb_module *module, struct ldb_request *req) +{ + switch (req->operation) { + + case LDB_REQ_SEARCH: + return extended_search(module, req); + + default: + return ldb_next_request(module, req); + + } +} + +static const struct ldb_module_ops extended_dn_ops = { + .name = "extended_dn", + .request = extended_request, +}; + +#ifdef HAVE_DLOPEN_DISABLED +struct ldb_module *init_module(struct ldb_context *ldb, int stage, const char *options[]) +#else +struct ldb_module *extended_dn_module_init(struct ldb_context *ldb, int stage, const char *options[]) +#endif +{ + struct ldb_module *ctx; + + if (stage == LDB_MODULES_INIT_STAGE_2) { + struct ldb_request request; + int ret; + + request.operation = LDB_REQ_REGISTER; + request.op.reg.oid = LDB_CONTROL_EXTENDED_DN_OID; + request.controls = NULL; + + ret = ldb_request(ldb, &request); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "extended_dn: Unable to register control with rootdse!\n"); + } + + return NULL; + } + + ctx = talloc(ldb, struct ldb_module); + if (!ctx) + return NULL; + + ctx->ldb = ldb; + ctx->prev = ctx->next = NULL; + ctx->ops = &extended_dn_ops; + ctx->private_data = NULL; + + return ctx; +} diff --git a/source4/dsdb/samdb/ldb_modules/objectguid.c b/source4/dsdb/samdb/ldb_modules/objectguid.c index c9063af6ef..935f92c55b 100644 --- a/source4/dsdb/samdb/ldb_modules/objectguid.c +++ b/source4/dsdb/samdb/ldb_modules/objectguid.c @@ -128,10 +128,12 @@ static const struct ldb_module_ops objectguid_ops = { /* the init function */ -struct ldb_module *objectguid_module_init(struct ldb_context *ldb, const char *options[]) +struct ldb_module *objectguid_module_init(struct ldb_context *ldb, int stage, const char *options[]) { struct ldb_module *ctx; + if (stage != LDB_MODULES_INIT_STAGE_1) return NULL; + ctx = talloc(ldb, struct ldb_module); if (!ctx) return NULL; diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index e0fc50f242..82e4639a23 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -147,6 +147,7 @@ static int password_hash_handle(struct ldb_module *module, struct ldb_request *r search_request->op.search.scope = LDB_SCOPE_BASE; search_request->op.search.tree = ldb_parse_tree(module->ldb, NULL); search_request->op.search.attrs = old_user_attrs; + search_request->controls = NULL; old_ret = ldb_next_request(module, search_request); } @@ -253,6 +254,7 @@ static int password_hash_handle(struct ldb_module *module, struct ldb_request *r search_request->op.search.scope = LDB_SCOPE_BASE; search_request->op.search.tree = ldb_parse_tree(module->ldb, NULL); search_request->op.search.attrs = user_attrs; + search_request->controls = NULL; ret = ldb_next_request(module, search_request); if (ret) { @@ -656,6 +658,7 @@ static int password_hash_handle(struct ldb_module *module, struct ldb_request *r modify_request->operation = LDB_REQ_MODIFY; modify_request->op.mod.message = modify_msg; + modify_request->controls = NULL; ret = ldb_next_request(module, modify_request); @@ -714,10 +717,12 @@ static const struct ldb_module_ops password_hash_ops = { /* the init function */ -struct ldb_module *password_hash_module_init(struct ldb_context *ldb, const char *options[]) +struct ldb_module *password_hash_module_init(struct ldb_context *ldb, int stage, const char *options[]) { struct ldb_module *ctx; + if (stage != LDB_MODULES_INIT_STAGE_1) return NULL; + ctx = talloc(ldb, struct ldb_module); if (!ctx) return NULL; diff --git a/source4/dsdb/samdb/ldb_modules/proxy.c b/source4/dsdb/samdb/ldb_modules/proxy.c index cbe404fc4b..540f4241b9 100644 --- a/source4/dsdb/samdb/ldb_modules/proxy.c +++ b/source4/dsdb/samdb/ldb_modules/proxy.c @@ -288,6 +288,7 @@ static int proxy_search_bytree(struct ldb_module *module, struct ldb_request *re newreq.op.search.scope = req->op.search.scope; newreq.op.search.attrs = req->op.search.attrs; newreq.op.search.res = req->op.search.res; + newreq.controls = req->controls; ret = ldb_request(proxy->upstream, &newreq); if (ret != LDB_SUCCESS) { ldb_set_errstring(module, talloc_strdup(module, ldb_errstring(proxy->upstream))); @@ -332,10 +333,12 @@ static const struct ldb_module_ops proxy_ops = { .request = proxy_request }; -struct ldb_module *proxy_module_init(struct ldb_context *ldb, const char *options[]) +struct ldb_module *proxy_module_init(struct ldb_context *ldb, int stage, const char *options[]) { struct ldb_module *ctx; + if (stage != LDB_MODULES_INIT_STAGE_1) return NULL; + ctx = talloc(ldb, struct ldb_module); if (!ctx) return NULL; diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 93bc9903ed..8e0c231301 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -4,6 +4,7 @@ rootDSE ldb module Copyright (C) Andrew Tridgell 2005 + Copyright (C) Simo Sorce 2005 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 @@ -27,6 +28,11 @@ #include "auth/gensec/gensec.h" #include <time.h> +struct private_data { + int num_controls; + char **controls; +}; + /* return 1 if a specific attribute has been requested */ @@ -42,6 +48,7 @@ static int do_attribute(const char * const *attrs, const char *name) */ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_request *req) { + struct private_data *priv = talloc_get_type(module->private_data, struct private_data); struct ldb_search *s = &req->op.search; struct ldb_message *msg; struct cli_credentials *server_creds; @@ -63,6 +70,16 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_request *re } } + if (do_attribute(s->attrs, "supportedControl")) { + int i; + for (i = 0; i < priv->num_controls; i++) { + if (ldb_msg_add_string(msg, "supportedControl", + priv->controls[i]) != 0) { + goto failed; + } + } + } + server_creds = talloc_get_type(ldb_get_opaque(module->ldb, "server_credentials"), struct cli_credentials); if (do_attribute(s->attrs, "supportedSASLMechanisms")) { @@ -130,12 +147,35 @@ static int rootdse_search_bytree(struct ldb_module *module, struct ldb_request * return ret; } +static int rootdse_register_control(struct ldb_module *module, struct ldb_request *req) +{ + struct private_data *priv = talloc_get_type(module->private_data, struct private_data); + char **list; + + list = talloc_realloc(priv, priv->controls, char *, priv->num_controls + 1); + if (!list) { + return LDB_ERR_OPERATIONS_ERROR; + } + + list[priv->num_controls] = talloc_strdup(list, req->op.reg.oid); + if (!list[priv->num_controls]) { + return LDB_ERR_OPERATIONS_ERROR; + } + + priv->num_controls += 1; + priv->controls = list; + + return LDB_SUCCESS; +} + static int rootdse_request(struct ldb_module *module, struct ldb_request *req) { switch (req->operation) { case LDB_REQ_SEARCH: return rootdse_search_bytree(module, req); + case LDB_REQ_REGISTER: + return rootdse_register_control(module, req); default: break; } @@ -147,18 +187,30 @@ static const struct ldb_module_ops rootdse_ops = { .request = rootdse_request }; -struct ldb_module *rootdse_module_init(struct ldb_context *ldb, const char *options[]) +struct ldb_module *rootdse_module_init(struct ldb_context *ldb, int stage, const char *options[]) { struct ldb_module *ctx; + struct private_data *data; + + if (stage != LDB_MODULES_INIT_STAGE_1) return NULL; ctx = talloc(ldb, struct ldb_module); if (!ctx) return NULL; + data = talloc(ctx, struct private_data); + if (data == NULL) { + talloc_free(ctx); + return NULL; + } + + data->num_controls = 0; + data->controls = NULL; + ctx->private_data = data; + ctx->ldb = ldb; ctx->prev = ctx->next = NULL; ctx->ops = &rootdse_ops; - ctx->private_data = NULL; return ctx; } diff --git a/source4/dsdb/samdb/ldb_modules/samba3sam.c b/source4/dsdb/samdb/ldb_modules/samba3sam.c index 429710c2c5..035321a90b 100644 --- a/source4/dsdb/samdb/ldb_modules/samba3sam.c +++ b/source4/dsdb/samdb/ldb_modules/samba3sam.c @@ -878,7 +878,9 @@ const struct ldb_map_attribute samba3_attributes[] = }; /* the init function */ -struct ldb_module *ldb_samba3sam_module_init(struct ldb_context *ldb, const char *options[]) +struct ldb_module *ldb_samba3sam_module_init(struct ldb_context *ldb, int stage, const char *options[]) { + if (stage != LDB_MODULES_INIT_STAGE_1) return NULL; + return ldb_map_init(ldb, samba3_attributes, samba3_objectclasses, "samba3sam"); } diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 7bf25994e2..82c2d4d0cc 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -583,10 +583,12 @@ static const struct ldb_module_ops samldb_ops = { /* the init function */ -struct ldb_module *samldb_module_init(struct ldb_context *ldb, const char *options[]) +struct ldb_module *samldb_module_init(struct ldb_context *ldb, int stage, const char *options[]) { struct ldb_module *ctx; + if (stage != LDB_MODULES_INIT_STAGE_1) return NULL; + ctx = talloc(ldb, struct ldb_module); if (!ctx) return NULL; |