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