svn commit: samba r18495 - in branches/SAMBA_4_0/source: dsdb/samdb/ldb_modules lib/ldb/modules

abartlet at samba.org abartlet at samba.org
Thu Sep 14 03:15:31 GMT 2006


Author: abartlet
Date: 2006-09-14 03:15:30 +0000 (Thu, 14 Sep 2006)
New Revision: 18495

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=18495

Log:
More work on the LDAP backend (which now passes a lot of our tests!)

This adds a list of attributes that are in our wildcard seaches, but
the remote server requires to be explicitly listed.  This also cleans
up the handling of wildcards in ldb_map to be more consistant.

Also fix the partitions module to rebase the search, if on the GC
port, we do a subtree search.  (Otherwise backends can rightly
complain that the search is not in their scope).

Andrew Bartlett

Modified:
   branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/entryUUID.c
   branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/partition.c
   branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/samba3sam.c
   branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map.c
   branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map.h
   branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map_outbound.c
   branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map_private.h


Changeset:
Modified: branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/entryUUID.c
===================================================================
--- branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/entryUUID.c	2006-09-14 03:13:02 UTC (rev 18494)
+++ branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/entryUUID.c	2006-09-14 03:15:30 UTC (rev 18495)
@@ -303,6 +303,15 @@
 	}
 };
 
+/* These things do not show up in wildcard searches in OpenLDAP, but
+ * we need them to show up in the AD-like view */
+const char * const wildcard_attributes[] = {
+	"objectGUID", 
+	"whenCreated", 
+	"whenChanged",
+	NULL
+};
+
 static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx) 
 {
 	const char *rootdse_attrs[] = {"schemaNamingContext", NULL};
@@ -372,7 +381,7 @@
 	struct entryUUID_private *entryUUID_private;
 	struct ldb_dn *schema_dn;
 
-	ret = ldb_map_init(module, entryUUID_attributes, NULL, NULL);
+	ret = ldb_map_init(module, entryUUID_attributes, NULL, wildcard_attributes, NULL);
         if (ret != LDB_SUCCESS)
                 return ret;
 
@@ -387,7 +396,8 @@
 		return LDB_SUCCESS;
 	}
 	
-	ret = fetch_objectclass_schema(module->ldb, schema_dn, entryUUID_private, &entryUUID_private->objectclass_res);
+	ret = fetch_objectclass_schema(module->ldb, schema_dn, entryUUID_private, 
+				       &entryUUID_private->objectclass_res);
 	if (ret != LDB_SUCCESS) {
 		ldb_asprintf_errstring(module->ldb, "Failed to fetch objectClass schema elements: %s\n", ldb_errstring(module->ldb));
 		return ret;

Modified: branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/partition.c
===================================================================
--- branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/partition.c	2006-09-14 03:13:02 UTC (rev 18494)
+++ branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/partition.c	2006-09-14 03:15:30 UTC (rev 18495)
@@ -186,35 +186,43 @@
 }
 
 
