svn commit: samba r16534 - in branches/SOC/mkhl/ldb-map/modules: .
mkhl at samba.org
mkhl at samba.org
Mon Jun 26 22:07:25 GMT 2006
Author: mkhl
Date: 2006-06-26 22:07:25 +0000 (Mon, 26 Jun 2006)
New Revision: 16534
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16534
Log:
Add support for merging remote search results with local search
results.
Martin
Modified:
branches/SOC/mkhl/ldb-map/modules/ldb_map.c
Changeset:
Modified: branches/SOC/mkhl/ldb-map/modules/ldb_map.c
===================================================================
--- branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-06-26 21:21:59 UTC (rev 16533)
+++ branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-06-26 22:07:25 UTC (rev 16534)
@@ -791,7 +791,6 @@
return NULL;
}
-
/* local DN -> remote DN (as LDB values) */
static
struct ldb_val
@@ -1131,112 +1130,6 @@
/* } */
/* /\* XXX *\/ */
-/* /\* Remote message element -> Local message element *\/ */
-/* static struct ldb_message_element *mop_remote_msg_element(struct ldb_module *module, */
-/* struct ldb_message *msg, */
-/* const struct ldb_message *oldmsg, */
-/* const struct ldb_map_attribute *attr) */
-/* { */
-/* struct ldb_message_element *el, *oldel; */
-/* int i; */
-
-/* el = talloc(msg, struct ldb_message_element); */
-/* if (el == NULL) */
-/* return NULL; */
-
-/* switch (attr->type) { */
-/* case MAP_IGNORE: */
-/* goto failed; */
-
-/* case MAP_KEEP: */
-/* ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map: " */
-/* "Keeping remote attribute '%s'\n", attr->local_name); */
-
-/* oldel = ldb_msg_find_element(oldmsg, attr->local_name); */
-/* if (oldel == NULL) */
-/* goto failed; */
-
-/* el->name = talloc_strdup(el, attr->local_name); */
-/* el->flags = oldel->flags; */
-/* el->num_values = oldel->num_values; */
-/* el->values = talloc_array(el, struct ldb_val, el->num_values); */
-/* if (el->values == NULL) */
-/* goto failed; */
-
-/* for (i = 0; i < el->num_values; i++) */
-/* el->values[i] = ldb_val_dup(el, &oldel->values[i]); */
-
-/* return el; */
-
-/* case MAP_RENAME: */
-/* ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map: " */
-/* "Renaming remote attribute '%s' to '%s'\n", */
-/* attr->u.rename.remote_name, attr->local_name); */
-
-/* oldel = ldb_msg_find_element(oldmsg, attr->u.rename.remote_name); */
-/* if (oldel == NULL) */
-/* goto failed; */
-
-/* el->name = talloc_strdup(el, attr->local_name); */
-/* el->flags = oldel->flags; */
-/* el->num_values = oldel->num_values; */
-/* el->values = talloc_array(el, struct ldb_val, el->num_values); */
-/* if (el->values == NULL) */
-/* goto failed; */
-
-/* for (i = 0; i < el->num_values; i++) */
-/* el->values[i] = ldb_val_dup(el, &oldel->values[i]); */
-
-/* return el; */
-
-/* case MAP_CONVERT: */
-/* ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map: " */
-/* "Converting remote attribute '%s' to '%s'\n", */
-/* attr->u.rename.remote_name, attr->local_name); */
-
-/* if (attr->u.convert.convert_remote == NULL) { */
-/* ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " */
-/* "'convert_remote' not set!\n"); */
-/* goto failed; */
-/* } */
-
-/* oldel = ldb_msg_find_element(oldmsg, attr->u.rename.remote_name); */
-/* if (oldel == NULL) */
-/* goto failed; */
-
-/* el->name = talloc_strdup(el, attr->local_name); */
-/* el->flags = oldel->flags; */
-/* el->num_values = oldel->num_values; */
-/* el->values = talloc_array(el, struct ldb_val, el->num_values); */
-/* if (el->values == NULL) */
-/* goto failed; */
-
-/* for (i = 0; i < el->num_values; i++) */
-/* el->values[i] = attr->u.convert.convert_remote(module, el, &oldel->values[i]); */
-
-/* return el; */
-
-/* case MAP_GENERATE: */
-/* ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map: " */
-/* "Generating local attribute '%s'\n", */
-/* attr->local_name); */
-
-/* if (attr->u.generate.generate_local == NULL) { */
-/* ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " */
-/* "'generate_local' not set!\n"); */
-/* goto failed; */
-/* } */
-
-/* talloc_free(el); */
-/* return attr->u.generate.generate_local(module, msg, attr->local_name, oldmsg); */
-/* } */
-
-/* failed: */
-/* talloc_free(el); */
-/* return NULL; */
-/* } */
-
-/* /\* XXX *\/ */
/* /\* Remote message -> Local message *\/ */
/* static struct ldb_message *mop_ldb_message_incoming(struct ldb_module *module, */
/* const char *const names[], */
@@ -1292,15 +1185,42 @@
/* return NULL; */
/* } */
+/* add element to message, overwriting old elements of the same name */
+static
+int
+ldb_msg_replace(struct ldb_message *msg,
+ const struct ldb_message_element *el)
+{
+ struct ldb_message_element *old;
+
+ old = ldb_msg_find_element(msg, el->name);
+ /* no local result, add as new */
+ if (old == NULL) {
+ if (ldb_msg_add_empty(msg, el->name, 0) != LDB_SUCCESS)
+ goto failed;
+
+ old = ldb_msg_find_element(msg, el->name);
+ if (old == NULL)
+ goto failed;
+ }
+
+ *old = *el; /* copy element */
+
+ return 0;
+
+failed:
+ return -1;
+}
+
/* Create a copy of the given message element with the specified name.
* If a mapping is specified, use it to convert the values. */
static
struct ldb_message_element *
copy_conv_msg_el(struct ldb_module *module,
struct ldb_message *msg,
- const struct ldb_map_attribute *map,
const struct ldb_message_element *old,
- const char *name)
+ const char *name,
+ const ldb_map_convert_func map)
{
struct ldb_message_element *el;
int i;
@@ -1326,8 +1246,7 @@
if (map == NULL)
el->values[i] = ldb_val_dup(el, &old->values[i]);
else
- el->values[i] = map->u.convert
- .convert_local(module, el, &old->values[i]);
+ el->values[i] = map(module, el, &old->values[i]);
}
return el;
@@ -1360,13 +1279,11 @@
goto local;
case MAP_KEEP:
- el = copy_conv_msg_el(module, remote, NULL, old,
- map->local_name);
+ el = copy_conv_msg_el(module, remote, old, map->local_name, NULL);
break;
case MAP_RENAME:
- el = copy_conv_msg_el(module, remote, NULL, old,
- map->u.rename.remote_name);
+ el = copy_conv_msg_el(module, remote, old, map->u.rename.remote_name, NULL);
break;
case MAP_CONVERT:
@@ -1377,8 +1294,7 @@
map->local_name);
goto failed;
- el = copy_conv_msg_el(module, remote, map, old,
- map->u.rename.remote_name);
+ el = copy_conv_msg_el(module, remote, old, map->u.convert.remote_name, map->u.convert.convert_local);
break;
case MAP_GENERATE:
@@ -1442,6 +1358,7 @@
}
map = find_local_attr(data, msg->elements[i].name);
+
ret = partition_msg_el(module, local, remote, map,
msg, &msg->elements[i]);
if (ret != 0)
@@ -1451,14 +1368,97 @@
return 0;
}
+/* merge remote message element into local message */
static
int
-merge_mapped_results(struct map_async_search_context *context)
+merge_msg_el(struct ldb_module *module,
+ struct ldb_message *local,
+ struct ldb_message *remote,
+ const struct ldb_map_attribute *map,
+ const struct ldb_message_element *old)
{
- return LDB_SUCCESS; /* TODO */
+ struct ldb_message_element *el;
+
+ /* no mapping: fail */
+ if (map == NULL) {
+ ldb_debug(module->ldb, LDB_DEBUG_WARNING, "ldb_map: "
+ "Not mapping attribute '%s': no mapping found\n",
+ old->name);
+ goto failed;
+ }
+
+ switch (map->type) {
+ case MAP_IGNORE:
+ goto failed;
+
+ case MAP_KEEP:
+ case MAP_RENAME:
+ el = copy_conv_msg_el(module, local, old, map->local_name, NULL);
+ break;
+
+ case MAP_CONVERT:
+ if (map->u.convert.convert_remote == NULL) {
+ ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "
+ "Skipping attribute '%s': "
+ "'convert_remote' not set\n",
+ old->name);
+ goto unmapped;
+ }
+
+ el = copy_conv_msg_el(module, local, old, map->local_name, map->u.convert.convert_remote);
+ break;
+
+ case MAP_GENERATE:
+ if (map->u.generate.generate_local == NULL) {
+ ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "
+ "Skipping attribute '%s': "
+ "'generate_local' not set\n",
+ old->name);
+ goto unmapped;
+ }
+
+ el = map->u.generate.generate_local(module, local, map->local_name, remote);
+ break;
+ }
+
+ if (el == NULL)
+ goto failed;
+ return ldb_msg_replace(local, el);
+
+unmapped:
+ return 0;
+
+failed:
+ return -1;
}
+/* merge remote message into local message */
+static
+int
+merge_msg(struct ldb_module *module,
+ struct ldb_message *local,
+ struct ldb_message *remote)
+{
+ struct ldb_map_context *data = map_get_context(module);
+ const struct ldb_map_attribute *map;
+ int i, ret;
+ /* try to map each attribute back;
+ add to the local message is possible,
+ overwrite old local attribute if necessary */
+ for (i = 0; i < remote->num_elements; i++) {
+ map = find_remote_attr(data, remote->elements[i].name);
+
+ ret = merge_msg_el(module, local, remote, map,
+ &remote->elements[i]);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+
/* store single search result in async context */
static
int
@@ -1577,7 +1577,7 @@
sc->remote_res = ares;
/* merge remote into local record */
- ret = merge_mapped_results(sc);
+ ret = merge_msg(sc->ac->module, sc->local_res->message, sc->remote_res->message);
if (ret != LDB_SUCCESS)
talloc_free(ares);
@@ -1648,6 +1648,7 @@
sc->local_res = ares;
sc->remote_res = NULL;
+ /* TODO: map the remote parse-tree */
remote_attrs = select_mapped_attrs(ac->module, ac,
ac->orig_req->op.search.attrs);
req = search_base_req(ac, dn, remote_attrs, remote_search_callback);
More information about the samba-cvs
mailing list