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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 2006
+   Copyright (C) Andrew Bartlett <[EMAIL PROTECTED]> 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);

Reply via email to