-static int partition_send_request(struct partition_context *ac, struct ldb_module *partition)
+static int partition_send_request(struct partition_context *ac, struct ldb_module *partition, 
+				  struct ldb_dn *partition_base_dn)
 {
 	int ret;
 	struct ldb_module *next = make_module_for_next_request(ac->module, ac->module->ldb, partition);
-	
+	struct ldb_request *req;
 	ac->down_req = talloc_realloc(ac, ac->down_req, 
 					struct ldb_request *, ac->num_requests + 1);
 	if (!ac->down_req) {
 		ldb_set_errstring(ac->module->ldb, "Out of Memory");
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
-	ac->down_req[ac->num_requests] = talloc(ac, struct ldb_request);
-	if (ac->down_req[ac->num_requests] == NULL) {
+	req = ac->down_req[ac->num_requests] = talloc(ac, struct ldb_request);
+	if (req == NULL) {
 		ldb_set_errstring(ac->module->ldb, "Out of Memory");
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 	
 	*ac->down_req[ac->num_requests] = *ac->orig_req; /* copy the request */
-	
-	if (ac->down_req[ac->num_requests]->operation == LDB_SEARCH) {
-		ac->down_req[ac->num_requests]->callback = partition_search_callback;
-		ac->down_req[ac->num_requests]->context = ac;
+
+	if (req->operation == LDB_SEARCH) {
+		/* If the search is for 'more' than this partition,
+		 * then change the basedn, so a remote LDAP server
+		 * doesn't object */
+		if (ldb_dn_compare_base(ac->module->ldb, 
+					partition_base_dn, req->op.search.base) != 0) {
+			req->op.search.base = partition_base_dn;
+		}
+		req->callback = partition_search_callback;
+		req->context = ac;
 	} else {
-		ac->down_req[ac->num_requests]->callback = partition_other_callback;
-		ac->down_req[ac->num_requests]->context = ac;
+		req->callback = partition_other_callback;
+		req->context = ac;
 	}
 
 	/* Spray off search requests to all backends */
-	ret = ldb_next_request(next, ac->down_req[ac->num_requests]); 
+	ret = ldb_next_request(next, req); 
 	if (ret != LDB_SUCCESS) {
 		return ret;
 	}
@@ -230,12 +238,12 @@
 	int i;
 	struct partition_private_data *data = talloc_get_type(module->private_data, 
 							      struct partition_private_data);
-	int ret = partition_send_request(ac, module->next);
+	int ret = partition_send_request(ac, module->next, NULL);
 	if (ret != LDB_SUCCESS) {
 		return ret;
 	}
 	for (i=0; data && data->partitions && data->partitions[i]; i++) {
-		ret = partition_send_request(ac, data->partitions[i]->module);
+		ret = partition_send_request(ac, data->partitions[i]->module, data->partitions[i]->dn);
 		if (ret != LDB_SUCCESS) {
 			return ret;
 		}
@@ -307,21 +315,26 @@
 		
 		ac = talloc_get_type(h->private_data, struct partition_context);
 		
+		/* Search from the base DN */
+		if (!req->op.search.base || req->op.search.base->comp_num == 0) {
+			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(module->ldb, 
 						req->op.search.base,
 						data->partitions[i]->dn) == 0) {
-				ret = partition_send_request(ac, data->partitions[i]->module);
+				ret = partition_send_request(ac, data->partitions[i]->module, data->partitions[i]->dn);
 				if (ret != LDB_SUCCESS) {
 					return ret;
 				}
 			}
 		}
 
-		/* Perhaps we didn't match any partitions.  Try the main partition, then all partitions */
+		/* Perhaps we didn't match any partitions.  Try the main partition, only */
 		if (ac->num_requests == 0) {
-			return partition_send_all(module, ac, req);
+			talloc_free(h);
+			return ldb_next_request(module, req);
 		}
 		
 		return LDB_SUCCESS;
@@ -701,11 +714,19 @@
 			
 			ret = ldb_load_modules_list(module->ldb, modules, partition->module, &partition->module);
 			if (ret != LDB_SUCCESS) {
+				ldb_asprintf_errstring(module->ldb, 
+						       "partition_init: "
+						       "loading backend for %s failed: %s", 
+						       base, ldb_errstring(module->ldb));
 				talloc_free(mem_ctx);
 				return ret;
 			}
 			ret = ldb_init_module_chain(module->ldb, partition->module);
 			if (ret != LDB_SUCCESS) {
+				ldb_asprintf_errstring(module->ldb, 
+						       "partition_init: "
+						       "initialising backend for %s failed: %s", 
+						       base, ldb_errstring(module->ldb));
 				talloc_free(mem_ctx);
 				return ret;
 			}

Modified: branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/samba3sam.c
===================================================================
--- branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/samba3sam.c	2006-09-14 03:13:02 UTC (rev 18494)
+++ branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/samba3sam.c	2006-09-14 03:15:30 UTC (rev 18495)
@@ -866,7 +866,7 @@
 {
         int ret;
 
-	ret = ldb_map_init(module, samba3_attributes, samba3_objectclasses, "samba3sam");
+	ret = ldb_map_init(module, samba3_attributes, samba3_objectclasses, NULL, "samba3sam");
         if (ret != LDB_SUCCESS)
                 return ret;
 

Modified: branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map.c
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map.c	2006-09-14 03:13:02 UTC (rev 18494)
+++ branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map.c	2006-09-14 03:15:30 UTC (rev 18495)
@@ -432,6 +432,30 @@
 	return talloc_strdup(mem_ctx, map->local_name);
 }
 
+
+/* Merge two lists of attributes into a single one. */
+int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs)
+{
+	int i, j, k;
+
+	for (i = 0; *attrs && (*attrs)[i]; i++) /* noop */ ;
+	for (j = 0; more_attrs && more_attrs[j]; j++) /* noop */ ;
+
+	*attrs = talloc_realloc(mem_ctx, *attrs, const char *, i+j+1);
+	if (*attrs == NULL) {
+		map_oom(module);
+		return -1;
+	}
+
+	for (k = 0; k < j; k++) {
+		(*attrs)[i+k] = more_attrs[k];
+	}
+
+	(*attrs)[i+k] = NULL;
+
+	return 0;
+}
+
 /* Mapping ldb values
  * ================== */
 
@@ -1226,7 +1250,10 @@
 }
 
 /* Store attribute maps and objectClass maps in private data. */
-static int map_init_maps(struct ldb_module *module, struct ldb_map_context *data, const struct ldb_map_attribute *attrs, const struct ldb_map_objectclass *ocls)
+static int map_init_maps(struct ldb_module *module, struct ldb_map_context *data, 
+			 const struct ldb_map_attribute *attrs, 
+			 const struct ldb_map_objectclass *ocls, 
+			 const char * const *wildcard_attributes)
 {
 	int i, j, last;
 	last = 0;
@@ -1261,6 +1288,8 @@
 	/* Store list of objectClass maps */
 	data->objectclass_maps = ocls;
 
+	data->wildcard_attributes = wildcard_attributes;
+
 	return LDB_SUCCESS;
 }
 
@@ -1271,7 +1300,10 @@
 }
 
 /* Initialize global private data. */
-int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, const struct ldb_map_objectclass *ocls, const char *name)
+int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, 
+		 const struct ldb_map_objectclass *ocls,
+		 const char * const *wildcard_attributes,
+		 const char *name)
 {
 	struct map_private *data;
 	int ret;
@@ -1299,7 +1331,7 @@
 	}
 
 	/* Store list of attribute and objectClass maps */
