diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-10-13 05:04:16 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:39:46 -0500 |
commit | 0fa924bb8f446e35a0fd543cda20b23c81e7dc9e (patch) | |
tree | ecf2d9c4d72b4a33a14a282fb2aada4a51d20147 /source4/lib | |
parent | d96f706bb0a6b41eddec9d467ef3d5f31bee41ab (diff) | |
download | samba-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')
-rw-r--r-- | source4/lib/ldb/common/ldb_msg.c | 13 | ||||
-rw-r--r-- | source4/lib/ldb/include/ldb.h | 1 | ||||
-rw-r--r-- | source4/lib/ldb/modules/operational.c | 112 |
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); |