summaryrefslogtreecommitdiff
path: root/source4/lib/ldb
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-10-13 05:04:16 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:39:46 -0500
commit0fa924bb8f446e35a0fd543cda20b23c81e7dc9e (patch)
treeecf2d9c4d72b4a33a14a282fb2aada4a51d20147 /source4/lib/ldb
parentd96f706bb0a6b41eddec9d467ef3d5f31bee41ab (diff)
downloadsamba-0fa924bb8f446e35a0fd543cda20b23c81e7dc9e.tar.gz
samba-0fa924bb8f446e35a0fd543cda20b23c81e7dc9e.tar.bz2
samba-0fa924bb8f446e35a0fd543cda20b23c81e7dc9e.zip
r10954: added support for canonicalName in the operational module, using the
dn->canonicalName function abartlet just committed (This used to be commit 197e8a27f0557869eacd17b74e1b14e0665883b1)
Diffstat (limited to 'source4/lib/ldb')
-rw-r--r--source4/lib/ldb/common/ldb_msg.c13
-rw-r--r--source4/lib/ldb/include/ldb.h1
-rw-r--r--source4/lib/ldb/modules/operational.c112
3 files changed, 94 insertions, 32 deletions
diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c
index 977f68144b..f4a49e47ce 100644
--- a/source4/lib/ldb/common/ldb_msg.c
+++ b/source4/lib/ldb/common/ldb_msg.c
@@ -618,6 +618,19 @@ int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *rep
/*
+ remove the specified attribute in a search result
+*/
+void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr)
+{
+ struct ldb_message_element *el = ldb_msg_find_element(msg, attr);
+ int n = (el - msg->elements);
+ if (n != msg->num_elements-1) {
+ memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el));
+ }
+ msg->num_elements--;
+}
+
+/*
return a LDAP formatted time string
*/
char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t)
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h
index 27313613ab..c26229678e 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -498,6 +498,7 @@ void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree,
int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace);
int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace);
+void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr);
char *ldb_timestring(void *mem_ctx, time_t t);
time_t ldb_string_to_time(const char *s);
diff --git a/source4/lib/ldb/modules/operational.c b/source4/lib/ldb/modules/operational.c
index c40936df07..8a06e20c29 100644
--- a/source4/lib/ldb/modules/operational.c
+++ b/source4/lib/ldb/modules/operational.c
@@ -80,6 +80,19 @@
#include <time.h>
/*
+ construct a canonical name from a message
+*/
+static int construct_canonical_name(struct ldb_module *module, struct ldb_message *msg)
+{
+ char *canonicalName;
+ canonicalName = ldb_dn_canonical_string(msg, msg->dn);
+ if (canonicalName == NULL) {
+ return -1;
+ }
+ return ldb_msg_add_string(msg, "canonicalName", canonicalName);
+}
+
+/*
a list of attribute names that should be substituted in the parse
tree before the search is done
*/
@@ -91,6 +104,7 @@ static const struct {
{ "modifyTimestamp", "whenChanged" }
};
+
/*
a list of attribute names that are hidden, but can be searched for
using another (non-hidden) name to produce the correct result
@@ -98,13 +112,66 @@ static const struct {
static const struct {
const char *attr;
const char *replace;
+ int (*constructor)(struct ldb_module *, struct ldb_message *);
} search_sub[] = {
- { "createTimestamp", "whenCreated" },
- { "modifyTimestamp", "whenChanged" },
- { "structuralObjectClass", "objectClass" }
+ { "createTimestamp", "whenCreated", NULL },
+ { "modifyTimestamp", "whenChanged", NULL },
+ { "structuralObjectClass", "objectClass", NULL },
+ { "canonicalName", "distinguishedName", construct_canonical_name }
};
/*
+ post process a search result record. For any search_sub[] attributes that were
+ asked for, we need to call the appropriate copy routine to copy the result
+ into the message, then remove any attributes that we added to the search but were
+ not asked for by the user
+*/
+static int operational_search_post_process(struct ldb_module *module,
+ struct ldb_message *msg,
+ const char * const *attrs)
+{
+ int i, a=0;
+
+ for (a=0;attrs && attrs[a];a++) {
+ for (i=0;i<ARRAY_SIZE(search_sub);i++) {
+ if (ldb_attr_cmp(attrs[a], search_sub[i].attr) != 0) {
+ continue;
+ }
+
+ /* construct the new attribute, using either a supplied
+ constructor or a simple copy */
+ if (search_sub[i].constructor) {
+ if (search_sub[i].constructor(module, msg) != 0) {
+ goto failed;
+ }
+ } else if (ldb_msg_copy_attr(msg,
+ search_sub[i].replace,
+ search_sub[i].attr) != 0) {
+ goto failed;
+ }
+
+ /* remove the added search attribute, unless it was asked for
+ by the user */
+ if (search_sub[i].replace == NULL ||
+ ldb_attr_in_list(attrs, search_sub[i].replace) ||
+ ldb_attr_in_list(attrs, "*")) {
+ continue;
+ }
+
+ ldb_msg_remove_attr(msg, search_sub[i].replace);
+ }
+ }
+
+ return 0;
+
+failed:
+ ldb_debug_set(module->ldb, LDB_DEBUG_WARNING,
+ "operational_search_post_process failed for attribute '%s'\n",
+ attrs[a]);
+ return -1;
+}
+
+/*
hook search operations
*/
static int operational_search_bytree(struct ldb_module *module,
@@ -131,13 +198,14 @@ static int operational_search_bytree(struct ldb_module *module,
/* in the list of attributes we are looking for, rename any
attributes to the alias for any hidden attributes that can
be fetched directly using non-hidden names */
- for (i=0;i<ARRAY_SIZE(search_sub);i++) {
- for (a=0;attrs && attrs[a];a++) {
- if (ldb_attr_cmp(attrs[a], search_sub[i].attr) == 0) {
+ for (a=0;attrs && attrs[a];a++) {
+ for (i=0;i<ARRAY_SIZE(search_sub);i++) {
+ if (ldb_attr_cmp(attrs[a], search_sub[i].attr) == 0 &&
+ search_sub[i].replace) {
if (!search_attrs) {
search_attrs = ldb_attr_list_copy(module, attrs);
if (search_attrs == NULL) {
- goto oom;
+ goto failed;
}
}
search_attrs[a] = search_sub[i].replace;
@@ -153,31 +221,11 @@ static int operational_search_bytree(struct ldb_module *module,
return ret;
}
- /* for each record returned see if we have added any
- attributes to the search, and if we have then either copy
- them (if the aliased name was also asked for) or rename
- them (if the aliased entry was not asked for) */
+ /* for each record returned post-process to add any derived
+ attributes that have been asked for */
for (r=0;r<ret;r++) {
- for (i=0;i<ARRAY_SIZE(search_sub);i++) {
- for (a=0;attrs && attrs[a];a++) {
- if (ldb_attr_cmp(attrs[a], search_sub[i].attr) != 0) {
- continue;
- }
- if (ldb_attr_in_list(attrs, search_sub[i].replace) ||
- ldb_attr_in_list(attrs, "*")) {
- if (ldb_msg_copy_attr((*res)[r],
- search_sub[i].replace,
- search_sub[i].attr) != 0) {
- goto oom;
- }
- } else {
- if (ldb_msg_rename_attr((*res)[r],
- search_sub[i].replace,
- search_sub[i].attr) != 0) {
- goto oom;
- }
- }
- }
+ if (operational_search_post_process(module, (*res)[r], attrs) != 0) {
+ goto failed;
}
}
@@ -185,7 +233,7 @@ static int operational_search_bytree(struct ldb_module *module,
talloc_free(search_attrs);
return ret;
-oom:
+failed:
talloc_free(search_attrs);
talloc_free(*res);
ldb_oom(module->ldb);