summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb/ldb_modules
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2008-01-22 16:39:56 +0100
committerJelmer Vernooij <jelmer@samba.org>2008-01-22 16:39:56 +0100
commit4075a2ba982ea56ff925e0a33839f0760fd71911 (patch)
tree87d87734257f814b7960a843e54455c447f34a9e /source4/dsdb/samdb/ldb_modules
parent24da29746998de1001d18871dcbe8d37643667d5 (diff)
parent35c68316442808a135aafa864d19592108a4d879 (diff)
downloadsamba-4075a2ba982ea56ff925e0a33839f0760fd71911.tar.gz
samba-4075a2ba982ea56ff925e0a33839f0760fd71911.tar.bz2
samba-4075a2ba982ea56ff925e0a33839f0760fd71911.zip
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-python
(This used to be commit 2f57e25f8f692889d9e057e13256f8a24c5ec10c)
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules')
-rw-r--r--source4/dsdb/samdb/ldb_modules/config.mk26
-rw-r--r--source4/dsdb/samdb/ldb_modules/instancetype.c128
-rw-r--r--source4/dsdb/samdb/ldb_modules/linked_attributes.c92
-rw-r--r--source4/dsdb/samdb/ldb_modules/normalise.c166
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectclass.c4
-rw-r--r--source4/dsdb/samdb/ldb_modules/partition.c54
-rw-r--r--source4/dsdb/samdb/ldb_modules/samba3sam.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/simple_ldap_map.c23
8 files changed, 451 insertions, 44 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk
index 95bb7de06c..dc407fbd8a 100644
--- a/source4/dsdb/samdb/ldb_modules/config.mk
+++ b/source4/dsdb/samdb/ldb_modules/config.mk
@@ -320,3 +320,29 @@ OBJ_FILES = \
# End MODULE ldb_anr
################################################
+################################################
+# Start MODULE ldb_normalise
+[MODULE::ldb_normalise]
+INIT_FUNCTION = ldb_normalise_init
+CFLAGS = -Ilib/ldb/include
+OUTPUT_TYPE = SHARED_LIBRARY
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBSAMBA-UTIL SAMDB
+SUBSYSTEM = LIBLDB
+OBJ_FILES = \
+ normalise.o
+# End MODULE ldb_normalise
+################################################
+
+################################################
+# Start MODULE ldb_instancetype
+[MODULE::ldb_instancetype]
+INIT_FUNCTION = ldb_instancetype_init
+CFLAGS = -Ilib/ldb/include
+OUTPUT_TYPE = SHARED_LIBRARY
+PRIVATE_DEPENDENCIES = LIBTALLOC
+SUBSYSTEM = LIBLDB
+OBJ_FILES = \
+ instancetype.o
+# End MODULE ldb_instancetype
+################################################
+
diff --git a/source4/dsdb/samdb/ldb_modules/instancetype.c b/source4/dsdb/samdb/ldb_modules/instancetype.c
new file mode 100644
index 0000000000..064c28ec65
--- /dev/null
+++ b/source4/dsdb/samdb/ldb_modules/instancetype.c
@@ -0,0 +1,128 @@
+/*
+ ldb database library
+
+ Copyright (C) Simo Sorce 2004-2006
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
+ Copyright (C) Andrew Tridgell 2005
+ Copyright (C) Stefan Metzmacher <metze@samba.org> 2007
+
+ ** 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 instancetype module
+ *
+ * Description: add an instanceType onto every new record
+ *
+ * Author: Andrew Bartlett
+ */
+
+#include "includes.h"
+#include "ldb/include/ldb_includes.h"
+#include "librpc/gen_ndr/ndr_misc.h"
+#include "param/param.h"
+#include "dsdb/samdb/samdb.h"
+#include "dsdb/common/flags.h"
+
+/* add_record: add instancetype attribute */
+static int instancetype_add(struct ldb_module *module, struct ldb_request *req)
+{
+ struct ldb_request *down_req;
+ struct ldb_message *msg;
+ uint32_t instance_type;
+ int ret;
+ const struct ldb_control *partition_ctrl;
+ const struct dsdb_control_current_partition *partition;
+
+
+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "instancetype_add_record\n");
+
+ /* do not manipulate our control entries */
+ if (ldb_dn_is_special(req->op.add.message->dn)) {
+ return ldb_next_request(module, req);
+ }
+
+ partition_ctrl = ldb_request_get_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID);
+ if (!partition_ctrl) {
+ ldb_debug_set(module->ldb, LDB_DEBUG_FATAL,
+ "instancetype_add: no current partition control found");
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+
+ partition = talloc_get_type(partition_ctrl->data,
+ struct dsdb_control_current_partition);
+ SMB_ASSERT(partition && partition->version == DSDB_CONTROL_CURRENT_PARTITION_VERSION);
+
+ down_req = talloc(req, struct ldb_request);
+ if (down_req == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ *down_req = *req;
+
+ /* we have to copy the message as the caller might have it as a const */
+ down_req->op.add.message = msg = ldb_msg_copy_shallow(down_req, req->op.add.message);
+ if (msg == NULL) {
+ talloc_free(down_req);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /*
+ * TODO: calculate correct instance type
+ */
+ instance_type = INSTANCE_TYPE_WRITE;
+ if (ldb_dn_compare(partition->dn, msg->dn) == 0) {
+ instance_type |= INSTANCE_TYPE_IS_NC_HEAD;
+ if (ldb_dn_compare(msg->dn, samdb_base_dn(module->ldb)) != 0) {
+ instance_type |= INSTANCE_TYPE_NC_ABOVE;
+ }
+ }
+
+ ret = ldb_msg_add_fmt(msg, "instanceType", "%u", instance_type);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(down_req);
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ldb_set_timeout_from_prev_req(module->ldb, req, down_req);
+
+ /* go on with the call chain */
+ ret = ldb_next_request(module, down_req);
+
+ /* do not free down_req as the call results may be linked to it,
+ * it will be freed when the upper level request get freed */
+ if (ret == LDB_SUCCESS) {
+ req->handle = down_req->handle;
+ }
+
+ return ret;
+}
+
+static const struct ldb_module_ops instancetype_ops = {
+ .name = "instancetype",
+ .add = instancetype_add,
+};
+
+
+int ldb_instancetype_init(void)
+{
+ return ldb_register_module(&instancetype_ops);
+}
diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
index 803d24e34e..b3fdffe566 100644
--- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c
+++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
@@ -279,6 +279,27 @@ static int linked_attributes_add(struct ldb_module *module, struct ldb_request *
return setup_modifies(module->ldb, ac, ac, req->op.add.message, NULL, req->op.add.message->dn);
}
+struct merge {
+ struct ldb_dn *dn;
+ bool add;
+ bool ignore;
+};
+
+static int merge_cmp(struct merge *merge1, struct merge *merge2) {
+ int ret;
+ ret = ldb_dn_compare(merge1->dn, merge2->dn);
+ if (ret == 0) {
+ if (merge1->add == merge2->add) {
+ return 0;
+ }
+ if (merge1->add == true) {
+ return 1;
+ }
+ return -1;
+ }
+ return ret;
+}
+
static int linked_attributes_mod_replace_search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares)
{
struct replace_context *ac2 = talloc_get_type(context, struct replace_context);
@@ -296,16 +317,63 @@ static int linked_attributes_mod_replace_search_callback(struct ldb_context *ldb
/* See if this element already exists */
if (search_el) {
- int ret;
+
+ struct merge *merged_list = NULL;
+
+ int ret, size = 0, i;
struct ldb_message *msg = ldb_msg_new(ac);
if (!msg) {
ldb_oom(ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- /* Lazy option: Delete and add the elements on all members */
- msg->num_elements = 1;
- msg->elements = search_el;
+ /* Add all the existing elements, marking as 'proposed for delete' by setting .add = false */
+ for (i=0; i < search_el->num_values; i++) {
+ merged_list = talloc_realloc(ares, merged_list, struct merge, size + 1);
+ merged_list[size].dn = ldb_dn_new(merged_list, ldb, (char *)search_el->values[i].data);
+ merged_list[size].add = false;
+ merged_list[size].ignore = false;
+ size++;
+ }
+
+ /* Add all the new replacement elements, marking as 'proposed for add' by setting .add = true */
+ for (i=0; i < ac2->el->num_values; i++) {
+ merged_list = talloc_realloc(ares, merged_list, struct merge, size + 1);
+ merged_list[size].dn = ldb_dn_new(merged_list, ldb, (char *)ac2->el->values[i].data);
+ merged_list[size].add = true;
+ merged_list[size].ignore = false;
+ size++;
+ }
+
+ /* Sort the list, so we can pick out an add and delete for the same DN, and eliminate them */
+ qsort(merged_list, size,
+ sizeof(*merged_list),
+ (comparison_fn_t)merge_cmp);
+
+ /* Now things are sorted, it is trivial to mark pairs of DNs as 'ignore' */
+ for (i=0; i + 1 < size; i++) {
+ if (ldb_dn_compare(merged_list[i].dn,
+ merged_list[i+1].dn) == 0
+ /* Fortunetly the sort also sorts 'add == false' first */
+ && merged_list[i].add == false
+ && merged_list[i+1].add == true) {
+
+ /* Mark as ignore, so we include neither in the actual operations */
+ merged_list[i].ignore = true;
+ merged_list[i+1].ignore = true;
+ }
+ }
+
+ /* Arrange to delete anything the search found that we don't re-add */
+ for (i=0; i < size; i++) {
+ if (merged_list[i].ignore == false
+ && merged_list[i].add == false) {
+ ldb_msg_add_steal_string(msg, search_el->name,
+ ldb_dn_get_linearized(merged_list[i].dn));
+ }
+ }
+
+ /* The DN to set on the linked attributes is the original DN of the modify message */
msg->dn = ac->orig_req->op.mod.message->dn;
ret = setup_modifies(ac->module->ldb, ac2, ac, msg, ares->message->dn, NULL);
@@ -313,13 +381,21 @@ static int linked_attributes_mod_replace_search_callback(struct ldb_context *ldb
return ret;
}
- msg->elements = ac2->el;
+ /* Now add links for all the actually new elements */
+ for (i=0; i < size; i++) {
+ if (merged_list[i].ignore == false && merged_list[i].add == true) {
+ ldb_msg_add_steal_string(msg, search_el->name,
+ ldb_dn_get_linearized(merged_list[i].dn));
+ }
+ }
ret = setup_modifies(ac->module->ldb, ac2, ac, msg, NULL, ares->message->dn);
if (ret != LDB_SUCCESS) {
return ret;
}
+ talloc_free(merged_list);
+
} else {
/* Looks like it doesn't exist, process like an 'add' */
struct ldb_message *msg = ldb_msg_new(ac);
@@ -411,6 +487,7 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
return LDB_ERR_OBJECT_CLASS_VIOLATION;
}
+ /* Replace with new set of values */
if (((el->flags & LDB_FLAG_MOD_MASK) == LDB_FLAG_MOD_REPLACE)
&& el->num_values > 0) {
struct replace_context *ac2 = talloc(ac, struct replace_context);
@@ -461,6 +538,8 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
}
continue;
+
+ /* Delete all values case */
} else if (((el->flags & LDB_FLAG_MOD_MASK) & (LDB_FLAG_MOD_DELETE|LDB_FLAG_MOD_REPLACE))
&& el->num_values == 0) {
const char **attrs = talloc_array(ac, const char *, 2);
@@ -508,7 +587,8 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
continue;
}
- /* Prepare the modify (mod element) on the targets */
+
+ /* Prepare the modify (mod element) on the targets, for a normal modify request */
/* For each value being moded, we need to setup the modify */
for (j=0; j < el->num_values; j++) {
diff --git a/source4/dsdb/samdb/ldb_modules/normalise.c b/source4/dsdb/samdb/ldb_modules/normalise.c
new file mode 100644
index 0000000000..efc9bb29e8
--- /dev/null
+++ b/source4/dsdb/samdb/ldb_modules/normalise.c
@@ -0,0 +1,166 @@
+/*
+ ldb database library
+
+ Copyright (C) Amdrew 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 normalisation module
+ *
+ * Description: module to ensure all DNs and attribute names are normalised
+ *
+ * Author: Andrew Bartlett
+ */
+
+#include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_errors.h"
+#include "ldb/include/ldb_private.h"
+#include "dsdb/samdb/samdb.h"
+
+/* Fix up the DN to be in the standard form, taking particular care to match the parent DN
+
+ This should mean that if the parent is:
+ CN=Users,DC=samba,DC=example,DC=com
+ and a proposed child is
+ cn=Admins ,cn=USERS,dc=Samba,dc=example,dc=COM
+
+ The resulting DN should be:
+
+ CN=Admins,CN=Users,DC=samba,DC=example,DC=com
+
+ */
+static int fix_dn(struct ldb_dn *dn)
+{
+ int i, ret;
+ char *upper_rdn_attr;
+
+ for (i=0; i < ldb_dn_get_comp_num(dn); i++) {
+ /* We need the attribute name in upper case */
+ upper_rdn_attr = strupper_talloc(dn,
+ ldb_dn_get_component_name(dn, i));
+ if (!upper_rdn_attr) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* And replace it with CN=foo (we need the attribute in upper case */
+ ret = ldb_dn_set_component(dn, i, upper_rdn_attr,
+ *ldb_dn_get_component_val(dn, i));
+ talloc_free(upper_rdn_attr);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ return LDB_SUCCESS;
+}
+
+static int normalise_search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares)
+{
+ const struct dsdb_schema *schema = dsdb_get_schema(ldb);
+ struct ldb_request *orig_req = talloc_get_type(context, struct ldb_request);
+ TALLOC_CTX *mem_ctx;
+ int i, j, ret;
+
+ /* Only entries are interesting, and we handle the case of the parent seperatly */
+ if (ares->type != LDB_REPLY_ENTRY) {
+ return orig_req->callback(ldb, orig_req->context, ares);
+ }
+
+ if (!schema) {
+ return orig_req->callback(ldb, orig_req->context, ares);
+ }
+
+ mem_ctx = talloc_new(ares);
+ if (!mem_ctx) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* OK, we have one of *many* search results passing by here,
+ * but we should get them one at a time */
+
+ ret = fix_dn(ares->message->dn);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+
+ for (i = 0; i < ares->message->num_elements; i++) {
+ const struct dsdb_attribute *attribute = dsdb_attribute_by_lDAPDisplayName(schema, ares->message->elements[i].name);
+ if (!attribute) {
+ continue;
+ }
+ if ((strcmp(attribute->attributeSyntax_oid, "2.5.5.1") != 0) &&
+ (strcmp(attribute->attributeSyntax_oid, "2.5.5.7") != 0)) {
+ continue;
+ }
+ for (j = 0; j < ares->message->elements[i].num_values; j++) {
+ const char *dn_str;
+ struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, (const char *)ares->message->elements[i].values[j].data);
+ if (!dn) {
+ talloc_free(mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ ret = fix_dn(ares->message->dn);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ dn_str = talloc_steal(ares->message->elements[i].values, ldb_dn_get_linearized(dn));
+ ares->message->elements[i].values[j] = data_blob_string_const(dn_str);
+ talloc_free(dn);
+ }
+ }
+ talloc_free(mem_ctx);
+ return orig_req->callback(ldb, orig_req->context, ares);
+}
+
+/* search */
+static int normalise_search(struct ldb_module *module, struct ldb_request *req)
+{
+ int ret;
+ struct ldb_request *down_req = talloc(req, struct ldb_request);
+ if (!down_req) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ *down_req = *req;
+ down_req->context = req;
+ down_req->callback = normalise_search_callback;
+
+ ret = ldb_next_request(module, down_req);
+
+ /* do not free down_req as the call results may be linked to it,
+ * it will be freed when the upper level request get freed */
+ if (ret == LDB_SUCCESS) {
+ req->handle = down_req->handle;
+ }
+ return ret;
+}
+
+
+static const struct ldb_module_ops normalise_ops = {
+ .name = "normalise",
+ .search = normalise_search,
+};
+
+int ldb_normalise_init(void)
+{
+ return ldb_register_module(&normalise_ops);
+}
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index d3beedc689..737475ca78 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -532,6 +532,10 @@ static int objectclass_do_add(struct ldb_handle *h)
ldb_msg_add_string(msg, "objectCategory",
current->objectclass->defaultObjectCategory);
}
+ if (!ldb_msg_find_element(msg, "showInAdvancedViewOnly") && (current->objectclass->defaultHidingValue == true)) {
+ ldb_msg_add_string(msg, "showInAdvancedViewOnly",
+ "TRUE");
+ }
if (!ldb_msg_find_element(msg, "nTSecurityDescriptor")) {
DATA_BLOB *sd = get_sd(ac->module, mem_ctx, current->objectclass);
ldb_msg_add_steal_value(msg, "nTSecurityDescriptor", sd);
diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c
index 4586810d96..61b64441a7 100644
--- a/source4/dsdb/samdb/ldb_modules/partition.c
+++ b/source4/dsdb/samdb/ldb_modules/partition.c
@@ -169,13 +169,12 @@ static int partition_other_callback(struct ldb_context *ldb, void *context, stru
}
-static int partition_send_request(struct partition_context *ac, struct ldb_control *remove_control,
+static int partition_send_request(struct partition_context *ac,
struct dsdb_control_current_partition *partition)
{
int ret;
struct ldb_module *backend;
struct ldb_request *req;
- struct ldb_control **saved_controls;
if (partition) {
backend = make_module_for_next_request(ac, ac->module->ldb, partition->module);
@@ -225,12 +224,6 @@ static int partition_send_request(struct partition_context *ac, struct ldb_contr
req->context = ac;
}
- /* Remove a control, so we don't confuse a backend server */
- if (remove_control && !save_controls(remove_control, req, &saved_controls)) {
- ldb_oom(ac->module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
if (partition) {
ret = ldb_request_add_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID, false, partition);
if (ret != LDB_SUCCESS) {
@@ -253,18 +246,17 @@ static int partition_send_request(struct partition_context *ac, struct ldb_contr
*/
static int partition_send_all(struct ldb_module *module,
struct partition_context *ac,
- struct ldb_control *remove_control,
struct ldb_request *req)
{
int i;
struct partition_private_data *data = talloc_get_type(module->private_data,
struct partition_private_data);
- int ret = partition_send_request(ac, remove_control, NULL);
+ int ret = partition_send_request(ac, NULL);
if (ret != LDB_SUCCESS) {
return ret;
}
for (i=0; data && data->partitions && data->partitions[i]; i++) {
- ret = partition_send_request(ac, remove_control, data->partitions[i]);
+ ret = partition_send_request(ac, data->partitions[i]);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -297,7 +289,7 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re
return LDB_ERR_OPERATIONS_ERROR;
}
- return partition_send_all(module, ac, NULL, req);
+ return partition_send_all(module, ac, req);
}
}
}
@@ -314,6 +306,7 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re
* TODO: we should maybe return an error here
* if it's not a special dn
*/
+
return ldb_next_request(module, req);
}
@@ -334,6 +327,8 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re
/* search */
static int partition_search(struct ldb_module *module, struct ldb_request *req)
{
+ struct ldb_control **saved_controls;
+
/* Find backend */
struct partition_private_data *data = talloc_get_type(module->private_data,
struct partition_private_data);
@@ -342,19 +337,34 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req)
/* (later) consider if we should be searching multiple
* partitions (for 'invisible' partition behaviour */
struct ldb_control *search_control = ldb_request_get_control(req, LDB_CONTROL_SEARCH_OPTIONS_OID);
+ struct ldb_control *domain_scope_control = ldb_request_get_control(req, LDB_CONTROL_DOMAIN_SCOPE_OID);
struct ldb_search_options_control *search_options = NULL;
if (search_control) {
search_options = talloc_get_type(search_control->data, struct ldb_search_options_control);
}
+ /* Remove the domain_scope control, so we don't confuse a backend server */
+ if (domain_scope_control && !save_controls(domain_scope_control, req, &saved_controls)) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* TODO:
+ Generate referrals (look for a partition under this DN) if we don't have the above control specified
+ */
+
if (search_options && (search_options->search_options & LDB_SEARCH_OPTION_PHANTOM_ROOT)) {
int ret, i;
struct partition_context *ac;
- struct ldb_control *remove_control = NULL;
if ((search_options->search_options & ~LDB_SEARCH_OPTION_PHANTOM_ROOT) == 0) {
/* We have processed this flag, so we are done with this control now */
- remove_control = search_control;
+
+ /* Remove search control, so we don't confuse a backend server */
+ if (search_control && !save_controls(search_control, req, &saved_controls)) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
}
ac = partition_init_handle(req, module);
if (!ac) {
@@ -363,12 +373,12 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req)
/* Search from the base DN */
if (!req->op.search.base || ldb_dn_is_null(req->op.search.base)) {
- return partition_send_all(module, ac, remove_control, req);
+ return partition_send_all(module, ac, req);
}
for (i=0; data && data->partitions && data->partitions[i]; i++) {
/* Find all partitions under the search base */
if (ldb_dn_compare_base(req->op.search.base, data->partitions[i]->dn) == 0) {
- ret = partition_send_request(ac, remove_control, data->partitions[i]);
+ ret = partition_send_request(ac, data->partitions[i]);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -384,6 +394,16 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req)
return LDB_SUCCESS;
} else {
/* Handle this like all other requests */
+ if (search_control && (search_options->search_options & ~LDB_SEARCH_OPTION_PHANTOM_ROOT) == 0) {
+ /* We have processed this flag, so we are done with this control now */
+
+ /* Remove search control, so we don't confuse a backend server */
+ if (search_control && !save_controls(search_control, req, &saved_controls)) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ }
+
return partition_replicate(module, req, req->op.search.base);
}
}
@@ -693,7 +713,7 @@ static int partition_extended(struct ldb_module *module, struct ldb_request *req
return LDB_ERR_OPERATIONS_ERROR;
}
- return partition_send_all(module, ac, NULL, req);
+ return partition_send_all(module, ac, req);
}
static int sort_compare(void *void1,
diff --git a/source4/dsdb/samdb/ldb_modules/samba3sam.c b/source4/dsdb/samdb/ldb_modules/samba3sam.c
index 0bfc9a3dae..3a666b5380 100644
--- a/source4/dsdb/samdb/ldb_modules/samba3sam.c
+++ b/source4/dsdb/samdb/ldb_modules/samba3sam.c
@@ -918,7 +918,7 @@ static int samba3sam_init(struct ldb_module *module)
{
int ret;
- ret = ldb_map_init(module, samba3_attributes, samba3_objectclasses, NULL, "samba3sam");
+ ret = ldb_map_init(module, samba3_attributes, samba3_objectclasses, NULL, NULL, "samba3sam");
if (ret != LDB_SUCCESS)
return ret;
diff --git a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c
index 91001d43d7..acf2fd622c 100644
--- a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c
+++ b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c
@@ -376,15 +376,6 @@ static const struct ldb_map_attribute entryuuid_attributes[] =
}
},
{
- .local_name = "dn",
- .type = MAP_RENAME,
- .u = {
- .rename = {
- .remote_name = "entryDN"
- }
- }
- },
- {
.local_name = "groupType",
.type = MAP_CONVERT,
.u = {
@@ -457,6 +448,7 @@ static const char * const entryuuid_wildcard_attributes[] = {
"whenChanged",
"usnCreated",
"usnChanged",
+ "memberOf",
NULL
};
@@ -534,15 +526,6 @@ static const struct ldb_map_attribute nsuniqueid_attributes[] =
}
},
{
- .local_name = "dn",
- .type = MAP_RENAME,
- .u = {
- .rename = {
- .remote_name = "entryDN"
- }
- }
- },
- {
.local_name = "groupType",
.type = MAP_CONVERT,
.u = {
@@ -685,7 +668,7 @@ static int entryuuid_init(struct ldb_module *module)
struct map_private *map_private;
struct entryuuid_private *entryuuid_private;
- ret = ldb_map_init(module, entryuuid_attributes, entryuuid_objectclasses, entryuuid_wildcard_attributes, NULL);
+ ret = ldb_map_init(module, entryuuid_attributes, entryuuid_objectclasses, entryuuid_wildcard_attributes, "extensibleObject", NULL);
if (ret != LDB_SUCCESS)
return ret;
@@ -706,7 +689,7 @@ static int nsuniqueid_init(struct ldb_module *module)
struct map_private *map_private;
struct entryuuid_private *entryuuid_private;
- ret = ldb_map_init(module, nsuniqueid_attributes, NULL, nsuniqueid_wildcard_attributes, NULL);
+ ret = ldb_map_init(module, nsuniqueid_attributes, NULL, nsuniqueid_wildcard_attributes, "extensibleObject", NULL);
if (ret != LDB_SUCCESS)
return ret;