-	ret = map_init_maps(module, data->context, attrs, ocls);
+	ret = map_init_maps(module, data->context, attrs, ocls, wildcard_attributes);
 	if (ret != LDB_SUCCESS) {
 		talloc_free(data);
 		return ret;

Modified: branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map.h
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map.h	2006-09-14 03:13:02 UTC (rev 18494)
+++ branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map.h	2006-09-14 03:15:30 UTC (rev 18495)
@@ -1,27 +1,26 @@
-/* 
-   ldb database library - map backend
+/*
+   ldb database mapping module
 
    Copyright (C) Jelmer Vernooij 2005
    Copyright (C) Martin Kuehl <mkhl at samba.org> 2006
-	Development sponsored by the Google Summer of Code program
 
-     ** NOTE! The following LGPL license applies to the ldb
-     ** library. This does NOT imply that all of Samba is released
-     ** under the LGPL
+   * NOTICE: this module is NOT released under the GNU LGPL license as
+   * other ldb code. This module is release under the GNU GPL v2 or
+   * later license.
+
+   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 2 of the License, or
+   (at your option) any later version.
    
-   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 2 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
+   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
-   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, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA
+   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, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 #ifndef __LDB_MAP_H__
@@ -130,6 +129,11 @@
 	struct ldb_map_attribute *attribute_maps;
 	/* NOTE: Always declare base classes first here */
 	const struct ldb_map_objectclass *objectclass_maps;
+
+	/* Remote (often operational) attributes that should be added
+	 * to any wildcard search */
+	const char * const *wildcard_attributes;
+
 	/* struct ldb_context *mapped_ldb; */
 	const struct ldb_dn *local_base_dn;
 	const struct ldb_dn *remote_base_dn;
@@ -141,12 +145,11 @@
 	struct ldb_map_context *context;
 };
 
-/* initialization function */
-int
-ldb_map_init(struct ldb_module *module,
-	     const struct ldb_map_attribute *attrs,
-	     const struct ldb_map_objectclass *ocls,
-	     const char *name);
+/* Initialize global private data. */
+int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, 
+		 const struct ldb_map_objectclass *ocls,
+		 const char * const *wildcard_attributes,
+		 const char *name);
 
 /* get copy of map_ops */
 struct ldb_module_ops

Modified: branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map_outbound.c
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map_outbound.c	2006-09-14 03:13:02 UTC (rev 18494)
+++ branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map_outbound.c	2006-09-14 03:15:30 UTC (rev 18495)
@@ -3,6 +3,7 @@
 
    Copyright (C) Jelmer Vernooij 2005
    Copyright (C) Martin Kuehl <mkhl at samba.org> 2006
