$olpath = "$olroot/libexec:$olroot/sbin:";
}
$ENV{PATH} = "$olpath/usr/local/sbin:/usr/sbin:/sbin:$ENV{PATH}";
- system("slapd -d63 -f $slapd_conf -h $uri > $logs 2>&1 &");
+ system("slapd -d0 -f $slapd_conf -h $uri > $logs 2>&1 &");
$ENV{PATH} = $oldpath;
}
ldb_kludge_acl_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/kludge_acl.o
################################################
-# Start MODULE ldb_extended_dn
-[MODULE::ldb_extended_dn]
+# Start MODULE ldb_extended_dn_in
+[MODULE::ldb_extended_dn_in]
SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR LIBSECURITY SAMDB
-INIT_FUNCTION = LDB_MODULE(extended_dn)
-# End MODULE ldb_extended_dn
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS
+INIT_FUNCTION = LDB_MODULE(extended_dn_in)
+# End MODULE ldb_extended_dn_in
+################################################
+
+ldb_extended_dn_in_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/extended_dn_in.o
+
+################################################
+# Start MODULE ldb_extended_dn_out
+[MODULE::ldb_extended_dn_out]
+SUBSYSTEM = LIBLDB
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS
+INIT_FUNCTION = LDB_MODULE(extended_dn_out_ldb),LDB_MODULE(extended_dn_out_dereference)
+ENABLE = YES
+ALIASES = extended_dn_out_ldb extended_dn_out_dereference
+# End MODULE ldb_extended_dn_out
+################################################
+
+ldb_extended_dn_out_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/extended_dn_out.o
+
+################################################
+# Start MODULE ldb_extended_dn_store
+[MODULE::ldb_extended_dn_store]
+SUBSYSTEM = LIBLDB
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS
+INIT_FUNCTION = LDB_MODULE(extended_dn_store)
+# End MODULE ldb_extended_dn_store
################################################
-ldb_extended_dn_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/extended_dn.o
+ldb_extended_dn_store_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/extended_dn_store.o
################################################
# Start MODULE ldb_show_deleted
+++ /dev/null
-/*
- ldb database library
-
- Copyright (C) Simo Sorce 2005-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: 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 "librpc/gen_ndr/ndr_misc.h"
-#include "dsdb/samdb/samdb.h"
-#include "libcli/security/security.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 int inject_extended_dn(struct ldb_message *msg,
- struct ldb_context *ldb,
- int type,
- bool remove_guid,
- bool remove_sid)
-{
- const struct ldb_val *val;
- struct GUID guid;
- struct dom_sid *sid;
- const DATA_BLOB *guid_blob;
- const DATA_BLOB *sid_blob;
- char *object_guid;
- char *object_sid;
- char *new_dn;
-
- guid_blob = ldb_msg_find_ldb_val(msg, "objectGUID");
- sid_blob = ldb_msg_find_ldb_val(msg, "objectSID");
-
- if (!guid_blob) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- switch (type) {
- case 0:
- /* return things in hexadecimal format */
- if (sid_blob) {
- const char *lower_guid_hex = strlower_talloc(msg, data_blob_hex_string(msg, guid_blob));
- const char *lower_sid_hex = strlower_talloc(msg, data_blob_hex_string(msg, sid_blob));
- if (!lower_guid_hex || !lower_sid_hex) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- new_dn = talloc_asprintf(msg, "<GUID=%s>;<SID=%s>;%s",
- lower_guid_hex,
- lower_sid_hex,
- ldb_dn_get_linearized(msg->dn));
- } else {
- const char *lower_guid_hex = strlower_talloc(msg, data_blob_hex_string(msg, guid_blob));
- if (!lower_guid_hex) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- new_dn = talloc_asprintf(msg, "<GUID=%s>;%s",
- lower_guid_hex,
- ldb_dn_get_linearized(msg->dn));
- }
-
- break;
- case 1:
- /* retrieve object_guid */
- guid = samdb_result_guid(msg, "objectGUID");
- object_guid = GUID_string(msg, &guid);
-
- /* 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 LDB_ERR_OPERATIONS_ERROR;
-
- }
-
- /* Normal, sane format */
- if (object_sid) {
- new_dn = talloc_asprintf(msg, "<GUID=%s>;<SID=%s>;%s",
- object_guid, object_sid,
- ldb_dn_get_linearized(msg->dn));
- } else {
- new_dn = talloc_asprintf(msg, "<GUID=%s>;%s",
- object_guid,
- ldb_dn_get_linearized(msg->dn));
- }
- break;
- default:
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (!new_dn) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (remove_guid) {
- ldb_msg_remove_attr(msg, "objectGUID");
- }
-
- if (sid_blob && remove_sid) {
- ldb_msg_remove_attr(msg, "objectSID");
- }
-
- msg->dn = ldb_dn_new(msg, ldb, new_dn);
- if (! ldb_dn_validate(msg->dn))
- return LDB_ERR_OPERATIONS_ERROR;
-
- val = ldb_msg_find_ldb_val(msg, "distinguishedName");
- if (val) {
- ldb_msg_remove_attr(msg, "distinguishedName");
- if (ldb_msg_add_steal_string(msg, "distinguishedName", new_dn))
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- return LDB_SUCCESS;
-}
-
-/* search */
-struct extended_context {
-
- struct ldb_module *module;
- struct ldb_request *req;
- struct ldb_control *control;
- struct ldb_dn *basedn;
- char *wellknown_object;
- bool inject;
- bool remove_guid;
- bool remove_sid;
- int extended_type;
- const char * const *cast_attrs;
-};
-
-static int extended_callback(struct ldb_request *req, struct ldb_reply *ares)
-{
- struct extended_context *ac;
- int ret;
-
- ac = talloc_get_type(req->context, struct extended_context);
-
- if (!ares) {
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
- if (ares->error != LDB_SUCCESS) {
- return ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
- }
-
- switch (ares->type) {
- case LDB_REPLY_ENTRY:
- if (ac->inject) {
- /* for each record returned post-process to add any derived
- attributes that have been asked for */
- ret = inject_extended_dn(ares->message, ac->module->ldb,
- ac->extended_type, ac->remove_guid,
- ac->remove_sid);
- if (ret != LDB_SUCCESS) {
- return ldb_module_done(ac->req, NULL, NULL, ret);
- }
- }
-
- return ldb_module_send_entry(ac->req, ares->message);
-
- case LDB_REPLY_REFERRAL:
- return ldb_module_send_referral(ac->req, ares->referral);
-
- case LDB_REPLY_DONE:
- return ldb_module_done(ac->req, ares->controls,
- ares->response, LDB_SUCCESS);
-
- }
- return LDB_SUCCESS;
-}
-
-static int extended_base_callback(struct ldb_request *req, struct ldb_reply *ares)
-{
- struct extended_context *ac;
- struct ldb_request *down_req;
- struct ldb_control **saved_controls;
- struct ldb_message_element *el;
- int ret;
- size_t i;
- size_t wkn_len = 0;
- char *valstr = NULL;
- const char *found = NULL;
-
- ac = talloc_get_type(req->context, struct extended_context);
-
- if (!ares) {
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
- if (ares->error != LDB_SUCCESS) {
- return ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
- }
-
- switch (ares->type) {
- case LDB_REPLY_ENTRY:
- if (!ac->wellknown_object) {
- ac->basedn = ares->message->dn;
- break;
- }
-
- wkn_len = strlen(ac->wellknown_object);
-
- el = ldb_msg_find_element(ares->message, "wellKnownObjects");
- if (!el) {
- ac->basedn = NULL;
- break;
- }
-
- for (i=0; i < el->num_values; i++) {
- valstr = talloc_strndup(ac,
- (const char *)el->values[i].data,
- el->values[i].length);
- if (!valstr) {
- ldb_oom(ac->module->ldb);
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
-
- if (strncasecmp(valstr, ac->wellknown_object, wkn_len) != 0) {
- talloc_free(valstr);
- continue;
- }
-
- found = &valstr[wkn_len];
- break;
- }
-
- if (!found) {
- break;
- }
-
- ac->basedn = ldb_dn_new(ac, ac->module->ldb, found);
- talloc_free(valstr);
- if (!ac->basedn) {
- ldb_oom(ac->module->ldb);
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
-
- break;
-
- case LDB_REPLY_REFERRAL:
- break;
-
- case LDB_REPLY_DONE:
-
- 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);
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_NO_SUCH_OBJECT);
- }
-
- ret = ldb_build_search_req_ex(&down_req,
- ac->module->ldb, ac,
- ac->basedn,
- ac->req->op.search.scope,
- ac->req->op.search.tree,
- ac->cast_attrs,
- ac->req->controls,
- ac, extended_callback,
- ac->req);
- if (ret != LDB_SUCCESS) {
- return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
- }
-
- if (ac->control) {
- /* save it locally and remove it from the list */
- /* we do not need to replace them later as we
- * are keeping the original req intact */
- if (!save_controls(ac->control, down_req, &saved_controls)) {
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
- }
-
- /* perform the search */
- return ldb_next_request(ac->module, down_req);
- }
- return LDB_SUCCESS;
-}
-
-static int extended_search(struct ldb_module *module, struct ldb_request *req)
-{
- struct ldb_control *control;
- struct ldb_extended_dn_control *extended_ctrl = NULL;
- struct ldb_control **saved_controls;
- struct extended_context *ac;
- struct ldb_request *down_req;
- char **new_attrs;
- int ret;
- struct ldb_dn *base_dn = NULL;
- enum ldb_scope base_dn_scope = LDB_SCOPE_BASE;
- const char *base_dn_filter = NULL;
- const char * const *base_dn_attrs = NULL;
- char *wellknown_object = NULL;
- static const char *dnattr[] = {
- "distinguishedName",
- NULL
- };
- static const char *wkattr[] = {
- "wellKnownObjects",
- NULL
- };
-
- if (ldb_dn_is_special(req->op.search.base)) {
- char *dn;
-
- dn = ldb_dn_alloc_linearized(req, req->op.search.base);
- if (!dn) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (strncasecmp(dn, "<SID=", 5) == 0) {
- char *str;
- char *valstr;
- char *p;
-
- p = strchr(dn, '=');
- if (!p) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
-
- p[0] = '\0';
- p++;
-
- str = p;
-
- p = strchr(str, '>');
- if (!p) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
- p[0] = '\0';
-
- if (strncasecmp(str, "S-", 2) == 0) {
- valstr = str;
- } else {
- DATA_BLOB binary;
- binary = strhex_to_data_blob(NULL, str);
- if (!binary.data) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- valstr = ldb_binary_encode(req, binary);
- data_blob_free(&binary);
- if (!valstr) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
-
- /* TODO: do a search over all partitions */
- base_dn = ldb_get_default_basedn(module->ldb);
- base_dn_filter = talloc_asprintf(req, "(objectSid=%s)", valstr);
- if (!base_dn_filter) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- base_dn_scope = LDB_SCOPE_SUBTREE;
- base_dn_attrs = dnattr;
- } else if (strncasecmp(dn, "<GUID=", 6) == 0) {
- char *str;
- char *valstr;
- char *p;
-
- p = strchr(dn, '=');
- if (!p) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
-
- p[0] = '\0';
- p++;
-
- str = p;
-
- p = strchr(str, '>');
- if (!p) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
- p[0] = '\0';
-
- if (strchr(str, '-')) {
- valstr = str;
- } else {
- DATA_BLOB binary;
- binary = strhex_to_data_blob(NULL, str);
- if (!binary.data) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- valstr = ldb_binary_encode(req, binary);
- data_blob_free(&binary);
- if (!valstr) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
-
- /* TODO: do a search over all partitions */
- base_dn = ldb_get_default_basedn(module->ldb);
- base_dn_filter = talloc_asprintf(req, "(objectGUID=%s)", valstr);
- if (!base_dn_filter) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- base_dn_scope = LDB_SCOPE_SUBTREE;
- base_dn_attrs = dnattr;
- } else if (strncasecmp(dn, "<WKGUID=", 8) == 0) {
- char *tail_str;
- char *p;
-
- p = strchr(dn, ',');
- if (!p) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
-
- p[0] = '\0';
- p++;
-
- wellknown_object = talloc_asprintf(req, "B:32:%s:", &dn[8]);
- if (!wellknown_object) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- tail_str = p;
- p = strchr(tail_str, '>');
- if (!p) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
- p[0] = '\0';
-
- base_dn = ldb_dn_new(req, module->ldb, tail_str);
- if (!base_dn) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- base_dn_filter = talloc_strdup(req, "(objectClass=*)");
- if (!base_dn_filter) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- base_dn_scope = LDB_SCOPE_BASE;
- base_dn_attrs = wkattr;
- }
- talloc_free(dn);
- }
-
- /* check if there's an extended dn control */
- control = ldb_request_get_control(req, LDB_CONTROL_EXTENDED_DN_OID);
- if (control == NULL && base_dn_filter == NULL) {
- /* not found go on */
- return ldb_next_request(module, req);
- }
-
- if (control && control->data) {
- extended_ctrl = talloc_get_type(control->data, struct ldb_extended_dn_control);
- if (!extended_ctrl) {
- return LDB_ERR_PROTOCOL_ERROR;
- }
- }
-
- ac = talloc_zero(req, struct extended_context);
- if (ac == NULL) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ac->module = module;
- ac->req = req;
- ac->control = control;
- ac->basedn = NULL;
- ac->wellknown_object = wellknown_object;
- ac->inject = false;
- ac->remove_guid = false;
- ac->remove_sid = false;
-
- if (control) {
- ac->inject = true;
- if (extended_ctrl) {
- ac->extended_type = extended_ctrl->type;
- } else {
- ac->extended_type = 0;
- }
-
- /* 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")) {
- ac->remove_guid = true;
- }
- if (! is_attr_in_list(req->op.search.attrs, "objectSID")) {
- ac->remove_sid = true;
- }
- if (ac->remove_guid || ac->remove_sid) {
- new_attrs = copy_attrs(ac, req->op.search.attrs);
- if (new_attrs == NULL) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (ac->remove_guid) {
- if (!add_attrs(ac, &new_attrs, "objectGUID"))
- return LDB_ERR_OPERATIONS_ERROR;
- }
- if (ac->remove_sid) {
- if (!add_attrs(ac, &new_attrs, "objectSID"))
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ac->cast_attrs = (const char * const *)new_attrs;
- } else {
- ac->cast_attrs = req->op.search.attrs;
- }
- }
- }
-
- if (base_dn) {
- ret = ldb_build_search_req(&down_req,
- module->ldb, ac,
- base_dn,
- base_dn_scope,
- base_dn_filter,
- base_dn_attrs,
- NULL,
- ac, extended_base_callback,
- req);
- if (ret != LDB_SUCCESS) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* perform the search */
- return ldb_next_request(module, down_req);
- }
-
- ret = ldb_build_search_req_ex(&down_req,
- module->ldb, ac,
- req->op.search.base,
- req->op.search.scope,
- req->op.search.tree,
- ac->cast_attrs,
- req->controls,
- ac, extended_callback,
- req);
- if (ret != LDB_SUCCESS) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (ac->control) {
- /* save it locally and remove it from the list */
- /* we do not need to replace them later as we
- * are keeping the original req intact */
- if (!save_controls(control, down_req, &saved_controls)) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
-
- /* perform the search */
- return ldb_next_request(module, down_req);
-}
-
-static int extended_init(struct ldb_module *module)
-{
- int ret;
-
- ret = ldb_mod_register_control(module, LDB_CONTROL_EXTENDED_DN_OID);
- if (ret != LDB_SUCCESS) {
- ldb_debug(module->ldb, LDB_DEBUG_ERROR,
- "extended_dn: Unable to register control with rootdse!\n");
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- return ldb_next_init(module);
-}
-
-_PUBLIC_ const struct ldb_module_ops ldb_extended_dn_module_ops = {
- .name = "extended_dn",
- .search = extended_search,
- .init_context = extended_init
-};
--- /dev/null
+/*
+ ldb database library
+
+ Copyright (C) Simo Sorce 2005-2008
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007-2008
+
+ 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/>.
+*/
+
+/*
+ * Name: ldb
+ *
+ * Component: ldb extended dn control module
+ *
+ * Description: this module interprets DNs of the form <SID=S-1-2-4456> into normal DNs.
+ *
+ * Authors: Simo Sorce
+ * Andrew Bartlett
+ */
+
+#include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_errors.h"
+#include "ldb/include/ldb_private.h"
+
+/* search */
+struct extended_search_context {
+ struct ldb_module *module;
+ struct ldb_request *req;
+ struct ldb_dn *basedn;
+ char *wellknown_object;
+ int extended_type;
+};
+
+/* An extra layer of indirection because LDB does not allow the original request to be altered */
+
+static int extended_final_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ int ret = LDB_ERR_OPERATIONS_ERROR;
+ struct extended_search_context *ac;
+ ac = talloc_get_type(req->context, struct extended_search_context);
+
+ if (ares->error != LDB_SUCCESS) {
+ ret = ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ } else {
+ switch (ares->type) {
+ case LDB_REPLY_ENTRY:
+
+ ret = ldb_module_send_entry(ac->req, ares->message);
+ break;
+ case LDB_REPLY_REFERRAL:
+
+ ret = ldb_module_send_referral(ac->req, ares->referral);
+ break;
+ case LDB_REPLY_DONE:
+
+ ret = ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ break;
+ }
+ }
+ return ret;
+}
+
+static int extended_base_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ struct extended_search_context *ac;
+ struct ldb_request *down_req;
+ struct ldb_message_element *el;
+ int ret;
+ size_t i;
+ size_t wkn_len = 0;
+ char *valstr = NULL;
+ const char *found = NULL;
+
+ ac = talloc_get_type(req->context, struct extended_search_context);
+
+ if (!ares) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ switch (ares->type) {
+ case LDB_REPLY_ENTRY:
+ if (!ac->wellknown_object) {
+ ac->basedn = talloc_steal(ac, ares->message->dn);
+ break;
+ }
+
+ wkn_len = strlen(ac->wellknown_object);
+
+ el = ldb_msg_find_element(ares->message, "wellKnownObjects");
+ if (!el) {
+ ac->basedn = NULL;
+ break;
+ }
+
+ for (i=0; i < el->num_values; i++) {
+ valstr = talloc_strndup(ac,
+ (const char *)el->values[i].data,
+ el->values[i].length);
+ if (!valstr) {
+ ldb_oom(ac->module->ldb);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ if (strncasecmp(valstr, ac->wellknown_object, wkn_len) != 0) {
+ talloc_free(valstr);
+ continue;
+ }
+
+ found = &valstr[wkn_len];
+ break;
+ }
+
+ if (!found) {
+ break;
+ }
+
+ ac->basedn = ldb_dn_new(ac, ac->module->ldb, found);
+ talloc_free(valstr);
+ if (!ac->basedn) {
+ ldb_oom(ac->module->ldb);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ break;
+
+ case LDB_REPLY_REFERRAL:
+ break;
+
+ case LDB_REPLY_DONE:
+
+ 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);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_NO_SUCH_OBJECT);
+ }
+
+ switch (ac->req->operation) {
+ case LDB_SEARCH:
+ ret = ldb_build_search_req_ex(&down_req,
+ ac->module->ldb, ac->req,
+ ac->basedn,
+ ac->req->op.search.scope,
+ ac->req->op.search.tree,
+ ac->req->op.search.attrs,
+ ac->req->controls,
+ ac, extended_final_callback,
+ ac->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);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ add_msg->dn = ac->basedn;
+
+ ret = ldb_build_add_req(&down_req,
+ ac->module->ldb, ac->req,
+ add_msg,
+ ac->req->controls,
+ ac, extended_final_callback,
+ ac->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);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ mod_msg->dn = ac->basedn;
+
+ ret = ldb_build_mod_req(&down_req,
+ ac->module->ldb, ac->req,
+ mod_msg,
+ ac->req->controls,
+ ac, extended_final_callback,
+ ac->req);
+ break;
+ }
+ case LDB_DELETE:
+ ret = ldb_build_del_req(&down_req,
+ ac->module->ldb, ac->req,
+ ac->basedn,
+ ac->req->controls,
+ ac, extended_final_callback,
+ ac->req);
+ break;
+ case LDB_RENAME:
+ ret = ldb_build_rename_req(&down_req,
+ ac->module->ldb, ac->req,
+ ac->basedn,
+ ac->req->op.rename.newdn,
+ ac->req->controls,
+ ac, extended_final_callback,
+ ac->req);
+ break;
+ default:
+ return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+
+ return ldb_next_request(ac->module, down_req);
+ }
+ talloc_free(ares);
+ return LDB_SUCCESS;
+}
+
+static int extended_dn_in_fix(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn)
+{
+ struct extended_search_context *ac;
+ struct ldb_request *down_req;
+ int ret;
+ struct ldb_dn *base_dn = NULL;
+ enum ldb_scope base_dn_scope = LDB_SCOPE_BASE;
+ const char *base_dn_filter = NULL;
+ const char * const *base_dn_attrs = NULL;
+ char *wellknown_object = NULL;
+ static const char *no_attr[] = {
+ NULL
+ };
+ static const char *wkattr[] = {
+ "wellKnownObjects",
+ NULL
+ };
+
+ if (!ldb_dn_has_extended(dn)) {
+ /* Move along there isn't anything to see here */
+ return ldb_next_request(module, req);
+ } else {
+ /* It looks like we need to map the DN */
+ const struct ldb_val *sid_val, *guid_val, *wkguid_val;
+
+ 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);
+ 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;
+ }
+ 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);
+ 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;
+ }
+ base_dn_scope = LDB_SCOPE_SUBTREE;
+ base_dn_attrs = no_attr;
+
+
+ } else if (wkguid_val) {
+ char *wkguid_dup;
+ char *tail_str;
+ char *p;
+
+ wkguid_dup = talloc_strndup(req, (char *)wkguid_val->data, wkguid_val->length);
+
+ p = strchr(wkguid_dup, ',');
+ if (!p) {
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+
+ p[0] = '\0';
+ p++;
+
+ wellknown_object = talloc_asprintf(req, "B:32:%s:", wkguid_dup);
+ if (!wellknown_object) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ tail_str = p;
+
+ base_dn = ldb_dn_new(req, module->ldb, tail_str);
+ talloc_free(wkguid_dup);
+ if (!base_dn) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ base_dn_filter = talloc_strdup(req, "(objectClass=*)");
+ if (!base_dn_filter) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ base_dn_scope = LDB_SCOPE_BASE;
+ base_dn_attrs = wkattr;
+ } else {
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+
+ ac = talloc_zero(req, struct extended_search_context);
+ if (ac == NULL) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ac->module = module;
+ ac->req = req;
+ ac->basedn = NULL; /* Filled in if the search finds the DN by SID/GUID etc */
+ ac->wellknown_object = wellknown_object;
+
+ /* If the base DN was an extended DN (perhaps a well known
+ * GUID) then search for that, so we can proceed with the original operation */
+
+ ret = ldb_build_search_req(&down_req,
+ module->ldb, ac,
+ base_dn,
+ base_dn_scope,
+ base_dn_filter,
+ base_dn_attrs,
+ NULL,
+ ac, extended_base_callback,
+ req);
+ if (ret != LDB_SUCCESS) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* perform the search */
+ return ldb_next_request(module, down_req);
+ }
+}
+
+static int extended_dn_in_search(struct ldb_module *module, struct ldb_request *req)
+{
+ return extended_dn_in_fix(module, req, req->op.search.base);
+}
+
+static int extended_dn_in_modify(struct ldb_module *module, struct ldb_request *req)
+{
+ return extended_dn_in_fix(module, req, req->op.mod.message->dn);
+}
+
+static int extended_dn_in_del(struct ldb_module *module, struct ldb_request *req)
+{
+ return extended_dn_in_fix(module, req, req->op.del.dn);
+}
+
+static int extended_dn_in_rename(struct ldb_module *module, struct ldb_request *req)
+{
+ return extended_dn_in_fix(module, req, req->op.rename.olddn);
+}
+
+_PUBLIC_ 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,
+};
--- /dev/null
+/*
+ ldb database library
+
+ Copyright (C) Simo Sorce 2005-2008
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007-2008
+
+ 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/>.
+*/
+
+/*
+ * Name: ldb
+ *
+ * Component: ldb extended dn control module
+ *
+ * Description: this module builds a special dn for returned search
+ * results
+ * values.
+ *
+ * Authors: Simo Sorce
+ * Andrew Bartlett
+ */
+
+#include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_errors.h"
+#include "ldb/include/ldb_private.h"
+#include "librpc/gen_ndr/ndr_misc.h"
+#include "librpc/ndr/libndr.h"
+#include "dsdb/samdb/samdb.h"
+
+struct extended_dn_out_private {
+ bool dereference;
+ struct dsdb_openldap_dereference_control *dereference_control;
+};
+
+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 int inject_extended_dn_out(struct ldb_reply *ares,
+ struct ldb_context *ldb,
+ int type,
+ bool remove_guid,
+ bool remove_sid)
+{
+ int ret;
+ const struct ldb_val *val;
+ const DATA_BLOB *guid_blob;
+ const DATA_BLOB *sid_blob;
+
+ guid_blob = ldb_msg_find_ldb_val(ares->message, "objectGUID");
+ sid_blob = ldb_msg_find_ldb_val(ares->message, "objectSID");
+
+ if (!guid_blob) {
+ ldb_set_errstring(ldb, "Did not find objectGUID to inject into extended DN");
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_dn_set_extended_component(ares->message->dn, "GUID", guid_blob);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ if (sid_blob) {
+ ret = ldb_dn_set_extended_component(ares->message->dn, "SID", sid_blob);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
+ if (remove_guid) {
+ ldb_msg_remove_attr(ares->message, "objectGUID");
+ }
+
+ if (sid_blob && remove_sid) {
+ ldb_msg_remove_attr(ares->message, "objectSID");
+ }
+
+ val = ldb_msg_find_ldb_val(ares->message, "distinguishedName");
+ if (val) {
+ ldb_msg_remove_attr(ares->message, "distinguishedName");
+ ret = ldb_msg_add_steal_string(ares->message, "distinguishedName",
+ ldb_dn_extended_linearized(ares->message, ares->message->dn, type));
+ if (ret != LDB_SUCCESS) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ }
+ return LDB_SUCCESS;
+}
+
+static int handle_dereference(struct ldb_dn *dn,
+ struct dsdb_openldap_dereference_result **dereference_attrs,
+ const char *attr, const DATA_BLOB *val)
+{
+ const struct ldb_val *entryUUIDblob, *sid_blob;
+ struct ldb_message fake_msg; /* easier to use routines that expect an ldb_message */
+ int j;
+
+ fake_msg.num_elements = 0;
+
+ /* Look for this attribute in the returned control */
+ for (j = 0; dereference_attrs && dereference_attrs[j]; j++) {
+ DATA_BLOB source_dn = data_blob_string_const(dereference_attrs[j]->dereferenced_dn);
+ if (ldb_attr_cmp(dereference_attrs[j]->source_attribute, attr)
+ && data_blob_cmp(&source_dn, val) == 0) {
+
+ fake_msg.num_elements = dereference_attrs[j]->num_attributes;
+ fake_msg.elements = dereference_attrs[j]->attributes;
+ break;
+ }
+ }
+ if (!fake_msg.num_elements) {
+ return LDB_SUCCESS;
+ }
+ /* Look for an OpenLDAP entryUUID */
+
+ entryUUIDblob = ldb_msg_find_ldb_val(&fake_msg, "entryUUID");
+ if (entryUUIDblob) {
+ NTSTATUS status;
+ enum ndr_err_code ndr_err;
+
+ struct ldb_val guid_blob;
+ struct GUID guid;
+
+ status = GUID_from_data_blob(entryUUIDblob, &guid);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+ ndr_err = ndr_push_struct_blob(&guid_blob, NULL, NULL, &guid,
+ (ndr_push_flags_fn_t)ndr_push_GUID);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+
+ ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
+ }
+
+ sid_blob = ldb_msg_find_ldb_val(&fake_msg, "objectSID");
+
+ /* Look for the objectSID */
+ if (sid_blob) {
+ ldb_dn_set_extended_component(dn, "SID", sid_blob);
+ }
+ return LDB_SUCCESS;
+}
+
+/* search */
+struct extended_search_context {
+ struct ldb_module *module;
+ const struct dsdb_schema *schema;
+ struct ldb_request *req;
+ bool inject;
+ bool remove_guid;
+ bool remove_sid;
+ int extended_type;
+};
+
+static int extended_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ struct extended_search_context *ac;
+ struct ldb_control *control;
+ struct dsdb_openldap_dereference_result_control *dereference_control = NULL;
+ int ret, i, j;
+ struct ldb_message *msg = ares->message;
+ struct extended_dn_out_private *private;
+
+ ac = talloc_get_type(req->context, struct extended_search_context);
+ private = talloc_get_type(ac->module->private_data, struct extended_dn_out_private);
+
+ if (!ares) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ switch (ares->type) {
+ case LDB_REPLY_REFERRAL:
+ return ldb_module_send_referral(ac->req, ares->referral);
+
+ case LDB_REPLY_DONE:
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, LDB_SUCCESS);
+ case LDB_REPLY_ENTRY:
+ break;
+ }
+
+ if (ac->inject) {
+ /* for each record returned post-process to add any derived
+ attributes that have been asked for */
+ ret = inject_extended_dn_out(ares, ac->module->ldb,
+ ac->extended_type, ac->remove_guid,
+ ac->remove_sid);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ }
+
+ if (private && private->dereference) {
+ control = ldb_reply_get_control(ares, DSDB_OPENLDAP_DEREFERENCE_CONTROL);
+
+ if (control && control->data) {
+ dereference_control = talloc_get_type(control->data, struct dsdb_openldap_dereference_result_control);
+ }
+ }
+
+ /* Walk the retruned elements (but only if we have a schema to interpret the list with) */
+ for (i = 0; ac->schema && i < msg->num_elements; i++) {
+ const struct dsdb_attribute *attribute;
+ /* distinguishedName has been dealt with above */
+ if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) {
+ continue;
+ }
+ attribute = dsdb_attribute_by_lDAPDisplayName(ac->schema, msg->elements[i].name);
+ if (!attribute) {
+ continue;
+ }
+ /* Look to see if this attributeSyntax is a DN */
+ if (strcmp(attribute->attributeSyntax_oid, "2.5.5.1") != 0) {
+ continue;
+ }
+
+ for (j = 0; j < msg->elements[i].num_values; j++) {
+ const char *dn_str;
+ struct ldb_dn *dn = ldb_dn_from_ldb_val(ac, ac->module->ldb, &msg->elements[i].values[j]);
+ if (!dn || !ldb_dn_validate(dn)) {
+ return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_INVALID_DN_SYNTAX);
+ }
+
+ /* If we are running in dereference mode (such
+ * as against OpenLDAP) then the DN in the msg
+ * above does not contain the extended values,
+ * and we need to look in the dereference
+ * result */
+
+ /* Look for this value in the attribute */
+
+ if (dereference_control) {
+ ret = handle_dereference(dn,
+ dereference_control->attributes,
+ msg->elements[i].name,
+ &msg->elements[i].values[j]);
+ if (ret != LDB_SUCCESS) {
+
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ }
+
+ if (!ac->inject) {
+ dn_str = talloc_steal(msg->elements[i].values,
+ ldb_dn_get_linearized(dn));
+ } else {
+ dn_str = talloc_steal(msg->elements[i].values,
+ ldb_dn_extended_linearized(msg->elements[i].values,
+ dn, ac->extended_type));
+ }
+ msg->elements[i].values[j] = data_blob_string_const(dn_str);
+ talloc_free(dn);
+ }
+ }
+ return ldb_module_send_entry(ac->req, msg);
+}
+
+
+static int extended_dn_out_search(struct ldb_module *module, struct ldb_request *req)
+{
+ struct ldb_control *control;
+ struct ldb_control *storage_format_control;
+ struct ldb_extended_dn_control *extended_ctrl = NULL;
+ struct ldb_control **saved_controls;
+ struct extended_search_context *ac;
+ struct ldb_request *down_req;
+ char **new_attrs;
+ const char * const *const_attrs;
+ int ret;
+
+ struct extended_dn_out_private *private = talloc_get_type(module->private_data, struct extended_dn_out_private);
+
+ /* check if there's an extended dn control */
+ control = ldb_request_get_control(req, LDB_CONTROL_EXTENDED_DN_OID);
+ if (control && control->data) {
+ extended_ctrl = talloc_get_type(control->data, struct ldb_extended_dn_control);
+ if (!extended_ctrl) {
+ return LDB_ERR_PROTOCOL_ERROR;
+ }
+ }
+
+ /* Look to see if, as we are in 'store DN+GUID+SID' mode, the
+ * client is after the storage format (to fill in linked
+ * attributes) */
+ storage_format_control = ldb_request_get_control(req, DSDB_CONTROL_DN_STORAGE_FORMAT_OID);
+ if (!control && storage_format_control && storage_format_control->data) {
+ extended_ctrl = talloc_get_type(storage_format_control->data, struct ldb_extended_dn_control);
+ if (!extended_ctrl) {
+ ldb_set_errstring(module->ldb, "extended_dn_out: extended_ctrl was of the wrong data type");
+ return LDB_ERR_PROTOCOL_ERROR;
+ }
+ }
+
+ ac = talloc_zero(req, struct extended_search_context);
+ if (ac == NULL) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ac->module = module;
+ ac->schema = dsdb_get_schema(module->ldb);
+ ac->req = req;
+ ac->inject = false;
+ ac->remove_guid = false;
+ ac->remove_sid = false;
+
+ const_attrs = req->op.search.attrs;
+
+ if (control || (storage_format_control && private && !private->dereference)) {
+ ac->inject = true;
+ if (extended_ctrl) {
+ ac->extended_type = extended_ctrl->type;
+ } else {
+ ac->extended_type = 0;
+ }
+
+ /* 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")) {
+ ac->remove_guid = true;
+ }
+ if (! is_attr_in_list(req->op.search.attrs, "objectSID")) {
+ ac->remove_sid = true;
+ }
+ if (ac->remove_guid || ac->remove_sid) {
+ new_attrs = copy_attrs(ac, req->op.search.attrs);
+ if (new_attrs == NULL) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ if (ac->remove_guid) {
+ if (!add_attrs(ac, &new_attrs, "objectGUID"))
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ if (ac->remove_sid) {
+ if (!add_attrs(ac, &new_attrs, "objectSID"))
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ const_attrs = (const char * const *)new_attrs;
+ }
+ }
+ }
+
+ ret = ldb_build_search_req_ex(&down_req,
+ module->ldb, ac,
+ req->op.search.base,
+ req->op.search.scope,
+ req->op.search.tree,
+ const_attrs,
+ req->controls,
+ ac, extended_callback,
+ req);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ /* Remove extended DN and storage format controls */
+
+ if (control) {
+ /* save it locally and remove it from the list */
+ /* we do not need to replace them later as we
+ * are keeping the original req intact */
+ if (!save_controls(control, down_req, &saved_controls)) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ }
+
+ if (storage_format_control) {
+ /* save it locally and remove it from the list */
+ /* we do not need to replace them later as we
+ * are keeping the original req intact */
+ if (!save_controls(storage_format_control, down_req, &saved_controls)) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ }
+
+ if (private && private->dereference && private->dereference_control) {
+
+ /* Add in dereference control */
+ ret = ldb_request_add_control(down_req,
+ DSDB_OPENLDAP_DEREFERENCE_CONTROL,
+ false, private->dereference_control);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
+ /* perform the search */
+ return ldb_next_request(module, down_req);
+}
+
+static int extended_dn_out_ldb_init(struct ldb_module *module)
+{
+ int ret;
+
+ struct extended_dn_out_private *private = talloc(module, struct extended_dn_out_private);
+
+ module->private_data = private;
+
+ if (!private) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ private->dereference = false;
+
+ ret = ldb_mod_register_control(module, LDB_CONTROL_EXTENDED_DN_OID);
+ if (ret != LDB_SUCCESS) {
+ ldb_debug(module->ldb, LDB_DEBUG_ERROR,
+ "extended_dn_out: Unable to register control with rootdse!\n");
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ return ldb_next_init(module);
+}
+
+static int extended_dn_out_dereference_init(struct ldb_module *module)
+{
+ int ret, i = 0;
+ struct extended_dn_out_private *private;
+ struct dsdb_openldap_dereference_control *dereference_control;
+ struct dsdb_attribute *cur;
+
+ struct dsdb_schema *schema;
+
+ module->private_data = private = talloc_zero(module, struct extended_dn_out_private);
+
+ if (!private) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ private->dereference = true;
+
+ ret = ldb_mod_register_control(module, LDB_CONTROL_EXTENDED_DN_OID);
+ if (ret != LDB_SUCCESS) {
+ ldb_debug(module->ldb, LDB_DEBUG_ERROR,
+ "extended_dn_out: Unable to register control with rootdse!\n");
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_next_init(module);
+
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ schema = dsdb_get_schema(module->ldb);
+ if (!schema) {
+ /* No schema on this DB (yet) */
+ return LDB_SUCCESS;
+ }
+
+ private->dereference_control = dereference_control
+ = talloc_zero(private, struct dsdb_openldap_dereference_control);
+
+ if (!private->dereference_control) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ for (cur = schema->attributes; cur; cur = cur->next) {
+ static const char *attrs[] = {
+ "entryUUID",
+ "objectSID",
+ NULL
+ };
+
+ if (strcmp(cur->syntax->attributeSyntax_oid, "2.5.5.1") != 0) {
+ continue;
+ }
+ dereference_control->dereference
+ = talloc_realloc(private, dereference_control->dereference,
+ struct dsdb_openldap_dereference *, i + 2);
+ if (!dereference_control) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ dereference_control->dereference[i] = talloc(dereference_control->dereference,
+ struct dsdb_openldap_dereference);
+ if (!dereference_control->dereference[i]) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ dereference_control->dereference[i]->source_attribute = cur->lDAPDisplayName;
+ dereference_control->dereference[i]->dereference_attribute = attrs;
+ i++;
+ dereference_control->dereference[i] = NULL;
+ }
+ return LDB_SUCCESS;
+}
+
+_PUBLIC_ const struct ldb_module_ops ldb_extended_dn_out_ldb_module_ops = {
+ .name = "extended_dn_out_ldb",
+ .search = extended_dn_out_search,
+ .init_context = extended_dn_out_ldb_init,
+};
+
+
+_PUBLIC_ const struct ldb_module_ops ldb_extended_dn_out_dereference_module_ops = {
+ .name = "extended_dn_out_dereference",
+ .search = extended_dn_out_search,
+ .init_context = extended_dn_out_dereference_init,
+};
--- /dev/null
+static int extended_dn_out_dereference_init(struct ldb_module *module)
+{
+ int ret;
+
+ ret = ldb_mod_register_control(module, LDB_CONTROL_EXTENDED_DN_OID);
+ if (ret != LDB_SUCCESS) {
+ ldb_debug(module->ldb, LDB_DEBUG_ERROR,
+ "extended_dn_out: Unable to register control with rootdse!\n");
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ return ldb_next_init(module);
+}
+
+_PUBLIC_ const struct ldb_module_ops ldb_extended_dn_out_dereference_module_ops = {
+ .name = "extended_dn_out_ldb",
+ .search = extended_dn_out_search,
+ .init_context = extended_dn_out_ldb_init,
+};
--- /dev/null
+static int extended_dn_out_ldb_init(struct ldb_module *module)
+{
+ int ret;
+
+ ret = ldb_mod_register_control(module, LDB_CONTROL_EXTENDED_DN_OID);
+ if (ret != LDB_SUCCESS) {
+ ldb_debug(module->ldb, LDB_DEBUG_ERROR,
+ "extended_dn_out: Unable to register control with rootdse!\n");
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ return ldb_next_init(module);
+}
+
+_PUBLIC_ const struct ldb_module_ops ldb_extended_dn_out_ldb_module_ops = {
+ .name = "extended_dn_out_ldb",
+ .search = extended_dn_out_search,
+ .init_context = extended_dn_out_ldb_init,
+};
+
--- /dev/null
+/*
+ ldb database library
+
+ Copyright (C) Simo Sorce 2005-2008
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007-2008
+
+ 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/>.
+*/
+
+/*
+ * Name: ldb
+ *
+ * Component: ldb extended dn control module
+ *
+ * Description: this module builds a special dn for returned search
+ * results nad creates the special DN in the backend store for new
+ * values.
+ *
+ * This also has the curious result that we convert <SID=S-1-2-345>
+ * in an attribute value into a normal DN for the rest of the stack
+ * to process
+ *
+ * Authors: Simo Sorce
+ * Andrew Bartlett
+ */
+
+#include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_errors.h"
+#include "ldb/include/ldb_private.h"
+#include "librpc/gen_ndr/ndr_misc.h"
+#include "dsdb/samdb/samdb.h"
+#include "libcli/security/security.h"
+
+#include <time.h>
+
+struct extended_dn_replace_list {
+ struct extended_dn_replace_list *next;
+ struct ldb_dn *dn;
+ TALLOC_CTX *mem_ctx;
+ struct ldb_val *replace_dn;
+ struct extended_dn_context *ac;
+ struct ldb_request *search_req;
+};
+
+
+struct extended_dn_context {
+ const struct dsdb_schema *schema;
+ struct ldb_module *module;
+ struct ldb_request *req;
+ struct ldb_request *new_req;
+
+ struct extended_dn_replace_list *ops;
+ struct extended_dn_replace_list *cur;
+};
+
+
+static struct extended_dn_context *extended_dn_context_init(struct ldb_module *module,
+ struct ldb_request *req)
+{
+ struct extended_dn_context *ac;
+
+ ac = talloc_zero(req, struct extended_dn_context);
+ if (ac == NULL) {
+ ldb_oom(module->ldb);
+ return NULL;
+ }
+
+ ac->schema = dsdb_get_schema(module->ldb);
+ ac->module = module;
+ ac->req = req;
+
+ return ac;
+}
+
+/* An extra layer of indirection because LDB does not allow the original request to be altered */
+
+static int extended_final_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ int ret = LDB_ERR_OPERATIONS_ERROR;
+ struct extended_dn_context *ac;
+ ac = talloc_get_type(req->context, struct extended_dn_context);
+
+ if (ares->error != LDB_SUCCESS) {
+ ret = ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ } else {
+ switch (ares->type) {
+ case LDB_REPLY_ENTRY:
+
+ ret = ldb_module_send_entry(ac->req, ares->message);
+ break;
+ case LDB_REPLY_REFERRAL:
+
+ ret = ldb_module_send_referral(ac->req, ares->referral);
+ break;
+ case LDB_REPLY_DONE:
+
+ ret = ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ break;
+ }
+ }
+ return ret;
+}
+
+static int extended_replace_dn(struct ldb_request *req, struct ldb_reply *ares)
+{
+ struct extended_dn_replace_list *os = talloc_get_type(req->context,
+ struct extended_dn_replace_list);
+
+ if (!ares) {
+ return ldb_module_done(os->ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ if (ares->error == LDB_ERR_NO_SUCH_OBJECT) {
+ /* Don't worry too much about dangling references */
+
+ ldb_reset_err_string(os->ac->module->ldb);
+ if (os->next) {
+ struct extended_dn_replace_list *next;
+
+ next = os->next;
+
+ talloc_free(os);
+
+ os = next;
+ return ldb_next_request(os->ac->module, next->search_req);
+ } else {
+ /* Otherwise, we are done - let's run the
+ * request now we have swapped the DNs for the
+ * full versions */
+ return ldb_next_request(os->ac->module, os->ac->req);
+ }
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(os->ac->req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ /* Only entries are interesting, and we only want the olddn */
+ switch (ares->type) {
+ case LDB_REPLY_ENTRY:
+ {
+ /* This *must* be the right DN, as this is a base
+ * search. We can't check, as it could be an extended
+ * DN, so a module below will resolve it */
+ struct ldb_dn *dn = ares->message->dn;
+
+ *os->replace_dn = data_blob_string_const(
+ ldb_dn_extended_linearized(os->mem_ctx,
+ dn, 1));
+ if (os->replace_dn->data == NULL) {
+ return ldb_module_done(os->ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ break;
+ }
+ case LDB_REPLY_REFERRAL:
+ /* ignore */
+ break;
+
+ case LDB_REPLY_DONE:
+
+ talloc_free(ares);
+
+ /* Run the next search */
+
+ if (os->next) {
+ struct extended_dn_replace_list *next;
+
+ next = os->next;
+
+ talloc_free(os);
+
+ os = next;
+ return ldb_next_request(os->ac->module, next->search_req);
+ } else {
+ /* Otherwise, we are done - let's run the
+ * request now we have swapped the DNs for the
+ * full versions */
+ return ldb_next_request(os->ac->module, os->ac->new_req);
+ }
+ }
+
+ talloc_free(ares);
+ return LDB_SUCCESS;
+}
+
+/* We have a 'normal' DN in the inbound request. We need to find out
+ * what the GUID and SID are on the DN it points to, so we can
+ * construct an extended DN for storage.
+ *
+ * This creates a list of DNs to look up, and the plain DN to replace
+ */
+
+static int extended_store_replace(struct extended_dn_context *ac,
+ TALLOC_CTX *callback_mem_ctx,
+ struct ldb_val *plain_dn)
+{
+ int ret;
+ struct extended_dn_replace_list *os;
+ static const char *attrs[] = {
+ "objectSid",
+ "objectGUID",
+ NULL
+ };
+
+ os = talloc_zero(ac, struct extended_dn_replace_list);
+ if (!os) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ os->ac = ac;
+
+ os->mem_ctx = callback_mem_ctx;
+
+ os->dn = ldb_dn_from_ldb_val(os, ac->module->ldb, plain_dn);
+ if (!os->dn || !ldb_dn_validate(os->dn)) {
+ talloc_free(os);
+ ldb_asprintf_errstring(ac->module->ldb,
+ "could not parse %.*s as a DN", (int)plain_dn->length, plain_dn->data);
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+
+ os->replace_dn = plain_dn;
+
+ /* The search request here might happen to be for an
+ * 'extended' style DN, such as <GUID=abced...>. The next
+ * module in the stack will convert this into a normal DN for
+ * processing */
+ ret = ldb_build_search_req(&os->search_req,
+ ac->module->ldb, os, os->dn, LDB_SCOPE_BASE, NULL,
+ attrs, NULL, os, extended_replace_dn,
+ ac->req);
+
+ if (ret != LDB_SUCCESS) {
+ talloc_free(os);
+ return ret;
+ }
+
+ ret = ldb_request_add_control(os->search_req,
+ DSDB_CONTROL_DN_STORAGE_FORMAT_OID,
+ true, NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(os);
+ return ret;
+ }
+
+ if (ac->ops) {
+ ac->cur->next = os;
+ } else {
+ ac->ops = os;
+ }
+ ac->cur = os;
+
+ return LDB_SUCCESS;
+}
+
+
+/* add */
+static int extended_dn_add(struct ldb_module *module, struct ldb_request *req)
+{
+ struct extended_dn_context *ac;
+ int ret;
+ int i, j;
+
+ if (ldb_dn_is_special(req->op.add.message->dn)) {
+ /* do not manipulate our control entries */
+ return ldb_next_request(module, req);
+ }
+
+ ac = extended_dn_context_init(module, req);
+ if (!ac) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ if (!ac->schema) {
+ /* without schema, this doesn't make any sense */
+ talloc_free(ac);
+ return ldb_next_request(module, req);
+ }
+
+ for (i=0; i < req->op.add.message->num_elements; i++) {
+ const struct ldb_message_element *el = &req->op.add.message->elements[i];
+ const struct dsdb_attribute *schema_attr
+ = dsdb_attribute_by_lDAPDisplayName(ac->schema, el->name);
+ if (!schema_attr) {
+ continue;
+ }
+
+ /* We only setup an extended DN GUID on these particular DN objects */
+ if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0) {
+ continue;
+ }
+
+ /* Before we setup a procedure to modify the incoming message, we must copy it */
+ if (!ac->new_req) {
+ struct ldb_message *msg = ldb_msg_copy(ac, req->op.add.message);
+ if (!msg) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_build_add_req(&ac->new_req, module->ldb, ac, msg, req->controls, ac, extended_final_callback, req);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ /* Re-calculate el */
+ el = &ac->new_req->op.add.message->elements[i];
+ for (j = 0; j < el->num_values; j++) {
+ ret = extended_store_replace(ac, ac->new_req->op.add.message->elements, &el->values[j]);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ }
+
+ /* if DNs were set continue */
+ if (ac->ops == NULL) {
+ talloc_free(ac);
+ return ldb_next_request(module, req);
+ }
+
+ /* start with the searches */
+ return ldb_next_request(module, ac->ops->search_req);
+}
+
+/* modify */
+static int extended_dn_modify(struct ldb_module *module, struct ldb_request *req)
+{
+ /* Look over list of modifications */
+ /* Find if any are for linked attributes */
+ /* Determine the effect of the modification */
+ /* Apply the modify to the linked entry */
+
+ int i, j;
+ struct extended_dn_context *ac;
+ int ret;
+
+ if (ldb_dn_is_special(req->op.mod.message->dn)) {
+ /* do not manipulate our control entries */
+ return ldb_next_request(module, req);
+ }
+
+ ac = extended_dn_context_init(module, req);
+ if (!ac) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ if (!ac->schema) {
+ /* without schema, this doesn't make any sense */
+ return ldb_next_request(module, req);
+ }
+
+ for (i=0; i < req->op.mod.message->num_elements; i++) {
+ const struct ldb_message_element *el = &req->op.mod.message->elements[i];
+ const struct dsdb_attribute *schema_attr
+ = dsdb_attribute_by_lDAPDisplayName(ac->schema, el->name);
+ if (!schema_attr) {
+ continue;
+ }
+
+ /* We only setup an extended DN GUID on these particular DN objects */
+ if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0) {
+ continue;
+ }
+
+ /* Before we setup a procedure to modify the incoming message, we must copy it */
+ if (!ac->new_req) {
+ struct ldb_message *msg = ldb_msg_copy(ac, req->op.mod.message);
+ if (!msg) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_build_mod_req(&ac->new_req, module->ldb, ac, msg, req->controls, ac, extended_final_callback, req);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ /* Re-calculate el */
+ el = &ac->new_req->op.mod.message->elements[i];
+ /* For each value being added, we need to setup the lookups to fill in the extended DN */
+ for (j = 0; j < el->num_values; j++) {
+ struct ldb_dn *dn = ldb_dn_from_ldb_val(ac, module->ldb, &el->values[j]);
+ if (!dn || !ldb_dn_validate(dn)) {
+ ldb_asprintf_errstring(module->ldb,
+ "could not parse attribute %s as a DN", el->name);
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+ if (((el->flags & LDB_FLAG_MOD_MASK) == LDB_FLAG_MOD_DELETE) && !ldb_dn_has_extended(dn)) {
+ /* NO need to figure this DN out, it's going to be deleted anyway */
+ continue;
+ }
+ ret = extended_store_replace(ac, req->op.mod.message->elements, &el->values[j]);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ }
+
+ /* if DNs were set continue */
+ if (ac->ops == NULL) {
+ talloc_free(ac);
+ return ldb_next_request(module, req);
+ }
+
+ /* start with the searches */
+ return ldb_next_request(module, ac->ops->search_req);
+}
+
+_PUBLIC_ const struct ldb_module_ops ldb_extended_dn_store_module_ops = {
+ .name = "extended_dn_store",
+ .add = extended_dn_add,
+ .modify = extended_dn_modify,
+};
#include "ldb/include/ldb.h"
#include "ldb/include/ldb_errors.h"
#include "ldb/include/ldb_private.h"
+#include "ldb/include/dlinklist.h"
#include "dsdb/samdb/samdb.h"
struct la_op_store {
struct la_op_store *next;
+ struct la_op_store *prev;
enum la_op {LA_OP_ADD, LA_OP_DEL} op;
struct ldb_dn *dn;
char *name;
const struct dsdb_schema *schema;
struct ldb_module *module;
struct ldb_request *req;
-
+ struct ldb_dn *add_dn;
+ struct ldb_dn *del_dn;
struct replace_context *rc;
struct la_op_store *ops;
- struct la_op_store *cur;
+ struct ldb_extended *op_response;
+ struct ldb_control **op_controls;
};
static struct la_context *linked_attributes_init(struct ldb_module *module,
ac = talloc_zero(req, struct la_context);
if (ac == NULL) {
- ldb_set_errstring(module->ldb, "Out of Memory");
+ ldb_oom(module->ldb);
return NULL;
}
* series of modify requests */
static int la_store_op(struct la_context *ac,
enum la_op op, struct ldb_val *dn,
- const char *name, const char *value)
+ const char *name)
{
- struct la_op_store *os, *tmp;
+ struct la_op_store *os;
struct ldb_dn *op_dn;
op_dn = ldb_dn_from_ldb_val(ac, ac->module->ldb, dn);
return LDB_ERR_INVALID_DN_SYNTAX;
}
- /* optimize out del - add operations that would end up
- * with no changes */
- if (ac->ops && op == LA_OP_DEL) {
- /* do a linear search to find out if there is
- * an equivalent add */
- os = ac->ops;
- while (os->next) {
-
- tmp = os->next;
- if (tmp->op == LA_OP_ADD) {
-
- if ((strcmp(name, tmp->name) == 0) &&
- (strcmp(value, tmp->value) == 0) &&
- (ldb_dn_compare(op_dn, tmp->dn) == 0)) {
-
- break;
- }
- }
- os = os->next;
- }
- if (os->next) {
- /* pair found, remove it and return */
- os->next = tmp->next;
- talloc_free(tmp);
- talloc_free(op_dn);
- return LDB_SUCCESS;
- }
- }
-
os = talloc_zero(ac, struct la_op_store);
if (!os) {
+ ldb_oom(ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
os->op = op;
os->dn = talloc_steal(os, op_dn);
- if (!os->dn) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
os->name = talloc_strdup(os, name);
if (!os->name) {
+ ldb_oom(ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- if ((op != LA_OP_DEL) && (value == NULL)) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- if (value) {
- os->value = talloc_strdup(os, value);
- if (!os->value) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
-
- if (ac->ops) {
- ac->cur->next = os;
+ /* Do deletes before adds */
+ if (op == LA_OP_ADD) {
+ DLIST_ADD_END(ac->ops, os, struct la_op_store *);
} else {
- ac->ops = os;
+ /* By adding to the head of the list, we do deletes before
+ * adds when processing a replace */
+ DLIST_ADD(ac->ops, os);
}
- ac->cur = os;
return LDB_SUCCESS;
}
static int la_mod_callback(struct ldb_request *req,
struct ldb_reply *ares);
static int la_down_req(struct la_context *ac);
-static int la_down_callback(struct ldb_request *req,
- struct ldb_reply *ares);
const struct dsdb_attribute *target_attr;
struct la_context *ac;
const char *attr_name;
- const char *attr_val;
int ret;
int i, j;
}
attr_name = target_attr->lDAPDisplayName;
- attr_val = ldb_dn_get_linearized(ac->req->op.add.message->dn);
for (j = 0; j < el->num_values; j++) {
ret = la_store_op(ac, LA_OP_ADD,
&el->values[j],
- attr_name, attr_val);
+ attr_name);
if (ret != LDB_SUCCESS) {
return ret;
}
/* if no linked attributes are present continue */
if (ac->ops == NULL) {
+ /* nothing to do for this module, proceed */
talloc_free(ac);
return ldb_next_request(module, req);
}
struct replace_context *rc;
struct la_context *ac;
const char *attr_name;
- const char *dn;
int i, j;
int ret = LDB_SUCCESS;
case LDB_REPLY_ENTRY:
if (ldb_dn_compare(ares->message->dn, ac->req->op.mod.message->dn) != 0) {
+ ldb_asprintf_errstring(ac->module->ldb,
+ "linked_attributes: %s is not the DN we were looking for", ldb_dn_get_linearized(ares->message->dn));
/* Guh? We only asked for this DN */
- ldb_oom(ac->module->ldb);
talloc_free(ares);
return ldb_module_done(ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
}
- dn = ldb_dn_get_linearized(ac->req->op.add.message->dn);
+ ac->add_dn = ac->del_dn = talloc_steal(ac, ares->message->dn);
- for (i = 0; i < rc->num_elements; i++) {
+ /* We don't populate 'rc' for ADD - it can't be deleting elements anyway */
+ for (i = 0; rc && i < rc->num_elements; i++) {
schema_attr = dsdb_attribute_by_lDAPDisplayName(ac->schema, rc->el[i].name);
if (!schema_attr) {
}
attr_name = target_attr->lDAPDisplayName;
- /* make sure we manage each value */
+ /* Now we know what was there, we can remove it for the re-add */
for (j = 0; j < search_el->num_values; j++) {
ret = la_store_op(ac, LA_OP_DEL,
&search_el->values[j],
- attr_name, dn);
+ attr_name);
if (ret != LDB_SUCCESS) {
talloc_free(ares);
return ldb_module_done(ac->req,
talloc_free(ares);
- /* Start with the original request */
- ret = la_down_req(ac);
- if (ret != LDB_SUCCESS) {
- return ldb_module_done(ac->req, NULL, NULL, ret);
+ if (ac->req->operation == LDB_ADD) {
+ /* Start the modifies to the backlinks */
+ ret = la_do_mod_request(ac);
+
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ ret);
+ }
+ } else {
+ /* Start with the original request */
+ ret = la_down_req(ac);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
}
return LDB_SUCCESS;
}
int i, j;
struct la_context *ac;
struct ldb_request *search_req;
+ const char **attrs;
+
int ret;
if (ldb_dn_is_special(req->op.mod.message->dn)) {
return ldb_next_request(module, req);
}
- ac->rc = NULL;
+ ac->rc = talloc_zero(ac, struct replace_context);
+ if (!ac->rc) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
for (i=0; i < req->op.mod.message->num_elements; i++) {
bool store_el = false;
const char *attr_name;
- const char *attr_val;
const struct dsdb_attribute *target_attr;
const struct ldb_message_element *el = &req->op.mod.message->elements[i];
const struct dsdb_attribute *schema_attr
}
attr_name = target_attr->lDAPDisplayName;
- attr_val = ldb_dn_get_linearized(ac->req->op.mod.message->dn);
-
+
switch (el->flags & LDB_FLAG_MOD_MASK) {
case LDB_FLAG_MOD_REPLACE:
/* treat as just a normal add the delete part is handled by the callback */
for (j = 0; j < el->num_values; j++) {
ret = la_store_op(ac, LA_OP_ADD,
&el->values[j],
- attr_name, attr_val);
+ attr_name);
if (ret != LDB_SUCCESS) {
return ret;
}
for (j = 0; j < el->num_values; j++) {
ret = la_store_op(ac, LA_OP_DEL,
&el->values[j],
- attr_name, attr_val);
+ attr_name);
if (ret != LDB_SUCCESS) {
return ret;
}
if (store_el) {
struct ldb_message_element *search_el;
- /* Fill out ac->rc only if we have to find the old values */
- if (!ac->rc) {
- ac->rc = talloc_zero(ac, struct replace_context);
- if (!ac->rc) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
-
search_el = talloc_realloc(ac->rc, ac->rc->el,
struct ldb_message_element,
ac->rc->num_elements +1);
ac->rc->num_elements++;
}
}
-
- /* both replace and delete without values are handled in the callback
- * after the search on the entry to be modified is performed */
-
- /* Only bother doing a search of this entry (to find old
- * values) if replace or delete operations are attempted */
- if (ac->rc) {
- const char **attrs;
-
- attrs = talloc_array(ac->rc, const char *, ac->rc->num_elements +1);
+
+ if (ac->ops || ac->rc->el) {
+ /* both replace and delete without values are handled in the callback
+ * after the search on the entry to be modified is performed */
+
+ attrs = talloc_array(ac->rc, const char *, ac->rc->num_elements + 1);
if (!attrs) {
ldb_oom(module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- for (i = 0; i < ac->rc->num_elements; i++) {
+ for (i = 0; ac->rc && i < ac->rc->num_elements; i++) {
attrs[i] = ac->rc->el[i].name;
}
attrs[i] = NULL;
-
+
/* The callback does all the hard work here */
ret = ldb_build_search_req(&search_req, module->ldb, ac,
req->op.mod.message->dn,
ac, la_mod_search_callback,
req);
+ /* We need to figure out our own extended DN, to fill in as the backlink target */
+ if (ret == LDB_SUCCESS) {
+ ret = ldb_request_add_control(search_req,
+ LDB_CONTROL_EXTENDED_DN_OID,
+ false, NULL);
+ }
if (ret == LDB_SUCCESS) {
talloc_steal(search_req, attrs);
-
+
ret = ldb_next_request(module, search_req);
}
-
} else {
- if (ac->ops) {
- /* Start with the original request */
- ret = la_down_req(ac);
- } else {
- /* nothing to do for this module, proceed */
- talloc_free(ac);
- ret = ldb_next_request(module, req);
- }
+ /* nothing to do for this module, proceed */
+ talloc_free(ac);
+ ret = ldb_next_request(module, req);
}
return ret;
}
/* delete, rename */
-static int linked_attributes_op(struct ldb_module *module, struct ldb_request *req)
+static int linked_attributes_del(struct ldb_module *module, struct ldb_request *req)
{
struct ldb_request *search_req;
- struct ldb_dn *base_dn;
struct la_context *ac;
const char **attrs;
WERROR werr;
- Regain our sainity
*/
- switch (req->operation) {
- case LDB_RENAME:
- base_dn = req->op.rename.olddn;
- break;
- case LDB_DELETE:
- base_dn = req->op.del.dn;
- break;
- default:
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
ac = linked_attributes_init(module, req);
if (!ac) {
return LDB_ERR_OPERATIONS_ERROR;
}
ret = ldb_build_search_req(&search_req, module->ldb, req,
- base_dn, LDB_SCOPE_BASE,
+ req->op.del.dn, LDB_SCOPE_BASE,
"(objectClass=*)", attrs,
NULL,
ac, la_op_search_callback,
return ldb_next_request(module, search_req);
}
+/* delete, rename */
+static int linked_attributes_rename(struct ldb_module *module, struct ldb_request *req)
+{
+ struct la_context *ac;
+
+ /* This gets complex: We need to:
+ - Do a search for the entry
+ - Wait for these result to appear
+ - In the callback for the result, issue a modify
+ request based on the linked attributes found
+ - Wait for each modify result
+ - Regain our sainity
+ */
+
+ ac = linked_attributes_init(module, req);
+ if (!ac) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ if (!ac->schema) {
+ /* without schema, this doesn't make any sense */
+ return ldb_next_request(module, req);
+ }
+
+ /* start with the original request */
+ return la_down_req(ac);
+}
+
+
static int la_op_search_callback(struct ldb_request *req,
struct ldb_reply *ares)
{
const struct dsdb_attribute *target_attr;
const struct ldb_message_element *el;
const char *attr_name;
- const char *deldn;
- const char *adddn;
int i, j;
int ret;
switch (ac->req->operation) {
case LDB_DELETE:
- deldn = ldb_dn_get_linearized(ac->req->op.del.dn);
- adddn = NULL;
+ ac->del_dn = talloc_steal(ac, ares->message->dn);
break;
case LDB_RENAME:
- deldn = ldb_dn_get_linearized(ac->req->op.rename.olddn);
- adddn = ldb_dn_get_linearized(ac->req->op.rename.newdn);
+ ac->add_dn = talloc_steal(ac, ares->message->dn);
+ ac->del_dn = talloc_steal(ac, ac->req->op.rename.olddn);
break;
default:
talloc_free(ares);
+ ldb_set_errstring(ac->module->ldb,
+ "operations must be delete or rename");
return ldb_module_done(ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
}
for (j = 0; j < el->num_values; j++) {
ret = la_store_op(ac, LA_OP_DEL,
&el->values[j],
- attr_name, deldn);
- if (ret != LDB_SUCCESS) {
- talloc_free(ares);
- return ldb_module_done(ac->req,
- NULL, NULL, ret);
+ attr_name);
+
+ /* for renames, ensure we add it back */
+ if (ret == LDB_SUCCESS
+ && ac->req->operation == LDB_RENAME) {
+ ret = la_store_op(ac, LA_OP_ADD,
+ &el->values[j],
+ attr_name);
}
- if (!adddn) continue;
- ret = la_store_op(ac, LA_OP_ADD,
- &el->values[j],
- attr_name, adddn);
if (ret != LDB_SUCCESS) {
talloc_free(ares);
return ldb_module_done(ac->req,
talloc_free(ares);
- /* start the mod requests chain */
- ret = la_down_req(ac);
- if (ret != LDB_SUCCESS) {
- return ldb_module_done(ac->req, NULL, NULL, ret);
+
+ switch (ac->req->operation) {
+ case LDB_DELETE:
+ /* start the mod requests chain */
+ ret = la_down_req(ac);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ break;
+ case LDB_RENAME:
+
+ ret = la_do_mod_request(ac);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ ret);
+ }
+
+ return ret;
+
+ default:
+ talloc_free(ares);
+ ldb_set_errstring(ac->module->ldb,
+ "operations must be delete or rename");
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
}
return LDB_SUCCESS;
}
struct ldb_context *ldb;
int ret;
+ /* If we have no modifies in the queue, we are done! */
+ if (!ac->ops) {
+ return ldb_module_done(ac->req, ac->op_controls,
+ ac->op_response, LDB_SUCCESS);
+ }
+
ldb = ac->module->ldb;
/* Create the modify request */
ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- new_msg->dn = ldb_dn_copy(new_msg, ac->ops->dn);
- if (!new_msg->dn) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
+ new_msg->dn = ac->ops->dn;
if (ac->ops->op == LA_OP_ADD) {
ret = ldb_msg_add_empty(new_msg, ac->ops->name,
ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- ret_el->values[0] = data_blob_string_const(ac->ops->value);
ret_el->num_values = 1;
+ if (ac->ops->op == LA_OP_ADD) {
+ ret_el->values[0] = data_blob_string_const(ldb_dn_extended_linearized(new_msg, ac->add_dn, 1));
+ } else {
+ ret_el->values[0] = data_blob_string_const(ldb_dn_extended_linearized(new_msg, ac->del_dn, 1));
+ }
+
+#if 0
+ ldb_debug(ac->module->ldb, LDB_DEBUG_WARNING,
+ "link on %s %s: %s %s\n",
+ ldb_dn_get_linearized(new_msg->dn), ret_el->name,
+ ret_el->values[0].data, ac->ops->op == LA_OP_ADD ? "added" : "deleted");
+#endif
/* use ac->ops as the mem_ctx so that the request will be freed
* in the callback as soon as completed */
{
struct la_context *ac;
struct la_op_store *os;
- int ret;
ac = talloc_get_type(req->context, struct la_context);
talloc_free(ares);
- if (ac->ops) {
- os = ac->ops;
- ac->ops = os->next;
+ os = ac->ops;
+ DLIST_REMOVE(ac->ops, os);
+
+ /* this frees the request too
+ * DO NOT access 'req' after this point */
+ talloc_free(os);
- /* this frees the request too
- * DO NOT access 'req' after this point */
- talloc_free(os);
+ return la_do_mod_request(ac);
+}
+
+/* Having done the original operation, then try to fix up all the linked attributes for modify and delete */
+static int la_mod_del_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ int ret;
+ struct la_context *ac;
+ ac = talloc_get_type(req->context, struct la_context);
+
+ if (!ares) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
}
- /* If we still have modifies in the queue, then run them */
- if (ac->ops) {
- ret = la_do_mod_request(ac);
- } else {
- /* Otherwise, we are done! */
- ret = ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
+ if (ares->type != LDB_REPLY_DONE) {
+ ldb_set_errstring(ac->module->ldb,
+ "invalid ldb_reply_type in callback");
+ talloc_free(ares);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
}
+
+ ac->op_controls = talloc_steal(ac, ares->controls);
+ ac->op_response = talloc_steal(ac, ares->response);
+ /* If we have modfies to make, this is the time to do them for modify and delete */
+ ret = la_do_mod_request(ac);
+
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
+ talloc_free(ares);
+
+ /* la_do_mod_request has already sent the callbacks */
return LDB_SUCCESS;
+
+}
+
+/* Having done the original rename try to fix up all the linked attributes */
+static int la_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ int ret;
+ struct la_context *ac;
+ struct ldb_request *search_req;
+ const char **attrs;
+ WERROR werr;
+ ac = talloc_get_type(req->context, struct la_context);
+
+ if (!ares) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ if (ares->type != LDB_REPLY_DONE) {
+ ldb_set_errstring(ac->module->ldb,
+ "invalid ldb_reply_type in callback");
+ talloc_free(ares);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ werr = dsdb_linked_attribute_lDAPDisplayName_list(ac->schema, ac, &attrs);
+ if (!W_ERROR_IS_OK(werr)) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_build_search_req(&search_req, ac->module->ldb, req,
+ ac->req->op.rename.newdn, LDB_SCOPE_BASE,
+ "(objectClass=*)", attrs,
+ NULL,
+ ac, la_op_search_callback,
+ req);
+
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ talloc_steal(search_req, attrs);
+
+ if (ret == LDB_SUCCESS) {
+ ret = ldb_request_add_control(search_req,
+ LDB_CONTROL_EXTENDED_DN_OID,
+ false, NULL);
+ }
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ ret);
+ }
+
+ ac->op_controls = talloc_steal(ac, ares->controls);
+ ac->op_response = talloc_steal(ac, ares->response);
+
+ return ldb_next_request(ac->module, search_req);
+}
+
+/* Having done the original add, then try to fix up all the linked attributes
+
+ This is done after the add so the links can get the extended DNs correctly.
+ */
+static int la_add_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ int ret;
+ struct la_context *ac;
+ ac = talloc_get_type(req->context, struct la_context);
+
+ if (!ares) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ if (ares->type != LDB_REPLY_DONE) {
+ ldb_set_errstring(ac->module->ldb,
+ "invalid ldb_reply_type in callback");
+ talloc_free(ares);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ if (ac->ops) {
+ struct ldb_request *search_req;
+ static const char *attrs[] = { NULL };
+
+ /* The callback does all the hard work here - we need
+ * the objectGUID and SID of the added record */
+ ret = ldb_build_search_req(&search_req, ac->module->ldb, ac,
+ ac->req->op.add.message->dn,
+ LDB_SCOPE_BASE,
+ "(objectClass=*)", attrs,
+ NULL,
+ ac, la_mod_search_callback,
+ ac->req);
+
+ if (ret == LDB_SUCCESS) {
+ ret = ldb_request_add_control(search_req,
+ LDB_CONTROL_EXTENDED_DN_OID,
+ false, NULL);
+ }
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ ret);
+ }
+
+ ac->op_controls = talloc_steal(ac, ares->controls);
+ ac->op_response = talloc_steal(ac, ares->response);
+
+ return ldb_next_request(ac->module, search_req);
+
+ } else {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
}
+/* Reconstruct the original request, but pointing at our local callback to finish things off */
static int la_down_req(struct la_context *ac)
{
struct ldb_request *down_req;
ret = ldb_build_add_req(&down_req, ac->module->ldb, ac,
ac->req->op.add.message,
ac->req->controls,
- ac, la_down_callback,
+ ac, la_add_callback,
ac->req);
break;
case LDB_MODIFY:
ret = ldb_build_mod_req(&down_req, ac->module->ldb, ac,
ac->req->op.mod.message,
ac->req->controls,
- ac, la_down_callback,
+ ac, la_mod_del_callback,
ac->req);
break;
case LDB_DELETE:
ret = ldb_build_del_req(&down_req, ac->module->ldb, ac,
ac->req->op.del.dn,
ac->req->controls,
- ac, la_down_callback,
+ ac, la_mod_del_callback,
ac->req);
break;
case LDB_RENAME:
ac->req->op.rename.olddn,
ac->req->op.rename.newdn,
ac->req->controls,
- ac, la_down_callback,
+ ac, la_rename_callback,
ac->req);
break;
default:
return ldb_next_request(ac->module, down_req);
}
-/* Having done the original operation, then try to fix up all the linked attributes */
-static int la_down_callback(struct ldb_request *req, struct ldb_reply *ares)
-{
- struct la_context *ac;
-
- ac = talloc_get_type(req->context, struct la_context);
-
- if (!ares) {
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
- if (ares->error != LDB_SUCCESS) {
- return ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
- }
-
- if (ares->type != LDB_REPLY_DONE) {
- ldb_set_errstring(ac->module->ldb,
- "invalid ldb_reply_type in callback");
- talloc_free(ares);
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
- /* If we have modfies to make, then run them */
- if (ac->ops) {
- return la_do_mod_request(ac);
- } else {
- return ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
- }
-}
_PUBLIC_ const struct ldb_module_ops ldb_linked_attributes_module_ops = {
.name = "linked_attributes",
.add = linked_attributes_add,
.modify = linked_attributes_modify,
- .del = linked_attributes_op,
- .rename = linked_attributes_op,
+ .del = linked_attributes_del,
+ .rename = linked_attributes_rename,
};
Each incoming add/modify is split into a remote, and a local request, done in that order.
- We maintain a list of attributes that are kept locally:
+ We maintain a list of attributes that are kept locally - perhaps
+ this should use the @KLUDGE_ACL list of passwordAttribute
*/
static const char * const password_attrs[] = {
continue;
}
/* Look to see if this attributeSyntax is a DN */
- if (!((strcmp(attribute->attributeSyntax_oid, "2.5.5.1") == 0) ||
- (strcmp(attribute->attributeSyntax_oid, "2.5.5.7") == 0))) {
+ if (strcmp(attribute->attributeSyntax_oid, "2.5.5.1") != 0) {
continue;
}
for (j = 0; j < msg->elements[i].num_values; j++) {
int ret;
/* see if its for the rootDSE - only a base search on the "" DN qualifies */
- if (req->op.search.scope != LDB_SCOPE_BASE ||
- ( ! ldb_dn_is_null(req->op.search.base))) {
+ if (!(req->op.search.scope == LDB_SCOPE_BASE && ldb_dn_is_null(req->op.search.base))) {
/* Otherwise, pass down to the rest of the stack */
return ldb_next_request(module, req);
}
}
nextRid = ldb_msg_find_attr_as_string(ares->message,
- "nextRid", NULL);
+ "nextRid", NULL);
if (nextRid == NULL) {
ldb_asprintf_errstring(ac->module->ldb,
- "attribute nextRid not found in %s\n",
- ldb_dn_get_linearized(ares->message->dn));
+ "while looking for domain above %s attribute nextRid not found in %s\n",
+ ldb_dn_get_linearized(ac->req->op.add.message->dn),
+ ldb_dn_get_linearized(ares->message->dn));
ret = LDB_ERR_OPERATIONS_ERROR;
- break;;
+ break;
}
ac->next_rid = strtol(nextRid, NULL, 0);
talloc_free(ares);
ret = LDB_SUCCESS;
+ ldb_reset_err_string(ac->module->ldb);
break;
case LDB_REPLY_REFERRAL:
"nextRid", NULL);
if (nextRid == NULL) {
ldb_asprintf_errstring(ac->module->ldb,
- "attribute nextRid not found in %s\n",
- ldb_dn_get_linearized(ares->message->dn));
+ "while looking for forign sid %s attribute nextRid not found in %s\n",
+ dom_sid_string(ares, ac->sid), ldb_dn_get_linearized(ares->message->dn));
ret = LDB_ERR_OPERATIONS_ERROR;
break;
}
{
static const char * const attrs[3] = { "nextRid", "name", NULL };
struct ldb_request *req;
+ NTSTATUS status;
char *filter;
int ret;
return LDB_ERR_OPERATIONS_ERROR;
}
- ac->domain_sid = dom_sid_dup(ac, ac->sid);
- if (!ac->domain_sid) {
+ status = dom_sid_split_rid(ac, ac->sid, &ac->domain_sid, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
return LDB_ERR_OPERATIONS_ERROR;
}
- /* get the domain component part of the provided SID */
- ac->domain_sid->num_auths--;
filter = talloc_asprintf(ac, "(&(objectSid=%s)(objectclass=domain))",
ldap_encode_ndr_dom_sid(ac, ac->domain_sid));
static struct ldb_val encode_guid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
{
struct GUID guid;
- NTSTATUS status = GUID_from_string((char *)val->data, &guid);
+ NTSTATUS status = GUID_from_data_blob(val, &guid);
enum ndr_err_code ndr_err;
struct ldb_val out = data_blob(NULL, 0);
static struct ldb_val guid_always_string(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
{
- struct GUID *guid;
struct ldb_val out = data_blob(NULL, 0);
- if (val->length >= 32 && val->data[val->length] == '\0') {
- ldb_handler_copy(module->ldb, ctx, val, &out);
- } else {
- enum ndr_err_code ndr_err;
-
- guid = talloc(ctx, struct GUID);
- if (guid == NULL) {
- return out;
- }
- ndr_err = ndr_pull_struct_blob(val, guid, NULL, guid,
- (ndr_pull_flags_fn_t)ndr_pull_GUID);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(guid);
- return out;
- }
- out = data_blob_string_const(GUID_string(ctx, guid));
- talloc_free(guid);
+ struct GUID guid;
+ NTSTATUS status = GUID_from_data_blob(val, &guid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return out;
}
- return out;
+ return data_blob_string_const(GUID_string(ctx, &guid));
}
static struct ldb_val encode_ns_guid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
static struct ldb_val guid_ns_string(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
{
struct ldb_val out = data_blob(NULL, 0);
- if (val->length >= 32 && val->data[val->length] == '\0') {
- struct GUID guid;
- GUID_from_string((char *)val->data, &guid);
- out = data_blob_string_const(NS_GUID_string(ctx, &guid));
- } else {
- enum ndr_err_code ndr_err;
- struct GUID *guid_p;
- guid_p = talloc(ctx, struct GUID);
- if (guid_p == NULL) {
- return out;
- }
- ndr_err = ndr_pull_struct_blob(val, guid_p, NULL, guid_p,
- (ndr_pull_flags_fn_t)ndr_pull_GUID);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(guid_p);
- return out;
- }
- out = data_blob_string_const(NS_GUID_string(ctx, guid_p));
- talloc_free(guid_p);
+ struct GUID guid;
+ NTSTATUS status = GUID_from_data_blob(val, &guid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return out;
}
- return out;
+ return data_blob_string_const(NS_GUID_string(ctx, &guid));
}
/* The backend holds binary sids, so just copy them back */
#define DSDB_CONTROL_REPLICATED_UPDATE_OID "1.3.6.1.4.1.7165.4.3.3"
/* DSDB_CONTROL_REPLICATED_UPDATE_OID has NULL data */
+#define DSDB_CONTROL_DN_STORAGE_FORMAT_OID "1.3.6.1.4.1.7165.4.3.4"
+/* DSDB_CONTROL_DN_STORAGE_FORMAT_OID has NULL data and behaves very
+ * much like LDB_CONTROL_EXTENDED_DN_OID when the DB stores an
+ * extended DN, and otherwise returns normal DNs */
+
#define DSDB_EXTENDED_REPLICATED_OBJECTS_OID "1.3.6.1.4.1.7165.4.4.1"
struct dsdb_extended_replicated_object {
struct ldb_message *msg;
*/
#define DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID "1.3.6.1.4.1.7165.4.4.2"
+#define DSDB_OPENLDAP_DEREFERENCE_CONTROL "1.3.6.1.4.1.1466.115.121.1.12"
+
+struct dsdb_openldap_dereference {
+ const char *source_attribute;
+ const char **dereference_attribute;
+};
+
+struct dsdb_openldap_dereference_control {
+ struct dsdb_openldap_dereference **dereference;
+};
+
+struct dsdb_openldap_dereference_result {
+ const char *source_attribute;
+ const char *dereferenced_dn;
+ int num_attributes;
+ struct ldb_message_element *attributes;
+};
+
+struct dsdb_openldap_dereference_result_control {
+ struct dsdb_openldap_dereference_result **attributes;
+};
+
#endif /* __SAMDB_H__ */
struct ldb_request *lreq;
struct ldb_control *search_control;
struct ldb_search_options_control *search_options;
+ struct ldb_control *extended_dn_control;
+ struct ldb_extended_dn_control *extended_dn_decoded = NULL;
enum ldb_scope scope = LDB_SCOPE_DEFAULT;
const char **attrs = NULL;
const char *scope_str, *errstr = NULL;
int result = -1;
int ldb_ret = -1;
int i, j;
+ int extended_type = 1;
DEBUG(10, ("SearchRequest"));
DEBUGADD(10, (" basedn: %s", req->basedn));
ldb_request_add_control(lreq, LDB_CONTROL_SEARCH_OPTIONS_OID, false, search_options);
}
}
+
+ extended_dn_control = ldb_request_get_control(lreq, LDB_CONTROL_EXTENDED_DN_OID);
+
+ if (extended_dn_control) {
+ if (extended_dn_control->data) {
+ extended_dn_decoded = talloc_get_type(extended_dn_control->data, struct ldb_extended_dn_control);
+ extended_type = extended_dn_decoded->type;
+ } else {
+ extended_type = 0;
+ }
+ }
+
ldb_set_timeout(samdb, lreq, req->timelimit);
ldb_ret = ldb_request(samdb, lreq);
talloc_steal(ent_r, res->msgs[i]);
ent = &ent_r->msg->r.SearchResultEntry;
- ent->dn = ldb_dn_alloc_linearized(ent_r, res->msgs[i]->dn);
+ ent->dn = ldb_dn_extended_linearized(ent_r, res->msgs[i]->dn, extended_type);
ent->num_attributes = 0;
ent->attributes = NULL;
if (res->msgs[i]->num_elements == 0) {
if (sid == NULL) {
return -1;
}
- ndr_err = ndr_pull_struct_blob(in, sid, NULL, sid,
- (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
+ ndr_err = ndr_pull_struct_blob_all(in, sid, NULL, sid,
+ (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
talloc_free(sid);
return -1;
return ldb_handler_copy(ldb, mem_ctx, in, out);
}
+static int extended_dn_read_SID(struct ldb_context *ldb, void *mem_ctx,
+ const struct ldb_val *in, struct ldb_val *out)
+{
+ struct dom_sid sid;
+ enum ndr_err_code ndr_err;
+ if (ldb_comparision_objectSid_isString(in)) {
+ if (ldif_read_objectSid(ldb, mem_ctx, in, out) == 0) {
+ return 0;
+ }
+ }
+
+ /* Perhaps not a string after all */
+ *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1);
+
+ if (!out->data) {
+ return -1;
+ }
+
+ (*out).length = strhex_to_str((char *)out->data, out->length,
+ (const char *)in->data, in->length);
+
+ /* Check it looks like a SID */
+ ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, NULL, &sid,
+ (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return -1;
+ }
+ return 0;
+}
+
/*
convert a ldif formatted objectGUID to a NDR formatted blob
*/
const struct ldb_val *in, struct ldb_val *out)
{
struct GUID guid;
- char *guid_string;
NTSTATUS status;
enum ndr_err_code ndr_err;
- guid_string = talloc_strndup(mem_ctx, (const char *)in->data, in->length);
- if (!guid_string) {
- return -1;
- }
- status = GUID_from_string(guid_string, &guid);
- talloc_free(guid_string);
+ status = GUID_from_data_blob(in, &guid);
if (!NT_STATUS_IS_OK(status)) {
return -1;
}
{
struct GUID guid;
enum ndr_err_code ndr_err;
- ndr_err = ndr_pull_struct_blob(in, mem_ctx, NULL, &guid,
- (ndr_pull_flags_fn_t)ndr_pull_GUID);
+ ndr_err = ndr_pull_struct_blob_all(in, mem_ctx, NULL, &guid,
+ (ndr_pull_flags_fn_t)ndr_pull_GUID);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return -1;
}
static bool ldb_comparision_objectGUID_isString(const struct ldb_val *v)
{
- struct GUID guid;
- NTSTATUS status;
-
- if (v->length < 33) return false;
+ if (v->length != 36 && v->length != 38) return false;
- /* see if the input if null-terninated (safety check for the below) */
- if (v->data[v->length] != '\0') return false;
+ /* Might be a GUID string, can't be a binary GUID (fixed 16 bytes) */
+ return true;
+}
- status = GUID_from_string((const char *)v->data, &guid);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
+static int extended_dn_read_GUID(struct ldb_context *ldb, void *mem_ctx,
+ const struct ldb_val *in, struct ldb_val *out)
+{
+ struct GUID guid;
+ enum ndr_err_code ndr_err;
+ if (in->length == 36 && ldif_read_objectGUID(ldb, mem_ctx, in, out) == 0) {
+ return 0;
}
- return true;
+ /* Try as 'hex' form */
+ if (in->length != 32) {
+ return -1;
+ }
+
+ *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1);
+
+ if (!out->data) {
+ return -1;
+ }
+
+ (*out).length = strhex_to_str((char *)out->data, out->length,
+ (const char *)in->data, in->length);
+
+ /* Check it looks like a GUID */
+ ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, NULL, &guid,
+ (ndr_pull_flags_fn_t)ndr_pull_GUID);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return -1;
+ }
+ return 0;
}
/*
if (sd == NULL) {
return -1;
}
+ /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */
ndr_err = ndr_pull_struct_blob(in, sd, NULL, sd,
- (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
+ (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
talloc_free(sd);
return -1;
if (blob == NULL) {
return -1;
}
- ndr_err = ndr_pull_struct_blob(in, blob,
- lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
- blob,
- (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob);
+ ndr_err = ndr_pull_struct_blob_all(in, blob,
+ lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
+ blob,
+ (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
talloc_free(blob);
return -1;
return ret;
}
+static int extended_dn_write_hex(struct ldb_context *ldb, void *mem_ctx,
+ const struct ldb_val *in, struct ldb_val *out)
+{
+ *out = data_blob_string_const(data_blob_hex_string(mem_ctx, in));
+ if (!out->data) {
+ return -1;
+ }
+ return 0;
+}
+
+
#define LDB_SYNTAX_SAMBA_GUID "LDB_SYNTAX_SAMBA_GUID"
#define LDB_SYNTAX_SAMBA_OBJECT_CATEGORY "LDB_SYNTAX_SAMBA_OBJECT_CATEGORY"
#define LDB_SYNTAX_SAMBA_PREFIX_MAP "LDB_SYNTAX_SAMBA_PREFIX_MAP"
static const struct ldb_schema_syntax samba_syntaxes[] = {
{
- .name = LDB_SYNTAX_SAMBA_SID,
- .ldif_read_fn = ldif_read_objectSid,
- .ldif_write_fn = ldif_write_objectSid,
- .canonicalise_fn= ldb_canonicalise_objectSid,
- .comparison_fn = ldb_comparison_objectSid
+ .name = LDB_SYNTAX_SAMBA_SID,
+ .ldif_read_fn = ldif_read_objectSid,
+ .ldif_write_fn = ldif_write_objectSid,
+ .canonicalise_fn = ldb_canonicalise_objectSid,
+ .comparison_fn = ldb_comparison_objectSid
+ },{
+ .name = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
+ .ldif_read_fn = ldif_read_ntSecurityDescriptor,
+ .ldif_write_fn = ldif_write_ntSecurityDescriptor,
+ .canonicalise_fn = ldb_handler_copy,
+ .comparison_fn = ldb_comparison_binary
+ },{
+ .name = LDB_SYNTAX_SAMBA_GUID,
+ .ldif_read_fn = ldif_read_objectGUID,
+ .ldif_write_fn = ldif_write_objectGUID,
+ .canonicalise_fn = ldb_canonicalise_objectGUID,
+ .comparison_fn = ldb_comparison_objectGUID
},{
- .name = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
- .ldif_read_fn = ldif_read_ntSecurityDescriptor,
- .ldif_write_fn = ldif_write_ntSecurityDescriptor,
- .canonicalise_fn= ldb_handler_copy,
- .comparison_fn = ldb_comparison_binary
+ .name = LDB_SYNTAX_SAMBA_OBJECT_CATEGORY,
+ .ldif_read_fn = ldb_handler_copy,
+ .ldif_write_fn = ldb_handler_copy,
+ .canonicalise_fn = ldif_canonicalise_objectCategory,
+ .comparison_fn = ldif_comparison_objectCategory
},{
- .name = LDB_SYNTAX_SAMBA_GUID,
- .ldif_read_fn = ldif_read_objectGUID,
- .ldif_write_fn = ldif_write_objectGUID,
- .canonicalise_fn= ldb_canonicalise_objectGUID,
- .comparison_fn = ldb_comparison_objectGUID
+ .name = LDB_SYNTAX_SAMBA_PREFIX_MAP,
+ .ldif_read_fn = ldif_read_prefixMap,
+ .ldif_write_fn = ldif_write_prefixMap,
+ .canonicalise_fn = ldif_canonicalise_prefixMap,
+ .comparison_fn = ldif_comparison_prefixMap
+ }
+};
+
+static const struct ldb_dn_extended_syntax samba_dn_syntax[] = {
+ {
+ .name = "SID",
+ .read_fn = extended_dn_read_SID,
+ .write_clear_fn = ldif_write_objectSid,
+ .write_hex_fn = extended_dn_write_hex
},{
- .name = LDB_SYNTAX_SAMBA_OBJECT_CATEGORY,
- .ldif_read_fn = ldb_handler_copy,
- .ldif_write_fn = ldb_handler_copy,
- .canonicalise_fn= ldif_canonicalise_objectCategory,
- .comparison_fn = ldif_comparison_objectCategory
+ .name = "GUID",
+ .read_fn = extended_dn_read_GUID,
+ .write_clear_fn = ldif_write_objectGUID,
+ .write_hex_fn = extended_dn_write_hex
},{
- .name = LDB_SYNTAX_SAMBA_PREFIX_MAP,
- .ldif_read_fn = ldif_read_prefixMap,
- .ldif_write_fn = ldif_write_prefixMap,
- .canonicalise_fn= ldif_canonicalise_prefixMap,
- .comparison_fn = ldif_comparison_prefixMap
+ .name = "WKGUID",
+ .read_fn = ldb_handler_copy,
+ .write_clear_fn = ldb_handler_copy,
+ .write_hex_fn = ldb_handler_copy
}
};
}
}
+ for (i=0; i < ARRAY_SIZE(samba_dn_syntax); i++) {
+ int ret;
+ ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &samba_dn_syntax[i]);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+
+ }
+
return LDB_SUCCESS;
}
return LDB_SUCCESS;
}
+
+/*
+ add a extended dn syntax to the ldb_schema
+*/
+int ldb_dn_extended_add_syntax(struct ldb_context *ldb,
+ unsigned flags,
+ const struct ldb_dn_extended_syntax *syntax)
+{
+ int n;
+ struct ldb_dn_extended_syntax *a;
+
+ if (!syntax) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ n = ldb->schema.num_dn_extended_syntax + 1;
+
+ a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax,
+ struct ldb_dn_extended_syntax, n);
+
+ if (!a) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ a[ldb->schema.num_dn_extended_syntax] = *syntax;
+ ldb->schema.dn_extended_syntax = a;
+
+ ldb->schema.num_dn_extended_syntax = n;
+
+ return 0;
+}
+
+/*
+ return the extended dn syntax for a given name
+*/
+const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb,
+ const char *name)
+{
+ int i;
+ for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) {
+ if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) {
+ return &ldb->schema.dn_extended_syntax[i];
+ }
+ }
+ return NULL;
+}
+
return NULL;
}
+/* check if a control with the specified "oid" exist and return it */
+/* returns NULL if not found */
+struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid)
+{
+ int i;
+
+ /* check if there's a paged request control */
+ if (rep->controls != NULL) {
+ for (i = 0; rep->controls[i]; i++) {
+ if (strcmp(oid, rep->controls[i]->oid) == 0) {
+ break;
+ }
+ }
+
+ return rep->controls[i];
+ }
+
+ return NULL;
+}
+
/* saves the current controls list into the "saver" and replace the one in req with a new one excluding
the "exclude" control */
/* returns False on error */
struct ldb_val cf_value;
};
+struct ldb_dn_extended_component {
+
+ char *name;
+ struct ldb_val value;
+};
+
struct ldb_dn {
struct ldb_context *ldb;
bool valid_case;
char *linearized;
+ char *extended_linearized;
char *casefold;
unsigned int comp_num;
struct ldb_dn_component *components;
+ unsigned int extended_comp_num;
+ struct ldb_dn_extended_component *extended_components;
};
/* strdn may be NULL */
if (strdn->data && strdn->length) {
if (strdn->data[0] == '@') {
dn->special = true;
+ }
+ dn->extended_linearized = talloc_strndup(dn, (const char *)strdn->data, strdn->length);
+ LDB_DN_NULL_FAILED(dn->extended_linearized);
+
+ if (strdn->data[0] == '<') {
+ const char *p_save, *p = dn->extended_linearized;
+ do {
+ p_save = p;
+ p = strstr(p, ">;");
+ if (p) {
+ p = p + 2;
+ }
+ } while (p);
+
+ if (p_save == dn->extended_linearized) {
+ dn->linearized = talloc_strdup(dn, "");
+ } else {
+ dn->linearized = talloc_strdup(dn, p_save);
+ }
+ LDB_DN_NULL_FAILED(dn->linearized);
+ } else {
+ dn->linearized = dn->extended_linearized;
+ dn->extended_linearized = NULL;
}
- if (strdn->length >= 6 && strncasecmp((const char *)strdn->data, "<GUID=", 6) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a GUID string to ldb_dn structure */
- } else if (strdn->length >= 5 && strncasecmp((const char *)strdn->data, "<SID=", 5) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a SID string to ldb_dn structure */
- } else if (strdn->length >= 8 && strncasecmp((const char *)strdn->data, "<WKGUID=", 8) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a WKGUID string to ldb_dn structure */
- }
- dn->linearized = talloc_strndup(dn, (const char *)strdn->data, strdn->length);
} else {
dn->linearized = talloc_strdup(dn, "");
+ LDB_DN_NULL_FAILED(dn->linearized);
}
- LDB_DN_NULL_FAILED(dn->linearized);
return dn;
struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...)
{
- struct ldb_dn *dn;
char *strdn;
va_list ap;
if ( (! mem_ctx) || (! ldb)) return NULL;
- dn = talloc_zero(mem_ctx, struct ldb_dn);
- LDB_DN_NULL_FAILED(dn);
-
- dn->ldb = ldb;
-
va_start(ap, new_fmt);
- strdn = talloc_vasprintf(dn, new_fmt, ap);
+ strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
va_end(ap);
- LDB_DN_NULL_FAILED(strdn);
-
- if (strdn[0] == '@') {
- dn->special = true;
- }
- if (strncasecmp(strdn, "<GUID=", 6) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a GUID string to ldb_dn structure */
- } else if (strncasecmp(strdn, "<SID=", 5) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a SID string to ldb_dn structure */
- } else if (strncasecmp(strdn, "<WKGUID=", 8) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a WKGUID string to ldb_dn structure */
- }
- dn->linearized = strdn;
- return dn;
-
-failed:
- talloc_free(dn);
+ if (strdn) {
+ struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
+ talloc_free(strdn);
+ return dn;
+ }
+
return NULL;
}
*/
static bool ldb_dn_explode(struct ldb_dn *dn)
{
- char *p, *data, *d, *dt, *t;
+ char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
bool trim = false;
+ bool in_extended = false;
+ bool in_ex_name = false;
+ bool in_ex_value = false;
bool in_attr = false;
bool in_value = false;
bool in_quote = false;
bool is_oid = false;
bool escape = false;
unsigned x;
- int l;
+ int l, ret;
+ char *parse_dn;
if ( ! dn || dn->invalid) return false;
return true;
}
- if ( ! dn->linearized) {
+ if (dn->extended_linearized) {
+ parse_dn = dn->extended_linearized;
+ } else {
+ parse_dn = dn->linearized;
+ }
+
+ if ( ! parse_dn ) {
return false;
}
/* Empty DNs */
- if (dn->linearized[0] == '\0') {
+ if (parse_dn[0] == '\0') {
return true;
}
/* make sure we free this if alloced previously before replacing */
talloc_free(dn->components);
+ talloc_free(dn->extended_components);
+ dn->extended_components = NULL;
+
/* in the common case we have 3 or more components */
/* make sure all components are zeroed, other functions depend on this */
dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
dn->comp_num = 0;
/* Components data space is allocated here once */
- data = talloc_array(dn->components, char, strlen(dn->linearized) + 1);
+ data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
if (!data) {
return false;
}
- p = dn->linearized;
- in_attr = true;
+ p = parse_dn;
+ in_extended = true;
+ in_ex_name = false;
+ in_ex_value = false;
trim = true;
t = NULL;
d = dt = data;
while (*p) {
+ if (in_extended) {
+
+ if (!in_ex_name && !in_ex_value) {
+
+ if (p[0] == '<') {
+ p++;
+ ex_name = d;
+ in_ex_name = true;
+ continue;
+ } else if (p[0] == '\0') {
+ p++;
+ continue;
+ } else {
+ in_extended = false;
+ in_attr = true;
+ dt = d;
+
+ continue;
+ }
+ }
+
+ if (in_ex_name && *p == '=') {
+ *d++ = '\0';
+ p++;
+ ex_value = d;
+ in_ex_name = false;
+ in_ex_value = true;
+ continue;
+ }
+
+ if (in_ex_value && *p == '>') {
+ const struct ldb_dn_extended_syntax *extended_syntax;
+ struct ldb_val ex_val = {
+ .data = ex_value,
+ .length = d - ex_value
+ };
+
+ *d++ = '\0';
+ p++;
+ in_ex_value = false;
+
+ /* Process name and ex_value */
+
+ dn->extended_components = talloc_realloc(dn,
+ dn->extended_components,
+ struct ldb_dn_extended_component,
+ dn->extended_comp_num + 1);
+ if ( ! dn->extended_components) {
+ /* ouch ! */
+ goto failed;
+ }
+
+ extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
+ if (!extended_syntax) {
+ /* We don't know about this type of extended DN */
+ goto failed;
+ }
+
+ dn->extended_components[dn->extended_comp_num].name = talloc_strdup(dn->extended_components, ex_name);
+ if (!dn->extended_components[dn->extended_comp_num].name) {
+ /* ouch */
+ goto failed;
+ }
+ ret = extended_syntax->read_fn(dn->ldb, dn->extended_components,
+ &ex_val, &dn->extended_components[dn->extended_comp_num].value);
+ if (ret != LDB_SUCCESS) {
+ dn->invalid = true;
+ goto failed;
+ }
+
+ dn->extended_comp_num++;
+ if (*p == '\0') {
+ /* We have reached the end (extended component only)! */
+ talloc_free(data);
+ return true;
+
+ } else if (*p == ';') {
+ p++;
+ continue;
+ } else {
+ dn->invalid = true;
+ goto failed;
+ }
+ }
+
+ *d++ = *p++;
+ continue;
+ }
if (in_attr) {
if (trim) {
if (*p == ' ') {
goto failed;
}
+ /* Copy this character across from parse_dn, now we have trimmed out spaces */
*d++ = *p++;
continue;
}
trim = true;
l = 0;
+ /* Terminate this string in d (which is a copy of parse_dn with spaces trimmed) */
*d++ = '\0';
dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
if ( ! dn->components[dn->comp_num].name) {
return dn->linearized;
}
+char *ldb_dn_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
+{
+ const char *linearized = ldb_dn_get_linearized(dn);
+ char *p;
+ int i;
+
+ if (!linearized) {
+ return NULL;
+ }
+
+ if (!ldb_dn_has_extended(dn)) {
+ return talloc_strdup(mem_ctx, linearized);
+ }
+
+ if (!ldb_dn_validate(dn)) {
+ return NULL;
+ }
+
+ for (i=0; i < dn->extended_comp_num; i++) {
+ struct ldb_val val;
+ int ret;
+ const struct ldb_dn_extended_syntax *extended_syntax;
+ const char *name = dn->extended_components[i].name;
+
+ extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
+
+ if (mode == 1) {
+ ret = extended_syntax->write_clear_fn(dn->ldb, mem_ctx,
+ &dn->extended_components[i].value,
+ &val);
+ } else if (mode == 0) {
+ ret = extended_syntax->write_hex_fn(dn->ldb, mem_ctx,
+ &dn->extended_components[i].value,
+ &val);
+ } else {
+ ret = -1;
+ }
+
+ if (ret != LDB_SUCCESS) {
+ return NULL;
+ }
+
+ if (i == 0) {
+ p = talloc_asprintf(mem_ctx, "<%s=%s>", dn->extended_components[i].name, val.data);
+ } else {
+ p = talloc_asprintf_append(p, ";<%s=%s>", dn->extended_components[i].name, val.data);
+ }
+
+ talloc_free(val.data);
+
+ if (!p) {
+ return NULL;
+ }
+ }
+
+ if (dn->extended_comp_num && *linearized) {
+ p = talloc_asprintf_append(p, ";%s", linearized);
+ }
+
+ if (!p) {
+ return NULL;
+ }
+
+ return p;
+}
+
+
+
char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
{
return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
return dst;
}
+static struct ldb_dn_extended_component ldb_dn_extended_copy_component(void *mem_ctx, struct ldb_dn_extended_component *src)
+{
+ struct ldb_dn_extended_component dst;
+
+ memset(&dst, 0, sizeof(dst));
+
+ if (src == NULL) {
+ return dst;
+ }
+
+ dst.value = ldb_val_dup(mem_ctx, &(src->value));
+ if (dst.value.data == NULL) {
+ return dst;
+ }
+
+ dst.name = talloc_strdup(mem_ctx, src->name);
+ if (dst.name == NULL) {
+ LDB_FREE(dst.value.data);
+ return dst;
+ }
+
+ return dst;
+}
+
struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
{
struct ldb_dn *new_dn;
}
}
+ if (dn->extended_components) {
+ int i;
+
+ new_dn->extended_components = talloc_zero_array(new_dn, struct ldb_dn_extended_component, dn->extended_comp_num);
+ if ( ! new_dn->extended_components) {
+ talloc_free(new_dn);
+ return NULL;
+ }
+
+ for (i = 0; i < dn->extended_comp_num; i++) {
+ new_dn->extended_components[i] = ldb_dn_extended_copy_component(new_dn->extended_components, &dn->extended_components[i]);
+ if ( ! new_dn->extended_components[i].value.data) {
+ talloc_free(new_dn);
+ return NULL;
+ }
+ }
+ }
+
if (dn->casefold) {
new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
if ( ! new_dn->casefold) {
}
}
+ if (dn->extended_linearized) {
+ new_dn->extended_linearized = talloc_strdup(new_dn, dn->extended_linearized);
+ if ( ! new_dn->extended_linearized) {
+ talloc_free(new_dn);
+ return NULL;
+ }
+ }
+
return new_dn;
}
dn->linearized = t;
}
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ if (dn->extended_linearized) {
+ LDB_FREE(dn->extended_linearized);
+ }
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
return true;
}
dn->linearized = t;
}
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
+
return true;
}
LDB_FREE(dn->casefold);
LDB_FREE(dn->linearized);
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
+
return true;
}
LDB_FREE(dn->casefold);
LDB_FREE(dn->linearized);
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
return true;
}
return NULL;
}
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
return new_dn;
}
LDB_FREE(dn->casefold);
LDB_FREE(dn->linearized);
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ dn->extended_comp_num = 0;
+ LDB_FREE(dn->extended_components);
return LDB_SUCCESS;
}
+const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name)
+{
+ int i;
+ if ( ! ldb_dn_validate(dn)) {
+ return NULL;
+ }
+ for (i=0; i < dn->extended_comp_num; i++) {
+ if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
+ return &dn->extended_components[i].value;
+ }
+ }
+ return NULL;
+}
+
+int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val)
+{
+ struct ldb_dn_extended_component *p;
+ int i;
+
+ if ( ! ldb_dn_validate(dn)) {
+ return LDB_ERR_OTHER;
+ }
+
+ for (i=0; i < dn->extended_comp_num; i++) {
+ if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
+ if (val) {
+ dn->extended_components[i].value = ldb_val_dup(dn->extended_components, val);
+
+ dn->extended_components[i].name = talloc_strdup(dn->extended_components, name);
+ if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
+ dn->invalid = true;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ } else {
+ if (i != (dn->extended_comp_num - 1)) {
+ memmove(&dn->extended_components[i], &dn->extended_components[i+1],
+ ((dn->extended_comp_num-1) - i)*sizeof(*dn->extended_components));
+ }
+ dn->extended_comp_num--;
+
+ dn->extended_components = talloc_realloc(dn,
+ dn->extended_components,
+ struct ldb_dn_extended_component,
+ dn->extended_comp_num);
+ if (!dn->extended_components) {
+ dn->invalid = true;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ return 0;
+ }
+ }
+ }
+
+ p = dn->extended_components
+ = talloc_realloc(dn,
+ dn->extended_components,
+ struct ldb_dn_extended_component,
+ dn->extended_comp_num + 1);
+ if (!dn->extended_components) {
+ dn->invalid = true;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ p[dn->extended_comp_num].value = ldb_val_dup(dn->extended_components, val);
+ p[dn->extended_comp_num].name = talloc_strdup(p, name);
+
+ if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
+ dn->invalid = true;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ dn->extended_components = p;
+ dn->extended_comp_num++;
+
+ return 0;
+}
+
+void ldb_dn_remove_extended_components(struct ldb_dn *dn)
+{
+ dn->extended_comp_num = 0;
+ LDB_FREE(dn->extended_components);
+}
+
bool ldb_dn_is_valid(struct ldb_dn *dn)
{
if ( ! dn) return false;
return dn->special;
}
+bool ldb_dn_has_extended(struct ldb_dn *dn)
+{
+ if ( ! dn || dn->invalid) return false;
+ if (dn->extended_linearized && (dn->extended_linearized[0] == '<')) return true;
+ return dn->extended_comp_num != 0;
+}
+
bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
{
if ( ! dn || dn->invalid) return false;
bool ldb_dn_is_null(struct ldb_dn *dn)
{
if ( ! dn || dn->invalid) return false;
+ if (ldb_dn_has_extended(dn)) return false;
if (dn->linearized && (dn->linearized[0] == '\0')) return true;
return false;
}
TALLOC_CTX *mem_ctx;
unsigned int i, j;
int total=0, ret;
+ char *p;
const struct ldb_message *msg;
mem_ctx = talloc_named_const(NULL, 0, "ldb_ldif_write");
msg = ldif->msg;
-
- ret = fprintf_fn(private_data, "dn: %s\n", ldb_dn_get_linearized(msg->dn));
+ p = ldb_dn_extended_linearized(mem_ctx, msg->dn, 1);
+ ret = fprintf_fn(private_data, "dn: %s\n", p);
+ talloc_free(p);
CHECK_RET;
if (ldif->changetype != LDB_CHANGETYPE_NONE) {
attribute handler structure
attr -> The attribute name
- flags -> LDB_ATTR_FLAG_*
ldif_read_fn -> convert from ldif to binary format
ldif_write_fn -> convert from binary to ldif format
canonicalise_fn -> canonicalise a value, for use by indexing and dn construction
const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb,
const char *name);
+struct ldb_dn_extended_syntax {
+ const char *name;
+ ldb_attr_handler_t read_fn;
+ ldb_attr_handler_t write_clear_fn;
+ ldb_attr_handler_t write_hex_fn;
+};
+
+const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb,
+ const char *name);
+
/**
The attribute is not returned by default
*/
*/
struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid);
+/**
+ check if a control with the specified "oid" exist and return it
+ \param rep the reply struct where to add the control
+ \param oid the object identifier of the control as string
+
+ \return the control, NULL if not found
+*/
+struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid);
+
/**
Search the database
\return array of ldb_control elements
*/
struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings);
+char *ldb_dn_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode);
+const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name);
+int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val);
+
+void ldb_dn_remove_extended_components(struct ldb_dn *dn);
+bool ldb_dn_has_extended(struct ldb_dn *dn);
+
+int ldb_dn_extended_add_syntax(struct ldb_context *ldb,
+ unsigned flags,
+ const struct ldb_dn_extended_syntax *syntax);
#endif
/* attribute handling table */
unsigned num_attributes;
struct ldb_schema_attribute *attributes;
+
+ unsigned num_dn_extended_syntax;
+ struct ldb_dn_extended_syntax *dn_extended_syntax;
};
/*
if (ldif == NULL) {
return Py_None;
} else {
+ /* We don't want this attached to the 'ldb' any more */
+ talloc_steal(NULL, ldif);
return Py_BuildValue((char *)"(iO)", ldif->changetype,
SWIG_NewPointerObj(ldif->msg, SWIGTYPE_p_ldb_message, 0));
}
# This file was automatically generated by SWIG (http://www.swig.org).
-# Version 1.3.36
+# Version 1.3.35
#
# Don't modify this file, modify the SWIG interface instead.
if (req->op.search.base == NULL) {
msg->r.SearchRequest.basedn = talloc_strdup(msg, "");
} else {
- msg->r.SearchRequest.basedn = ldb_dn_alloc_linearized(msg, req->op.search.base);
+ msg->r.SearchRequest.basedn = ldb_dn_extended_linearized(msg, req->op.search.base, 0);
}
if (msg->r.SearchRequest.basedn == NULL) {
ldb_set_errstring(ac->module->ldb, "Unable to determine baseDN");
msg->type = LDAP_TAG_AddRequest;
- msg->r.AddRequest.dn = ldb_dn_alloc_linearized(msg, req->op.add.message->dn);
+ msg->r.AddRequest.dn = ldb_dn_extended_linearized(msg, req->op.add.message->dn, 0);
if (msg->r.AddRequest.dn == NULL) {
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
msg->type = LDAP_TAG_ModifyRequest;
- msg->r.ModifyRequest.dn = ldb_dn_alloc_linearized(msg, req->op.mod.message->dn);
+ msg->r.ModifyRequest.dn = ldb_dn_extended_linearized(msg, req->op.mod.message->dn, 0);
if (msg->r.ModifyRequest.dn == NULL) {
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
msg->type = LDAP_TAG_DelRequest;
- msg->r.DelRequest.dn = ldb_dn_alloc_linearized(msg, req->op.del.dn);
+ msg->r.DelRequest.dn = ldb_dn_extended_linearized(msg, req->op.del.dn, 0);
if (msg->r.DelRequest.dn == NULL) {
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
}
msg->type = LDAP_TAG_ModifyDNRequest;
- msg->r.ModifyDNRequest.dn = ldb_dn_alloc_linearized(msg, req->op.rename.olddn);
+ msg->r.ModifyDNRequest.dn = ldb_dn_extended_linearized(msg, req->op.rename.olddn, 0);
if (msg->r.ModifyDNRequest.dn == NULL) {
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
/* ----------------------------------------------------------------------------
* This file was automatically generated by SWIG (http://www.swig.org).
- * Version 1.3.36
+ * Version 1.3.35
*
* This file is not intended to be easily readable and contains a number of
* coding conventions designed to improve portability and efficiency. Do not make
# endif
#endif
-#ifndef SWIG_MSC_UNSUPPRESS_4505
-# if defined(_MSC_VER)
-# pragma warning(disable : 4505) /* unreferenced local function has been removed */
-# endif
-#endif
-
#ifndef SWIGUNUSEDPARM
# ifdef __cplusplus
# define SWIGUNUSEDPARM(p)
#define SWIGTYPE_p_ldb_parse_tree swig_types[11]
#define SWIGTYPE_p_ldb_result swig_types[12]
#define SWIGTYPE_p_ldb_val swig_types[13]
-#define SWIGTYPE_p_long_long swig_types[14]
+#define SWIGTYPE_p_long swig_types[14]
#define SWIGTYPE_p_p_char swig_types[15]
#define SWIGTYPE_p_p_ldb_control swig_types[16]
#define SWIGTYPE_p_p_ldb_result swig_types[17]
#define SWIGTYPE_p_unsigned_char swig_types[20]
#define SWIGTYPE_p_unsigned_int swig_types[21]
#define SWIGTYPE_p_unsigned_long swig_types[22]
-#define SWIGTYPE_p_unsigned_long_long swig_types[23]
-#define SWIGTYPE_p_unsigned_short swig_types[24]
-#define SWIGTYPE_p_void swig_types[25]
-static swig_type_info *swig_types[27];
-static swig_module_info swig_module = {swig_types, 26, 0, 0, 0, 0};
+#define SWIGTYPE_p_unsigned_short swig_types[23]
+#define SWIGTYPE_p_void swig_types[24]
+static swig_type_info *swig_types[26];
+static swig_module_info swig_module = {swig_types, 25, 0, 0, 0, 0};
#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
#define SWIG_name "_ldb"
-#define SWIGVERSION 0x010336
+#define SWIGVERSION 0x010335
#define SWIG_VERSION SWIGVERSION
if (ldif == NULL) {
return Py_None;
} else {
+ talloc_steal(NULL, ldif);
return Py_BuildValue((char *)"(iO)", ldif->changetype,
SWIG_NewPointerObj(ldif->msg, SWIGTYPE_p_ldb_message, 0));
}
struct ldb_context *arg1 = (struct ldb_context *) 0 ;
struct ldb_message_element *arg2 = (struct ldb_message_element *) 0 ;
struct ldb_val *arg3 = (struct ldb_val *) 0 ;
+ PyObject *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
char * kwnames[] = {
(char *) "ldb_ctx",(char *) "el",(char *) "val", NULL
};
- PyObject *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:ldb_val_to_py_object",kwnames,&obj0,&obj1,&obj2)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
char *arg2 = (char *) 0 ;
+ ldb_dn *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char * kwnames[] = {
(char *) "ldb_ctx",(char *) "str", NULL
};
- ldb_dn *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:new_Dn",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
}
arg1 = (ldb_dn *)(argp1);
delete_ldb_dn(arg1);
+
resultobj = SWIG_Py_Void();
return resultobj;
fail:
SWIGINTERN PyObject *_wrap_Dn_validate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
+ bool result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- bool result;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Dn_get_casefold(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
+ char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- char *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Dn___str__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
+ char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- char *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Dn_parent(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
+ ldb_dn *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_dn *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
ldb_dn *arg2 = (ldb_dn *) 0 ;
+ int result;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "other", NULL
};
- int result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Dn___cmp__",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_dn, 0 | 0 );
SWIGINTERN PyObject *_wrap_Dn_is_valid(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
+ bool result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- bool result;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Dn_is_special(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
+ bool result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- bool result;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Dn_is_null(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
+ bool result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- bool result;
if (!args) SWIG_fail;
swig_obj[0] = args;
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
char *arg2 = (char *) 0 ;
+ bool result;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char * kwnames[] = {
(char *) "self",(char *) "name", NULL
};
- bool result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Dn_check_special",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_dn, 0 | 0 );
SWIGINTERN PyObject *_wrap_Dn___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
+ int result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- int result;
if (!args) SWIG_fail;
swig_obj[0] = args;
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
ldb_dn *arg2 = (ldb_dn *) 0 ;
+ bool result;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "child", NULL
};
- bool result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Dn_add_child",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_dn, 0 | 0 );
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
ldb_dn *arg2 = (ldb_dn *) 0 ;
+ bool result;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "base", NULL
};
- bool result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Dn_add_base",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_dn, 0 | 0 );
SWIGINTERN PyObject *_wrap_Dn_canonical_str(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
+ char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- char *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Dn_canonical_ex_str(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
+ char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- char *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Dn___repr__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
+ char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- char *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) 0 ;
ldb_dn *arg2 = (ldb_dn *) 0 ;
+ ldb_dn *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "other", NULL
};
- ldb_dn *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Dn___add__",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_dn, 0 | 0 );
PyObject *resultobj = 0;
ldb_message_element *arg1 = (ldb_message_element *) 0 ;
ldb_message_element *arg2 = (ldb_message_element *) 0 ;
+ int result;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "other", NULL
};
- int result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:MessageElement___cmp__",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_message_element, 0 | 0 );
SWIGINTERN PyObject *_wrap_MessageElement___iter__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_message_element *arg1 = (ldb_message_element *) 0 ;
+ PyObject *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- PyObject *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_MessageElement___set__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_message_element *arg1 = (ldb_message_element *) 0 ;
+ PyObject *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- PyObject *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
PyObject *arg1 = (PyObject *) 0 ;
int arg2 = (int) 0 ;
char *arg3 = (char *) NULL ;
+ ldb_message_element *result = 0 ;
int val2 ;
int ecode2 = 0 ;
int res3 ;
char * kwnames[] = {
(char *) "set_obj",(char *) "flags",(char *) "name", NULL
};
- ldb_message_element *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OO:new_MessageElement",kwnames,&obj0,&obj1,&obj2)) SWIG_fail;
arg1 = obj0;
SWIGINTERN PyObject *_wrap_MessageElement___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_message_element *arg1 = (ldb_message_element *) 0 ;
+ int result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- int result;
if (!args) SWIG_fail;
swig_obj[0] = args;
PyObject *resultobj = 0;
ldb_message_element *arg1 = (ldb_message_element *) 0 ;
int arg2 ;
+ PyObject *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
int val2 ;
char * kwnames[] = {
(char *) "self",(char *) "i", NULL
};
- PyObject *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:MessageElement_get",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_message_element, 0 | 0 );
}
arg1 = (ldb_message_element *)(argp1);
delete_ldb_message_element(arg1);
+
resultobj = SWIG_Py_Void();
return resultobj;
fail:
SWIGINTERN PyObject *_wrap_ldb_msg_list_elements(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb_msg *arg1 = (ldb_msg *) 0 ;
+ PyObject *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
char * kwnames[] = {
(char *) "msg", NULL
};
- PyObject *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:ldb_msg_list_elements",kwnames,&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_message, 0 | 0 );
SWIG_exception(SWIG_ValueError,
"Message can not be None");
if (arg1) (arg1)->dn = arg2;
+
resultobj = SWIG_Py_Void();
return resultobj;
fail:
SWIGINTERN PyObject *_wrap_Message_dn_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_msg *arg1 = (ldb_msg *) 0 ;
+ ldb_dn *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_dn *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_new_Message(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb_dn *arg1 = (ldb_dn *) NULL ;
+ ldb_msg *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
char * kwnames[] = {
(char *) "dn", NULL
};
- ldb_msg *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|O:new_Message",kwnames,&obj0)) SWIG_fail;
if (obj0) {
SWIG_exception(SWIG_ValueError,
"Message can not be None");
delete_ldb_msg(arg1);
+
resultobj = SWIG_Py_Void();
return resultobj;
fail:
PyObject *resultobj = 0;
ldb_msg *arg1 = (ldb_msg *) 0 ;
char *arg2 = (char *) 0 ;
+ ldb_message_element *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char * kwnames[] = {
(char *) "self",(char *) "name", NULL
};
- ldb_message_element *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Message_find_element",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_message, 0 | 0 );
SWIGINTERN PyObject *_wrap_Message___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_msg *arg1 = (ldb_msg *) 0 ;
+ unsigned int result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- unsigned int result;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Message_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_msg *arg1 = (ldb_msg *) 0 ;
+ PyObject *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- PyObject *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Message___iter__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_msg *arg1 = (ldb_msg *) 0 ;
+ PyObject *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- PyObject *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_ldb_ldif_to_pyobject(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb_ldif *arg1 = (ldb_ldif *) 0 ;
+ PyObject *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
char * kwnames[] = {
(char *) "ldif", NULL
};
- PyObject *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:ldb_ldif_to_pyobject",kwnames,&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_ldif, 0 | 0 );
SWIG_exception(SWIG_ValueError,
"ldb context must be non-NULL");
if (arg1) (arg1)->modules = arg2;
+
resultobj = SWIG_Py_Void();
return resultobj;
fail:
SWIGINTERN PyObject *_wrap_Ldb_firstmodule_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
+ struct ldb_module *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- struct ldb_module *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
char *arg2 = (char *) 0 ;
unsigned int arg3 = (unsigned int) 0 ;
char **arg4 = (char **) (char **)NULL ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char * kwnames[] = {
(char *) "self",(char *) "url",(char *) "flags",(char *) "options", NULL
};
- ldb_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO|OO:Ldb_connect",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
SWIG_exception(SWIG_ValueError,
"ldb context must be non-NULL");
delete_ldb(arg1);
+
resultobj = SWIG_Py_Void();
return resultobj;
fail:
char **arg6 = (char **) NULL ;
struct ldb_control **arg7 = (struct ldb_control **) NULL ;
struct ldb_result **arg8 = (struct ldb_result **) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
int val4 ;
char * kwnames[] = {
(char *) "self",(char *) "base",(char *) "scope",(char *) "expression",(char *) "attrs",(char *) "controls", NULL
};
- ldb_error result;
arg2 = NULL;
arg8 = &temp_ldb_result8;
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
ldb_dn *arg2 = (ldb_dn *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "dn", NULL
};
- ldb_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Ldb_delete",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
ldb *arg1 = (ldb *) 0 ;
ldb_dn *arg2 = (ldb_dn *) 0 ;
ldb_dn *arg3 = (ldb_dn *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "olddn",(char *) "newdn", NULL
};
- ldb_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:Ldb_rename",kwnames,&obj0,&obj1,&obj2)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
ldb *arg1 = (ldb *) 0 ;
TALLOC_CTX *arg2 = (TALLOC_CTX *) 0 ;
char **arg3 = (char **) 0 ;
+ struct ldb_control **result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "control_strings", NULL
};
- struct ldb_control **result = 0 ;
arg2 = NULL;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Ldb_parse_control_strings",kwnames,&obj0,&obj1)) SWIG_fail;
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
ldb_msg *arg2 = (ldb_msg *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "add_msg", NULL
};
- ldb_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Ldb_add",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
ldb_msg *arg2 = (ldb_msg *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "message", NULL
};
- ldb_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Ldb_modify",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
SWIGINTERN PyObject *_wrap_Ldb_get_config_basedn(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
+ ldb_dn *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_dn *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Ldb_get_root_basedn(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
+ ldb_dn *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_dn *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Ldb_get_schema_basedn(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
+ ldb_dn *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_dn *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Ldb_get_default_basedn(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
+ ldb_dn *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_dn *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
ldb *arg1 = (ldb *) 0 ;
char *arg2 = (char *) 0 ;
PyObject *arg3 = (PyObject *) 0 ;
+ PyObject *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char * kwnames[] = {
(char *) "self",(char *) "element_name",(char *) "val", NULL
};
- PyObject *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:Ldb_schema_format_value",kwnames,&obj0,&obj1,&obj2)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
SWIGINTERN PyObject *_wrap_Ldb_errstring(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
+ char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- char *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
ldb *arg1 = (ldb *) 0 ;
void (*arg2)(void *,enum ldb_debug_level,char const *,va_list) = (void (*)(void *,enum ldb_debug_level,char const *,va_list)) 0 ;
void *arg3 = (void *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "debug", NULL
};
- ldb_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Ldb_set_debug",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
ldb *arg1 = (ldb *) 0 ;
char *arg2 = (char *) 0 ;
void *arg3 = (void *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char * kwnames[] = {
(char *) "self",(char *) "name",(char *) "value", NULL
};
- ldb_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:Ldb_set_opaque",kwnames,&obj0,&obj1,&obj2)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
char *arg2 = (char *) 0 ;
+ void *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char * kwnames[] = {
(char *) "self",(char *) "name", NULL
};
- void *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Ldb_get_opaque",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
SWIGINTERN PyObject *_wrap_Ldb_transaction_start(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_error result;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Ldb_transaction_commit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_error result;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_Ldb_transaction_cancel(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_error result;
if (!args) SWIG_fail;
swig_obj[0] = args;
char *arg2 = (char *) 0 ;
unsigned int arg3 ;
char *arg4 = (char *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char * kwnames[] = {
(char *) "self",(char *) "attribute",(char *) "flags",(char *) "syntax", NULL
};
- ldb_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOO:Ldb_schema_attribute_add",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
SWIGINTERN PyObject *_wrap_Ldb_setup_wellknown_attributes(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_error result;
if (!args) SWIG_fail;
swig_obj[0] = args;
ldb *arg1 = (ldb *) 0 ;
ldb_dn *arg2 = (ldb_dn *) 0 ;
struct ldb_result **arg3 = (struct ldb_result **) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
struct ldb_result *tmp3 ;
char * kwnames[] = {
(char *) "self",(char *) "dn", NULL
};
- ldb_error result;
arg3 = &tmp3;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Ldb___contains__",kwnames,&obj0,&obj1)) SWIG_fail;
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
char *arg2 = (char *) 0 ;
+ PyObject *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char * kwnames[] = {
(char *) "self",(char *) "s", NULL
};
- PyObject *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Ldb_parse_ldif",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
SWIGINTERN PyObject *_wrap_Ldb___repr__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
+ char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- char *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_valid_attr_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
char *arg1 = (char *) 0 ;
+ int result;
int res1 ;
char *buf1 = 0 ;
int alloc1 = 0 ;
char * kwnames[] = {
(char *) "s", NULL
};
- int result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:valid_attr_name",kwnames,&obj0)) SWIG_fail;
res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
SWIGINTERN PyObject *_wrap_timestring(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
time_t arg1 ;
+ char *result = 0 ;
unsigned long val1 ;
int ecode1 = 0 ;
PyObject * obj0 = 0 ;
char * kwnames[] = {
(char *) "t", NULL
};
- char *result = 0 ;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:timestring",kwnames,&obj0)) SWIG_fail;
ecode1 = SWIG_AsVal_unsigned_SS_long(obj0, &val1);
SWIGINTERN PyObject *_wrap_string_to_time(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
char *arg1 = (char *) 0 ;
+ time_t result;
int res1 ;
char *buf1 = 0 ;
int alloc1 = 0 ;
char * kwnames[] = {
(char *) "s", NULL
};
- time_t result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:string_to_time",kwnames,&obj0)) SWIG_fail;
res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
}
arg2 = (struct ldb_module *)(argp2);
if (arg1) (arg1)->prev = arg2;
+
resultobj = SWIG_Py_Void();
return resultobj;
fail:
SWIGINTERN PyObject *_wrap_ldb_module_prev_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
+ struct ldb_module *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- struct ldb_module *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
}
arg2 = (struct ldb_module *)(argp2);
if (arg1) (arg1)->next = arg2;
+
resultobj = SWIG_Py_Void();
return resultobj;
fail:
SWIGINTERN PyObject *_wrap_ldb_module_next_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
+ struct ldb_module *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- struct ldb_module *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_ldb_module___str__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
+ char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- char *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_ldb_module___repr__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
+ char *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- char *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
struct ldb_parse_tree *arg4 = (struct ldb_parse_tree *) 0 ;
char **arg5 = (char **) 0 ;
struct ldb_result **arg6 = (struct ldb_result **) 0 ;
+ int result;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "base",(char *) "scope",(char *) "tree",(char *) "attrs", NULL
};
- int result;
arg6 = &temp_ldb_result6;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOOO:ldb_module_search",kwnames,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
struct ldb_message *arg2 = (struct ldb_message *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "message", NULL
};
- ldb_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:ldb_module_add",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_module, 0 | 0 );
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
struct ldb_message *arg2 = (struct ldb_message *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "message", NULL
};
- ldb_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:ldb_module_modify",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_module, 0 | 0 );
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
struct ldb_dn *arg2 = (struct ldb_dn *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "dn", NULL
};
- ldb_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:ldb_module_delete",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_module, 0 | 0 );
ldb_module *arg1 = (ldb_module *) 0 ;
struct ldb_dn *arg2 = (struct ldb_dn *) 0 ;
struct ldb_dn *arg3 = (struct ldb_dn *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "olddn",(char *) "newdn", NULL
};
- ldb_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:ldb_module_rename",kwnames,&obj0,&obj1,&obj2)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_module, 0 | 0 );
SWIGINTERN PyObject *_wrap_ldb_module_start_transaction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_error result;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_ldb_module_end_transaction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_error result;
if (!args) SWIG_fail;
swig_obj[0] = args;
SWIGINTERN PyObject *_wrap_ldb_module_del_transaction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
+ ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
- ldb_error result;
if (!args) SWIG_fail;
swig_obj[0] = args;
}
arg1 = (ldb_module *)(argp1);
free((char *) arg1);
+
resultobj = SWIG_Py_Void();
return resultobj;
fail:
SWIGINTERN PyObject *_wrap_register_module(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
struct ldb_module_ops *arg1 = (struct ldb_module_ops *) 0 ;
+ ldb_int_error result;
PyObject * obj0 = 0 ;
char * kwnames[] = {
(char *)"arg1", NULL
};
- ldb_int_error result;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:register_module",kwnames,&obj0)) SWIG_fail;
arg1 = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_f_p_void_enum_ldb_debug_level_p_q_const__char_va_list__void = {"_p_f_p_void_enum_ldb_debug_level_p_q_const__char_va_list__void", "void (*)(void *,enum ldb_debug_level,char const *,va_list)", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_int = {"_p_int", "int *|int_least32_t *|int32_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_context = {"_p_ldb_context", "struct ldb_context *|ldb *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_dn = {"_p_ldb_dn", "struct ldb_dn *|ldb_dn *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_ldif = {"_p_ldb_ldif", "struct ldb_ldif *|ldb_ldif *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_parse_tree = {"_p_ldb_parse_tree", "struct ldb_parse_tree *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_result = {"_p_ldb_result", "struct ldb_result *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_val = {"_p_ldb_val", "struct ldb_val *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_long = {"_p_long", "intptr_t *|int_least64_t *|int_fast32_t *|int_fast64_t *|int64_t *|long *|int_fast16_t *|intmax_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_p_ldb_control = {"_p_p_ldb_control", "struct ldb_control **", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_p_ldb_result = {"_p_p_ldb_result", "struct ldb_result **", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_unsigned_long = {"_p_unsigned_long", "unsigned long *|time_t *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uint_least32_t *|uint32_t *|unsigned int *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_unsigned_long = {"_p_unsigned_long", "uintptr_t *|uint_least64_t *|uint_fast32_t *|uint_fast64_t *|uint64_t *|unsigned long *|time_t *|uint_fast16_t *|uintmax_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_void = {"_p_void", "void *", 0, 0, (void*)0, 0};
&_swigt__p_ldb_parse_tree,
&_swigt__p_ldb_result,
&_swigt__p_ldb_val,
- &_swigt__p_long_long,
+ &_swigt__p_long,
&_swigt__p_p_char,
&_swigt__p_p_ldb_control,
&_swigt__p_p_ldb_result,
&_swigt__p_unsigned_char,
&_swigt__p_unsigned_int,
&_swigt__p_unsigned_long,
- &_swigt__p_unsigned_long_long,
&_swigt__p_unsigned_short,
&_swigt__p_void,
};
static swig_cast_info _swigc__p_ldb_parse_tree[] = { {&_swigt__p_ldb_parse_tree, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_result[] = { {&_swigt__p_ldb_result, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_val[] = { {&_swigt__p_ldb_val, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_long[] = { {&_swigt__p_long, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_p_ldb_control[] = { {&_swigt__p_p_ldb_control, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_p_ldb_result[] = { {&_swigt__p_p_ldb_result, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_unsigned_long[] = { {&_swigt__p_unsigned_long, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_void[] = { {&_swigt__p_void, 0, 0, 0},{0, 0, 0, 0}};
_swigc__p_ldb_parse_tree,
_swigc__p_ldb_result,
_swigc__p_ldb_val,
- _swigc__p_long_long,
+ _swigc__p_long,
_swigc__p_p_char,
_swigc__p_p_ldb_control,
_swigc__p_p_ldb_result,
_swigc__p_unsigned_char,
_swigc__p_unsigned_int,
_swigc__p_unsigned_long,
- _swigc__p_unsigned_long_long,
_swigc__p_unsigned_short,
_swigc__p_void,
};
print "Testing Renames"
- ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
+ attrs = ["objectGUID", "objectSid"]
+ print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
+ res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
+ self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
+
+ #Check rename works with extended/alternate DN forms
+ ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestuser3,cn=users," + self.base_dn)
ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
- self.assertEquals(len(res), 1, "Could not find (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)), perhaps linked attributes are not conistant with subtree renames?")
+ self.assertEquals(len(res), 1, "Could not find (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)), perhaps linked attributes are not consistant with subtree renames?")
print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
try:
self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
self.assertEquals(res[0].dn, res6[0].dn)
-
- ldb.delete(res[0].dn)
+
+ ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306369)
self.assertEquals(int(res[0]["userAccountControl"][0]), 4096)
- ldb.delete(res[0].dn)
+ ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
- attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
+ attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
- res = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
-
- self.assertEquals(res[0].dn, ("CN=ldaptestuser2,CN=Users," + self.base_dn))
- self.assertEquals(res[0]["cn"], "ldaptestuser2")
- self.assertEquals(res[0]["name"], "ldaptestuser2")
- self.assertEquals(res[0]["objectClass"], ["top", "person", "organizationalPerson", "user"])
- self.assertTrue("objectGUID" in res[0])
- self.assertTrue("whenCreated" in res[0])
- self.assertTrue("nTSecurityDescriptor" in res[0])
- self.assertTrue("allowedAttributes" in res[0])
- self.assertTrue("allowedAttributesEffective" in res[0])
- self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
-
- attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
+ res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
+ self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
+
+ self.assertEquals(res_user[0].dn, ("CN=ldaptestuser2,CN=Users," + self.base_dn))
+ self.assertEquals(res_user[0]["cn"], "ldaptestuser2")
+ self.assertEquals(res_user[0]["name"], "ldaptestuser2")
+ self.assertEquals(res_user[0]["objectClass"], ["top", "person", "organizationalPerson", "user"])
+ self.assertTrue("objectSid" in res_user[0])
+ self.assertTrue("objectGUID" in res_user[0])
+ self.assertTrue("whenCreated" in res_user[0])
+ self.assertTrue("nTSecurityDescriptor" in res_user[0])
+ self.assertTrue("allowedAttributes" in res_user[0])
+ self.assertTrue("allowedAttributesEffective" in res_user[0])
+ self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
+
+ attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
self.assertEquals(res[0]["cn"], "ldaptestgroup2")
self.assertEquals(res[0]["name"], "ldaptestgroup2")
self.assertEquals(res[0]["objectClass"], ["top", "group"])
- self.assertTrue("objectGuid" not in res[0])
+ self.assertTrue("objectGUID" in res[0])
+ self.assertTrue("objectSid" in res[0])
self.assertTrue("whenCreated" in res[0])
self.assertTrue("nTSecurityDescriptor" in res[0])
self.assertTrue("allowedAttributes" in res[0])
memberUP.append(m.upper())
self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
+ print "Testing Linked attribute behaviours"
ldb.modify_ldif("""
dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
changetype: modify
member: CN=ldaptestutf8user èùéìòà ,CN=Users,""" + self.base_dn + """
""")
- print "Testing Linked attribute behaviours"
ldb.modify_ldif("""
-dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
+dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
+changetype: modify
+replace: member
+member: CN=ldaptestutf8user èùéìòà ,CN=Users,""" + self.base_dn + """
+""")
+
+ ldb.modify_ldif("""
+dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
changetype: modify
delete: member
""")
dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
changetype: modify
add: member
-member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
+member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
member: CN=ldaptestutf8user èùéìòà ,CN=Users,""" + self.base_dn + """
""")
dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
changetype: modify
add: member
-member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
+member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
member: CN=ldaptestutf8user èùéìòà ,CN=Users,""" + self.base_dn + """
""")
return result;
}
-static bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
- struct asn1_data *data,
- const char **result)
+bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
+ struct asn1_data *data,
+ const char **result)
{
DATA_BLOB string;
if (!asn1_read_OctetString(data, mem_ctx, &string))
}
-static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
- struct ldb_message_element **attributes,
- int *num_attributes)
+void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
+ struct ldb_message_element **attributes,
+ int *num_attributes)
{
asn1_start_tag(data, ASN1_SEQUENCE(0));
while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) {
#include "libcli/ldap/ldap.h"
#include "lib/ldb/include/ldb.h"
#include "libcli/ldap/ldap_proto.h"
+#include "dsdb/samdb/samdb.h"
struct control_handler {
const char *oid;
return true;
}
+static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out)
+{
+ struct dsdb_openldap_dereference_control *control = talloc_get_type(in, struct dsdb_openldap_dereference_control);
+ int i,j;
+ struct asn1_data *data = asn1_init(mem_ctx);
+
+ if (!data) return false;
+
+ if (!control) return false;
+
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+
+ for (i=0; control->dereference && control->dereference[i]; i++) {
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+ if (!asn1_write_OctetString(data, control->dereference[i]->source_attribute, strlen(control->dereference[i]->source_attribute))) {
+ return false;
+ }
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+ for (j=0; control->dereference && control->dereference[i]->dereference_attribute[j]; j++) {
+ if (!asn1_write_OctetString(data, control->dereference[i]->dereference_attribute[j],
+ strlen(control->dereference[i]->dereference_attribute[j]))) {
+ return false;
+ }
+ }
+
+ asn1_pop_tag(data);
+ asn1_pop_tag(data);
+ }
+ asn1_pop_tag(data);
+
+ *out = data_blob_talloc(mem_ctx, data->data, data->length);
+ if (out->data == NULL) {
+ return false;
+ }
+ talloc_free(data);
+ return true;
+}
+
+static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void **out)
+{
+ struct asn1_data *data = asn1_init(mem_ctx);
+ struct dsdb_openldap_dereference_result_control *control;
+ struct dsdb_openldap_dereference_result **r;
+ int i = 0;
+ if (!data) return false;
+
+ control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control);
+ if (!control) return false;
+
+ r = control->attributes = talloc_array(control, struct dsdb_openldap_dereference_result *, 0);
+ if (!r) return false;
+
+ if (!asn1_load(data, in)) {
+ return false;
+ }
+
+ control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control);
+ if (!control) {
+ return false;
+ }
+
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+
+ while (asn1_tag_remaining(data) > 0) {
+ i++;
+ r = talloc_realloc(r, control, struct dsdb_openldap_dereference_result *, i + 1);
+
+ r[i] = talloc(r, struct dsdb_openldap_dereference_result);
+
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+
+ asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute);
+ asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn);
+ ldap_decode_attribs(r[i], data, &r[i]->attributes,
+ &r[i]->num_attributes);
+
+ if (!asn1_end_tag(data)) {
+ return false;
+ }
+ r[i+1] = NULL;
+ }
+
+ if (!asn1_end_tag(data)) {
+ return false;
+ }
+
+ *out = control;
+
+ return true;
+}
+
struct control_handler ldap_known_controls[] = {
{ "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request },
{ "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request },
{ "1.3.6.1.4.1.7165.4.3.2", NULL, NULL },
/* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */
{ "1.3.6.1.4.1.7165.4.4.1", NULL, NULL },
+ { DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference},
{ NULL, NULL, NULL }
};
"ranged_results",
"anr",
"server_sort",
- "extended_dn",
"asq",
+ "extended_dn_store",
+ "extended_dn_in",
"rdn_name",
"objectclass",
"samldb",
tdb_modules_list = [
"subtree_rename",
"subtree_delete",
- "linked_attributes"]
+ "linked_attributes",
+ "extended_dn_out_ldb"]
modules_list2 = ["show_deleted",
- "partition"]
+ "partition"]
domaindn_ldb = "users.ldb"
if ldap_backend is not None:
if ldap_backend_type == "fedora-ds":
backend_modules = ["nsuniqueid", "paged_searches"]
# We can handle linked attributes here, as we don't have directory-side subtree operations
- tdb_modules_list = ["linked_attributes"]
+ tdb_modules_list = ["linked_attributes", "extended_dn_out_dereference"]
elif ldap_backend_type == "openldap":
backend_modules = ["normalise", "entryuuid", "paged_searches"]
# OpenLDAP handles subtree renames, so we don't want to do any of these things
- tdb_modules_list = None
+ tdb_modules_list = ["extended_dn_out_dereference"]
elif ldap_backend is not None:
raise "LDAP Backend specified, but LDAP Backend Type not specified"
elif serverrole == "domain controller":
replace: modifiedCount
modifiedCount: 1
-
-replace: objectCategory
-objectCategory: CN=Domain-DNS,${SCHEMADN}
--
replace: fSMORoleOwner
fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
-
defaultSecurityDescriptor: D:(A;;RPLCLORC;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)
systemFlags: 16
defaultHidingValue: TRUE
-defaultObjectCategory: CN=Builtin-Domain,${SCHEMADN}
+defaultObjectCategory: CN=Samba4-Local-Domain,${SCHEMADN}
dn: CN=Samba4Top,${SCHEMADN}
RPC_NDR_LSA RPC_NDR_EPMAPPER RPC_NDR_DFS RPC_NDR_FRSAPI RPC_NDR_SPOOLSS \
RPC_NDR_SRVSVC RPC_NDR_WKSSVC RPC_NDR_ROT RPC_NDR_DSSETUP \
RPC_NDR_REMACT RPC_NDR_OXIDRESOLVER RPC_NDR_NTSVCS WB_HELPER LIBSAMBA-NET \
- LIBCLI_AUTH POPT_CREDENTIALS TORTURE_LDAP TORTURE_UTIL TORTURE_RAP \
+ LIBCLI_AUTH POPT_CREDENTIALS TORTURE_LDAP TORTURE_LDB TORTURE_UTIL TORTURE_RAP \
dcerpc_server service process_model ntvfs SERVICE_SMB RPC_NDR_BROWSER
torture_rpc_OBJ_FILES = $(addprefix $(torturesrcdir)/rpc/, \
$(eval $(call proto_header_template,$(torturesrcdir)/ldap/proto.h,$(TORTURE_LDAP_OBJ_FILES:.o=.c)))
+#################################
+# Start SUBSYSTEM TORTURE_LDB
+[MODULE::TORTURE_LDB]
+SUBSYSTEM = smbtorture
+INIT_FUNCTION = torture_ldb_init
+PRIVATE_DEPENDENCIES = \
+ LDB_WRAP
+# End SUBSYSTEM TORTURE_LDB
+#################################
+
+TORTURE_LDB_OBJ_FILES = $(addprefix $(torturesrcdir)/ldb/, ldb.o)
+
+$(eval $(call proto_header_template,$(torturesrcdir)/ldb/proto.h,$(TORTURE_LDB_OBJ_FILES:.o=.c)))
+
#################################
# Start SUBSYSTEM TORTURE_NBT
[MODULE::TORTURE_NBT]
--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+
+ Test LDB attribute functions
+
+ Copyright (C) Andrew Bartlet <abartlet@samba.org> 2008
+
+ 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 "includes.h"
+#include "lib/events/events.h"
+#include "lib/ldb/include/ldb.h"
+#include "lib/ldb/include/ldb_errors.h"
+#include "lib/ldb-samba/ldif_handlers.h"
+#include "ldb_wrap.h"
+#include "dsdb/samdb/samdb.h"
+#include "param/param.h"
+#include "torture/smbtorture.h"
+#include "torture/ldb/proto.h"
+
+static const char *sid = "S-1-5-21-4177067393-1453636373-93818737";
+static const char *hex_sid = "01040000000000051500000081FDF8F815BBA456718F9705";
+static const char *guid = "975ac5fa-35d9-431d-b86a-845bcd34fff9";
+static const char *guid2 = "{975ac5fa-35d9-431d-b86a-845bcd34fff9}";
+static const char *hex_guid = "FAC55A97D9351D43B86A845BCD34FFF9";
+
+static bool torture_ldb_attrs(struct torture_context *torture)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(torture);
+ struct ldb_context *ldb;
+ const struct ldb_schema_attribute *attr;
+ struct ldb_val string_sid_blob, binary_sid_blob;
+ struct ldb_val string_guid_blob, string_guid_blob2, binary_guid_blob;
+
+ DATA_BLOB sid_blob = strhex_to_data_blob(mem_ctx, hex_sid);
+ DATA_BLOB guid_blob = strhex_to_data_blob(mem_ctx, hex_guid);
+
+ torture_assert(torture,
+ ldb = ldb_init(mem_ctx, torture->ev),
+ "Failed to init ldb");
+
+ torture_assert_int_equal(torture,
+ ldb_register_samba_handlers(ldb), 0,
+ "Failed to register Samba handlers");
+
+ ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
+
+ /* Test SID behaviour */
+ torture_assert(torture, attr = ldb_schema_attribute_by_name(ldb, "objectSid"),
+ "Failed to get objectSid schema attribute");
+
+ string_sid_blob = data_blob_string_const(sid);
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_read_fn(ldb, mem_ctx,
+ &string_sid_blob, &binary_sid_blob), 0,
+ "Failed to parse string SID");
+
+ torture_assert_data_blob_equal(torture, binary_sid_blob, sid_blob,
+ "Read SID into blob form failed");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_read_fn(ldb, mem_ctx,
+ &sid_blob, &binary_sid_blob), -1,
+ "Should have failed to parse binary SID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_write_fn(ldb, mem_ctx, &binary_sid_blob, &string_sid_blob), 0,
+ "Failed to parse binary SID");
+
+ torture_assert_data_blob_equal(torture,
+ string_sid_blob, data_blob_string_const(sid),
+ "Write SID into string form failed");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &binary_sid_blob, &string_sid_blob), 0,
+ "Failed to compare binary and string SID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &string_sid_blob, &binary_sid_blob), 0,
+ "Failed to compare string and binary binary SID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &string_sid_blob, &string_sid_blob), 0,
+ "Failed to compare string and string SID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &binary_sid_blob, &binary_sid_blob), 0,
+ "Failed to compare binary and binary SID");
+
+ torture_assert(torture, attr->syntax->comparison_fn(ldb, mem_ctx, &guid_blob, &binary_sid_blob) != 0,
+ "Failed to distinguish binary GUID and binary SID");
+
+
+ /* Test GUID behaviour */
+ torture_assert(torture, attr = ldb_schema_attribute_by_name(ldb, "objectGUID"),
+ "Failed to get objectGUID schema attribute");
+
+ string_guid_blob = data_blob_string_const(guid);
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_read_fn(ldb, mem_ctx,
+ &string_guid_blob, &binary_guid_blob), 0,
+ "Failed to parse string GUID");
+
+ torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
+ "Read GUID into blob form failed");
+
+ string_guid_blob2 = data_blob_string_const(guid2);
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_read_fn(ldb, mem_ctx,
+ &string_guid_blob2, &binary_guid_blob), 0,
+ "Failed to parse string GUID");
+
+ torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
+ "Read GUID into blob form failed");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_read_fn(ldb, mem_ctx,
+ &guid_blob, &binary_guid_blob), 0,
+ "Failed to parse binary GUID");
+
+ torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
+ "Read GUID into blob form failed");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_write_fn(ldb, mem_ctx, &binary_guid_blob, &string_guid_blob), 0,
+ "Failed to print binary GUID as string");
+
+ torture_assert_data_blob_equal(torture, string_sid_blob, data_blob_string_const(sid),
+ "Write SID into string form failed");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &binary_guid_blob, &string_guid_blob), 0,
+ "Failed to compare binary and string GUID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &string_guid_blob, &binary_guid_blob), 0,
+ "Failed to compare string and binary binary GUID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &string_guid_blob, &string_guid_blob), 0,
+ "Failed to compare string and string GUID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &binary_guid_blob, &binary_guid_blob), 0,
+ "Failed to compare binary and binary GUID");
+
+
+
+ talloc_free(mem_ctx);
+ return true;
+}
+
+static bool torture_ldb_dn_attrs(struct torture_context *torture)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(torture);
+ struct ldb_context *ldb;
+ const struct ldb_dn_extended_syntax *attr;
+ struct ldb_val string_sid_blob, binary_sid_blob;
+ struct ldb_val string_guid_blob, binary_guid_blob;
+ struct ldb_val hex_sid_blob, hex_guid_blob;
+
+ DATA_BLOB sid_blob = strhex_to_data_blob(mem_ctx, hex_sid);
+ DATA_BLOB guid_blob = strhex_to_data_blob(mem_ctx, hex_guid);
+
+ torture_assert(torture,
+ ldb = ldb_init(mem_ctx, torture->ev),
+ "Failed to init ldb");
+
+ torture_assert_int_equal(torture,
+ ldb_register_samba_handlers(ldb), 0,
+ "Failed to register Samba handlers");
+
+ ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
+
+ /* Test SID behaviour */
+ torture_assert(torture, attr = ldb_dn_extended_syntax_by_name(ldb, "SID"),
+ "Failed to get SID DN syntax");
+
+ string_sid_blob = data_blob_string_const(sid);
+
+ torture_assert_int_equal(torture,
+ attr->read_fn(ldb, mem_ctx,
+ &string_sid_blob, &binary_sid_blob), 0,
+ "Failed to parse string SID");
+
+ torture_assert_data_blob_equal(torture, binary_sid_blob, sid_blob,
+ "Read SID into blob form failed");
+
+ hex_sid_blob = data_blob_string_const(hex_sid);
+
+ torture_assert_int_equal(torture,
+ attr->read_fn(ldb, mem_ctx,
+ &hex_sid_blob, &binary_sid_blob), 0,
+ "Failed to parse HEX SID");
+
+ torture_assert_data_blob_equal(torture, binary_sid_blob, sid_blob,
+ "Read SID into blob form failed");
+
+ torture_assert_int_equal(torture,
+ attr->read_fn(ldb, mem_ctx,
+ &sid_blob, &binary_sid_blob), -1,
+ "Should have failed to parse binary SID");
+
+ torture_assert_int_equal(torture,
+ attr->write_hex_fn(ldb, mem_ctx, &sid_blob, &hex_sid_blob), 0,
+ "Failed to parse binary SID");
+
+ torture_assert_data_blob_equal(torture,
+ hex_sid_blob, data_blob_string_const(hex_sid),
+ "Write SID into HEX string form failed");
+
+ torture_assert_int_equal(torture,
+ attr->write_clear_fn(ldb, mem_ctx, &sid_blob, &string_sid_blob), 0,
+ "Failed to parse binary SID");
+
+ torture_assert_data_blob_equal(torture,
+ string_sid_blob, data_blob_string_const(sid),
+ "Write SID into clear string form failed");
+
+
+ /* Test GUID behaviour */
+ torture_assert(torture, attr = ldb_dn_extended_syntax_by_name(ldb, "GUID"),
+ "Failed to get GUID DN syntax");
+
+ string_guid_blob = data_blob_string_const(guid);
+
+ torture_assert_int_equal(torture,
+ attr->read_fn(ldb, mem_ctx,
+ &string_guid_blob, &binary_guid_blob), 0,
+ "Failed to parse string GUID");
+
+ torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
+ "Read GUID into blob form failed");
+
+ hex_guid_blob = data_blob_string_const(hex_guid);
+
+ torture_assert_int_equal(torture,
+ attr->read_fn(ldb, mem_ctx,
+ &hex_guid_blob, &binary_guid_blob), 0,
+ "Failed to parse HEX GUID");
+
+ torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
+ "Read GUID into blob form failed");
+
+ torture_assert_int_equal(torture,
+ attr->read_fn(ldb, mem_ctx,
+ &guid_blob, &binary_guid_blob), -1,
+ "Should have failed to parse binary GUID");
+
+ torture_assert_int_equal(torture,
+ attr->write_hex_fn(ldb, mem_ctx, &guid_blob, &hex_guid_blob), 0,
+ "Failed to parse binary GUID");
+
+ torture_assert_data_blob_equal(torture,
+ hex_guid_blob, data_blob_string_const(hex_guid),
+ "Write GUID into HEX string form failed");
+
+ torture_assert_int_equal(torture,
+ attr->write_clear_fn(ldb, mem_ctx, &guid_blob, &string_guid_blob), 0,
+ "Failed to parse binary GUID");
+
+ torture_assert_data_blob_equal(torture,
+ string_guid_blob, data_blob_string_const(guid),
+ "Write GUID into clear string form failed");
+
+
+
+ talloc_free(mem_ctx);
+ return true;
+}
+
+static bool torture_ldb_dn_extended(struct torture_context *torture)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(torture);
+ struct ldb_context *ldb;
+ struct ldb_dn *dn, *dn2;
+ struct ldb_val string_sid_blob = data_blob_string_const(sid);
+ struct ldb_val string_guid_blob = data_blob_string_const(guid);
+
+ DATA_BLOB sid_blob = strhex_to_data_blob(mem_ctx, hex_sid);
+ DATA_BLOB guid_blob = strhex_to_data_blob(mem_ctx, hex_guid);
+
+ const char *dn_str = "cn=admin,cn=users,dc=samba,dc=org";
+
+ torture_assert(torture,
+ ldb = ldb_init(mem_ctx, torture->ev),
+ "Failed to init ldb");
+
+ torture_assert_int_equal(torture,
+ ldb_register_samba_handlers(ldb), 0,
+ "Failed to register Samba handlers");
+
+ ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
+
+ /* Check behaviour of a normal DN */
+ torture_assert(torture,
+ dn = ldb_dn_new(mem_ctx, ldb, dn_str),
+ "Failed to create a 'normal' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate 'normal' DN");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == false,
+ "Should not find plain DN to be 'extended'");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
+ "Should not find an SID on plain DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
+ "Should not find an GUID on plain DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "WKGUID") == NULL,
+ "Should not find an WKGUID on plain DN");
+
+ /* Now make an extended DN */
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;<SID=%s>;%s",
+ guid, sid, dn_str),
+ "Failed to create an 'extended' DN");
+
+ torture_assert(torture,
+ dn2 = ldb_dn_copy(mem_ctx, dn),
+ "Failed to copy the 'extended' DN");
+ talloc_free(dn);
+ dn = dn2;
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate 'extended' DN");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == true,
+ "Should find extended DN to be 'extended'");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL,
+ "Should find an SID on extended DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL,
+ "Should find an GUID on extended DN");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
+ "Extended DN SID incorect");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
+ "Extended DN GUID incorect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), dn_str,
+ "linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_casefold(dn), strupper_talloc(mem_ctx, dn_str),
+ "casefolded DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_component_name(dn, 0), "cn",
+ "componet zero incorrect");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_component_val(dn, 0), data_blob_string_const("admin"),
+ "componet zero incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 1),
+ talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
+ guid, sid, dn_str),
+ "Clear extended linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 0),
+ talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
+ hex_guid, hex_sid, dn_str),
+ "HEX extended linearized DN incorrect");
+
+ torture_assert(torture, ldb_dn_remove_child_components(dn, 1) == true,
+ "Failed to remove DN child");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == false,
+ "Extended DN flag should be cleared after child element removal");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
+ "Should not find an SID on DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
+ "Should not find an GUID on DN");
+
+
+ /* TODO: test setting these in the other order, and ensure it still comes out 'GUID first' */
+ torture_assert_int_equal(torture, ldb_dn_set_extended_component(dn, "GUID", &guid_blob), 0,
+ "Failed to set a GUID on DN");
+
+ torture_assert_int_equal(torture, ldb_dn_set_extended_component(dn, "SID", &sid_blob), 0,
+ "Failed to set a SID on DN");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
+ "Extended DN SID incorect");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
+ "Extended DN GUID incorect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "cn=users,dc=samba,dc=org",
+ "linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 1),
+ talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
+ guid, sid, "cn=users,dc=samba,dc=org"),
+ "Clear extended linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 0),
+ talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
+ hex_guid, hex_sid, "cn=users,dc=samba,dc=org"),
+ "HEX extended linearized DN incorrect");
+
+ /* Now check a 'just GUID' DN (clear format) */
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>",
+ guid),
+ "Failed to create an 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate 'extended' DN");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == true,
+ "Should find extended DN to be 'extended'");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
+ "Should not find an SID on this DN");
+
+ torture_assert_int_equal(torture, ldb_dn_get_comp_num(dn), 0,
+ "Should not find an 'normal' componet on this DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL,
+ "Should find an GUID on this DN");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
+ "Extended DN GUID incorect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
+ "linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 1),
+ talloc_asprintf(mem_ctx, "<GUID=%s>",
+ guid),
+ "Clear extended linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 0),
+ talloc_asprintf(mem_ctx, "<GUID=%s>",
+ hex_guid),
+ "HEX extended linearized DN incorrect");
+
+ /* Now check a 'just GUID' DN (HEX format) */
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>",
+ hex_guid),
+ "Failed to create an 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate 'extended' DN");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == true,
+ "Should find extended DN to be 'extended'");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
+ "Should not find an SID on this DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL,
+ "Should find an GUID on this DN");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
+ "Extended DN GUID incorect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
+ "linearized DN incorrect");
+
+ /* Now check a 'just SID' DN (clear format) */
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>",
+ sid),
+ "Failed to create an 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate 'extended' DN");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == true,
+ "Should find extended DN to be 'extended'");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
+ "Should not find an SID on this DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL,
+ "Should find an SID on this DN");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
+ "Extended DN SID incorect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
+ "linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 1),
+ talloc_asprintf(mem_ctx, "<SID=%s>",
+ sid),
+ "Clear extended linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 0),
+ talloc_asprintf(mem_ctx, "<SID=%s>",
+ hex_sid),
+ "HEX extended linearized DN incorrect");
+
+ /* Now check a 'just SID' DN (HEX format) */
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>",
+ hex_sid),
+ "Failed to create an 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate 'extended' DN");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == true,
+ "Should find extended DN to be 'extended'");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
+ "Should not find an SID on this DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL,
+ "Should find an SID on this DN");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
+ "Extended DN SID incorect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
+ "linearized DN incorrect");
+
+ talloc_free(mem_ctx);
+ return true;
+}
+
+
+static bool torture_ldb_dn(struct torture_context *torture)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(torture);
+ struct ldb_context *ldb;
+ struct ldb_dn *dn;
+ struct ldb_dn *child_dn;
+ struct ldb_dn *typo_dn;
+
+ torture_assert(torture,
+ ldb = ldb_init(mem_ctx, torture->ev),
+ "Failed to init ldb");
+
+ torture_assert_int_equal(torture,
+ ldb_register_samba_handlers(ldb), 0,
+ "Failed to register Samba handlers");
+
+ ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
+
+ /* Check behaviour of a normal DN */
+ torture_assert(torture,
+ dn = ldb_dn_new(mem_ctx, ldb, NULL),
+ "Failed to create a NULL DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate NULL DN");
+
+ torture_assert(torture,
+ ldb_dn_add_base_fmt(dn, "dc=org"),
+ "Failed to add base DN");
+
+ torture_assert(torture,
+ ldb_dn_add_child_fmt(dn, "dc=samba"),
+ "Failed to add base DN");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "dc=samba,dc=org",
+ "linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 0), "dc=samba,dc=org",
+ "extended linearized DN incorrect");
+
+ /* Check child DN comparisons */
+ torture_assert(torture,
+ child_dn = ldb_dn_new(mem_ctx, ldb, "CN=users,DC=SAMBA,DC=org"),
+ "Failed to create child DN");
+
+ torture_assert(torture,
+ ldb_dn_compare(dn, child_dn) != 0,
+ "Comparison on dc=samba,dc=org and CN=users,DC=SAMBA,DC=org should != 0");
+
+ torture_assert(torture,
+ ldb_dn_compare_base(child_dn, dn) != 0,
+ "Base Comparison of CN=users,DC=SAMBA,DC=org and dc=samba,dc=org should != 0");
+
+ torture_assert(torture,
+ ldb_dn_compare_base(dn, child_dn) == 0,
+ "Base Comparison on dc=samba,dc=org and CN=users,DC=SAMBA,DC=org should == 0");
+
+ /* Check comparisons with a truncated DN */
+ torture_assert(torture,
+ typo_dn = ldb_dn_new(mem_ctx, ldb, "c=samba,dc=org"),
+ "Failed to create 'typo' DN");
+
+ torture_assert(torture,
+ ldb_dn_compare(dn, typo_dn) != 0,
+ "Comparison on dc=samba,dc=org and c=samba,dc=org should != 0");
+
+ torture_assert(torture,
+ ldb_dn_compare_base(typo_dn, dn) != 0,
+ "Base Comparison of c=samba,dc=org and dc=samba,dc=org should != 0");
+
+ torture_assert(torture,
+ ldb_dn_compare_base(dn, typo_dn) != 0,
+ "Base Comparison on dc=samba,dc=org and c=samba,dc=org should != 0");
+
+ talloc_free(mem_ctx);
+ return true;
+}
+
+static bool torture_ldb_dn_invalid_extended(struct torture_context *torture)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(torture);
+ struct ldb_context *ldb;
+ struct ldb_dn *dn;
+
+ const char *dn_str = "cn=admin,cn=users,dc=samba,dc=org";
+
+ torture_assert(torture,
+ ldb = ldb_init(mem_ctx, torture->ev),
+ "Failed to init ldb");
+
+ torture_assert_int_equal(torture,
+ ldb_register_samba_handlers(ldb), 0,
+ "Failed to register Samba handlers");
+
+ ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
+
+ /* Check behaviour of a normal DN */
+ torture_assert(torture,
+ dn = ldb_dn_new(mem_ctx, ldb, "samba,dc=org"),
+ "Failed to create a 'normal' invalid DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'normal' invalid DN");
+
+ /* Now make an extended DN */
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<PID=%s>;%s",
+ sid, dn_str),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>%s",
+ sid, dn_str),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;",
+ sid),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;",
+ hex_sid),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>;",
+ hex_guid),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>;",
+ guid),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=>"),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ return true;
+}
+
+NTSTATUS torture_ldb_init(void)
+{
+ struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "LDB");
+ torture_suite_add_simple_test(suite, "ATTRS", torture_ldb_attrs);
+ torture_suite_add_simple_test(suite, "DN-ATTRS", torture_ldb_dn_attrs);
+ torture_suite_add_simple_test(suite, "DN-EXTENDED", torture_ldb_dn_extended);
+ torture_suite_add_simple_test(suite, "DN-INVALID-EXTENDED", torture_ldb_dn_invalid_extended);
+ torture_suite_add_simple_test(suite, "DN", torture_ldb_dn);
+
+ suite->description = talloc_strdup(suite, "LDB (samba-specific behaviour) tests");
+
+ torture_register_suite(suite);
+
+ return NT_STATUS_OK;
+}
{
extern NTSTATUS torture_base_init(void);
extern NTSTATUS torture_ldap_init(void);
+ extern NTSTATUS torture_ldb_init(void);
extern NTSTATUS torture_local_init(void);
extern NTSTATUS torture_nbt_init(void);
extern NTSTATUS torture_nbench_init(void);
fi
echo "Getting HEX GUID/SID of $BASEDN"
-HEXDN=`bin/ldbsearch $CONFIGURATION $options -b "$BASEDN" -H $p://$SERVER -s base "(objectClass=*)" --controls=extended_dn:1:0 | grep 'dn: ' | cut -d ' ' -f2-`
+HEXDN=`bin/ldbsearch $CONFIGURATION $options -b "$BASEDN" -H $p://$SERVER -s base "(objectClass=*)" --controls=extended_dn:1:0 distinguishedName | grep 'distinguishedName: ' | cut -d ' ' -f2-`
HEXGUID=`echo "$HEXDN" | cut -d ';' -f1`
-HEXSID=`echo "$HEXDN" | cut -d ';' -f2`
echo "HEXGUID[$HEXGUID]"
-echo "HEXSID[$HEXSID]"
echo "Getting STR GUID/SID of $BASEDN"
-STRDN=`bin/ldbsearch $CONFIGURATION $options -b "$BASEDN" -H $p://$SERVER -s base "(objectClass=*)" --controls=extended_dn:1:1 | grep 'dn: ' | cut -d ' ' -f2-`
+STRDN=`bin/ldbsearch $CONFIGURATION $options -b "$BASEDN" -H $p://$SERVER -s base "(objectClass=*)" --controls=extended_dn:1:1 distinguishedName | grep 'distinguishedName: ' | cut -d ' ' -f2-`
echo "STRDN: $STRDN"
STRGUID=`echo "$STRDN" | cut -d ';' -f1`
-STRSID=`echo "$STRDN" | cut -d ';' -f2`
echo "STRGUID[$STRGUID]"
+
+echo "Getting STR GUID/SID of $BASEDN"
+STRDN=`bin/ldbsearch $CONFIGURATION $options -b "$BASEDN" -H $p://$SERVER -s base "(objectClass=*)" --controls=extended_dn:1:1 | grep 'dn: ' | cut -d ' ' -f2-`
+echo "STRDN: $STRDN"
+STRSID=`echo "$STRDN" | cut -d ';' -f2`
echo "STRSID[$STRSID]"
-SPECIALDNS="$HEXGUID $HEXSID $STRGUID $STRSID"
+SPECIALDNS="$HEXGUID $STRGUID $STRSID"
for SPDN in $SPECIALDNS; do
echo "Search for $SPDN"
nentries=`bin/ldbsearch $options $CONFIGURATION -H $p://$SERVER -s base -b "$SPDN" '(objectClass=*)' | grep "dn: $BASEDN" | wc -l`