+   Copyright (C) Andrew Bartlett <abartlet at samba.org> 2006
 
    * NOTICE: this module is NOT released under the GNU LGPL license as
    * other ldb code. This module is release under the GNU GPL v2 or
@@ -81,10 +82,8 @@
 	const struct ldb_map_attribute *map;
 	const char *name=NULL;
 	int i, j, last;
+	int ret;
 
-	if (attrs == NULL)
-		return NULL;
-
 	last = 0;
 	result = talloc_array(mem_ctx, const char *, 1);
 	if (result == NULL) {
@@ -95,6 +94,25 @@
 	for (i = 0; attrs[i]; i++) {
 		/* Wildcards are kept remotely, too */
 		if (ldb_attr_cmp(attrs[i], "*") == 0) {
+			const char **new_attrs = NULL;
+			ret = map_attrs_merge(module, mem_ctx, &new_attrs, attrs);
+			if (ret != LDB_SUCCESS) {
+				goto failed;
+			}
+			ret = map_attrs_merge(module, mem_ctx, &new_attrs, data->wildcard_attributes);
+			if (ret != LDB_SUCCESS) {
+				goto failed;
+			}
+
+			attrs = new_attrs;
+			break;
+		}
+	}
+
+	for (i = 0; attrs[i]; i++) {
+		/* Wildcards are kept remotely, too */
+		if (ldb_attr_cmp(attrs[i], "*") == 0) {
+			/* Add all 'include in wildcard' attributes */
 			name = attrs[i];
 			goto named;
 		}
@@ -162,29 +180,6 @@
 	return 0;
 }
 
-/* Merge two lists of attributes into a single one. */
-static int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs)
-{
-	int i, j, k;
-
-	for (i = 0; (*attrs)[i]; i++) /* noop */ ;
-	for (j = 0; more_attrs[j]; j++) /* noop */ ;
-
-	*attrs = talloc_realloc(mem_ctx, *attrs, const char *, i+j+1);
-	if (*attrs == NULL) {
-		map_oom(module);
-		return -1;
-	}
-
-	for (k = 0; k < j; k++) {
-		(*attrs)[i+k] = more_attrs[k];
-	}
-
-	(*attrs)[i+k] = NULL;
-
-	return 0;
-}
-
 /* Mapping ldb values
  * ================== */
 
@@ -815,11 +810,6 @@
 	*local_attrs = NULL;
 	*remote_attrs = NULL;
 
-	/* There are no searched attributes, just stick to that */
-	if (search_attrs == NULL) {
-		return 0;
-	}
-
 	/* There is no tree, just partition the searched attributes */
 	if (tree == NULL) {
 		return map_attrs_partition(module, local_ctx, remote_ctx, local_attrs, remote_attrs, search_attrs);
@@ -1028,6 +1018,9 @@
 	const char **local_attrs, **remote_attrs;
 	int ret;
 
+	const char *wildcard[] = { "*", NULL };
+	const char * const *attrs;
+
 	/* Do not manipulate our control entries */
 	if (ldb_dn_is_special(req->op.search.base))
 		return ldb_next_request(module, req);
@@ -1068,8 +1061,15 @@
 	ac->search_reqs[0]->context = ac;
 	ac->search_reqs[0]->callback = map_remote_search_callback;
 
+	/* It is easier to deal with the two different ways of
+	 * expressing the wildcard in the same codepath */
+	attrs = req->op.search.attrs;
+	if (attrs == NULL) {
+		attrs = wildcard;
+	}
+
 	/* Split local from remote attrs */
-	ret = map_attrs_collect_and_partition(module, ac, ac->search_reqs[0], &local_attrs, &remote_attrs, req->op.search.attrs, req->op.search.tree);
+	ret = map_attrs_collect_and_partition(module, ac, ac->search_reqs[0], &local_attrs, &remote_attrs, attrs, req->op.search.tree);
 	if (ret) {
 		goto failed;
 	}

Modified: branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map_private.h
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map_private.h	2006-09-14 03:13:02 UTC (rev 18494)
+++ branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map_private.h	2006-09-14 03:15:30 UTC (rev 18495)
@@ -75,6 +75,7 @@
 
 const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr);
 const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr);
+int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs);
 
 struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, struct ldb_val val);
 struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, struct ldb_val val);



More information about the samba-cvs mailing list