Author: mkhl
Date: 2006-08-10 15:07:55 +0000 (Thu, 10 Aug 2006)
New Revision: 17479

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

Log:
Merge from mainline, r17478
Modified:
   branches/SOC/mkhl/ldb-map/common/ldb_modules.c
   branches/SOC/mkhl/ldb-map/include/ldb.h
   branches/SOC/mkhl/ldb-map/include/ldb_private.h
   branches/SOC/mkhl/ldb-map/samba/ldif_handlers.c
   branches/SOC/mkhl/ldb-map/tools/cmdline.c
   branches/SOC/mkhl/samdb-map/ldb_modules/partition.c


Changeset:
Modified: branches/SOC/mkhl/ldb-map/common/ldb_modules.c
===================================================================
--- branches/SOC/mkhl/ldb-map/common/ldb_modules.c      2006-08-10 11:51:43 UTC 
(rev 17478)
+++ branches/SOC/mkhl/ldb-map/common/ldb_modules.c      2006-08-10 15:07:55 UTC 
(rev 17479)
@@ -73,7 +73,7 @@
 /* modules are called in inverse order on the stack.
    Lets place them as an admin would think the right order is.
    Modules order is important */
-static const char **ldb_modules_list_from_string(struct ldb_context *ldb, 
TALLOC_CTX *mem_ctx, const char *string)
+const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX 
*mem_ctx, const char *string)
 {
        char **modules = NULL;
        const char **m;
@@ -95,6 +95,7 @@
        talloc_steal(modules, modstr);
 
        i = 0;
+       /* The str*r*chr walks backwards:  This is how we get the inverse order 
mentioned above */
        while ((p = strrchr(modstr, ',')) != NULL) {
                *p = '\0';
                p++;
@@ -236,11 +237,63 @@
 #endif
 }
 
+int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, 
struct ldb_module *backend, struct ldb_module **out)
+{
+       struct ldb_module *module;
+       int i;
+       
+       module = backend;
+
+       for (i = 0; module_list[i] != NULL; i++) {
+               struct ldb_module *current;
+               const struct ldb_module_ops *ops;
+               
+               ops = ldb_find_module_ops(module_list[i]);
+               if (ops == NULL) {
+                       if (ldb_try_load_dso(ldb, module_list[i]) == 0) {
+                               ops = ldb_find_module_ops(module_list[i]);
+                       }
+               }
+               
+               if (ops == NULL) {
+                       ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] 
not found\n", 
+                                 module_list[i]);
+                       continue;
+               }
+               
+               current = talloc_zero(ldb, struct ldb_module);
+               if (current == NULL) {
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
+               
+               current->ldb = ldb;
+               current->ops = ops;
+               
+               DLIST_ADD(module, current);
+       }
+       *out = module;
+       return LDB_SUCCESS;
+}
+
+int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module) 
+{
+       while (module && module->ops->init_context == NULL) 
+               module = module->next;
+
+       if (module && module->ops->init_context &&
+               module->ops->init_context(module) != LDB_SUCCESS) {
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "module initialization 
failed\n");
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       return LDB_SUCCESS;
+}
+
 int ldb_load_modules(struct ldb_context *ldb, const char *options[])
 {
        const char **modules = NULL;
-       struct ldb_module *module;
        int i;
+       int ret;
        TALLOC_CTX *mem_ctx = talloc_new(ldb);
        if (!mem_ctx) {
                return LDB_ERR_OPERATIONS_ERROR;
@@ -259,7 +312,6 @@
 
        /* if not overloaded by options and the backend is not ldap try to load 
the modules list from ldb */
        if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 
0)) { 
-               int ret;
                const char * const attrs[] = { "@LIST" , NULL};
                struct ldb_result *res = NULL;
                struct ldb_dn *mods_dn;
@@ -295,51 +347,16 @@
        }
 
        if (modules != NULL) {
-               for (i = 0; modules[i] != NULL; i++) {
-                       struct ldb_module *current;
-                       const struct ldb_module_ops *ops;
-                               
-                       ops = ldb_find_module_ops(modules[i]);
-                       if (ops == NULL) {
-                               if (ldb_try_load_dso(ldb, modules[i]) == 0) {
-                                       ops = ldb_find_module_ops(modules[i]);
-                               }
-                       }
-                       
-                       if (ops == NULL) {
-                               ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: 
Module [%s] not found\n", 
-                                         modules[i]);
-                               continue;
-                       }
-
-                       current = talloc_zero(ldb, struct ldb_module);
-                       if (current == NULL) {
-                               return -1;
-                       }
-
-                       current->ldb = ldb;
-                       current->ops = ops;
-               
-                       DLIST_ADD(ldb->modules, current);
+               ret = ldb_load_modules_list(ldb, modules, ldb->modules, 
&ldb->modules);
+               talloc_free(modules);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
                }
-
-               talloc_free(modules);
        } else {
                ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this 
database\n");
        }
 
-       module = ldb->modules;
-
-       while (module && module->ops->init_context == NULL) 
-               module = module->next;
-
-       if (module && module->ops->init_context &&
-               module->ops->init_context(module) != LDB_SUCCESS) {
-               ldb_debug(ldb, LDB_DEBUG_FATAL, "module initialization 
failed\n");
-               return -1;
-       }
-
-       return 0; 
+       return ldb_init_module_chain(ldb, ldb->modules);
 }
 
 /*

Modified: branches/SOC/mkhl/ldb-map/include/ldb.h
===================================================================
--- branches/SOC/mkhl/ldb-map/include/ldb.h     2006-08-10 11:51:43 UTC (rev 
17478)
+++ branches/SOC/mkhl/ldb-map/include/ldb.h     2006-08-10 15:07:55 UTC (rev 
17479)
@@ -451,6 +451,13 @@
 #define LDB_CONTROL_NOTIFICATION_OID   "1.2.840.113556.1.4.528"
 
 /**
+   OID for getting deleted objects
+
+   \sa <a 
href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_show_deleted_oid.asp";>Microsoft
 documentation of this OID</a>
+*/
+#define LDB_CONTROL_SHOW_DELETED_OID   "1.2.840.113556.1.4.417"
+
+/**
    OID for extended DN
 
    \sa <a 
href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_extended_dn_oid.asp";>Microsoft
 documentation of this OID</a>
@@ -516,6 +523,14 @@
 #define LDB_CONTROL_VLV_RESP_OID       "2.16.840.1.113730.3.4.10"
 
 /**
+   OID to let modifies don't give an error when adding an existing
+   attribute with the same value or deleting an nonexisting one attribute
+
+   \sa <a 
href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_permissive_modify_oid.asp";>Microsoft
 documentation of this OID</a>
+*/
+#define LDB_CONTROL_PERMISSIVE_MODIFY_OID      "1.2.840.113556.1.4.1413"
+
+/**
    OID for LDAP Extended Operation START_TLS.
 
    This Extended operation is used to start a new TLS

Modified: branches/SOC/mkhl/ldb-map/include/ldb_private.h
===================================================================
--- branches/SOC/mkhl/ldb-map/include/ldb_private.h     2006-08-10 11:51:43 UTC 
(rev 17478)
+++ branches/SOC/mkhl/ldb-map/include/ldb_private.h     2006-08-10 15:07:55 UTC 
(rev 17479)
@@ -137,7 +137,10 @@
 
 /* The following definitions come from lib/ldb/common/ldb_modules.c  */
 
+const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX 
*mem_ctx, const char *string);
+int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, 
struct ldb_module *backend, struct ldb_module **out);
 int ldb_load_modules(struct ldb_context *ldb, const char *options[]);
+int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module);
 int ldb_next_request(struct ldb_module *module, struct ldb_request *request);
 int ldb_next_start_trans(struct ldb_module *module);
 int ldb_next_end_trans(struct ldb_module *module);

Modified: branches/SOC/mkhl/ldb-map/samba/ldif_handlers.c
===================================================================
--- branches/SOC/mkhl/ldb-map/samba/ldif_handlers.c     2006-08-10 11:51:43 UTC 
(rev 17478)
+++ branches/SOC/mkhl/ldb-map/samba/ldif_handlers.c     2006-08-10 15:07:55 UTC 
(rev 17479)
@@ -414,6 +414,54 @@
                .comparison_fn   = ldb_comparison_objectGUID
        },
        { 
+               .attr            = "parentGUID",
+               .flags           = 0,
+               .ldif_read_fn    = ldif_read_objectGUID,
+               .ldif_write_fn   = ldif_write_objectGUID,
+               .canonicalise_fn = ldb_canonicalise_objectGUID,
+               .comparison_fn   = ldb_comparison_objectGUID
+       },
+       { 
+               .attr            = "siteGUID",
+               .flags           = 0,
+               .ldif_read_fn    = ldif_read_objectGUID,
+               .ldif_write_fn   = ldif_write_objectGUID,
+               .canonicalise_fn = ldb_canonicalise_objectGUID,
+               .comparison_fn   = ldb_comparison_objectGUID
+       },
+       { 
+               .attr            = "pKTGUID",
+               .flags           = 0,
+               .ldif_read_fn    = ldif_read_objectGUID,
+               .ldif_write_fn   = ldif_write_objectGUID,
+               .canonicalise_fn = ldb_canonicalise_objectGUID,
+               .comparison_fn   = ldb_comparison_objectGUID
+       },
+       { 
+               .attr            = "fRSVersionGUID",
+               .flags           = 0,
+               .ldif_read_fn    = ldif_read_objectGUID,
+               .ldif_write_fn   = ldif_write_objectGUID,
+               .canonicalise_fn = ldb_canonicalise_objectGUID,
+               .comparison_fn   = ldb_comparison_objectGUID
+       },
+       { 
+               .attr            = "fRSReplicaSetGUID",
+               .flags           = 0,
+               .ldif_read_fn    = ldif_read_objectGUID,
+               .ldif_write_fn   = ldif_write_objectGUID,
+               .canonicalise_fn = ldb_canonicalise_objectGUID,
+               .comparison_fn   = ldb_comparison_objectGUID
+       },
+       { 
+               .attr            = "netbootGUID",
+               .flags           = 0,
+               .ldif_read_fn    = ldif_read_objectGUID,
+               .ldif_write_fn   = ldif_write_objectGUID,
+               .canonicalise_fn = ldb_canonicalise_objectGUID,
+               .comparison_fn   = ldb_comparison_objectGUID
+       },
+       { 
                .attr            = "objectCategory",
                .flags           = 0,
                .ldif_read_fn    = ldb_handler_copy,

Modified: branches/SOC/mkhl/ldb-map/tools/cmdline.c
===================================================================
--- branches/SOC/mkhl/ldb-map/tools/cmdline.c   2006-08-10 11:51:43 UTC (rev 
17478)
+++ branches/SOC/mkhl/ldb-map/tools/cmdline.c   2006-08-10 15:07:55 UTC (rev 
17479)
@@ -534,6 +534,48 @@
                        continue;
                }
 
+               if (strncmp(control_strings[i], "show_deleted:", 13) == 0) {
+                       const char *p;
+                       int crit, ret;
+
+                       p = &(control_strings[i][13]);
+                       ret = sscanf(p, "%d", &crit);
+                       if ((ret != 1) || (crit < 0) || (crit > 1)) {
+                               fprintf(stderr, "invalid show_deleted control 
syntax\n");
+                               fprintf(stderr, " syntax: crit(b)\n");
+                               fprintf(stderr, "   note: b = boolean\n");
+                               return NULL;
+                       }
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       ctrl[i]->oid = LDB_CONTROL_SHOW_DELETED_OID;
+                       ctrl[i]->critical = crit;
+                       ctrl[i]->data = NULL;
+
+                       continue;
+               }
+
+               if (strncmp(control_strings[i], "permissive_modify:", 18) == 0) 
{
+                       const char *p;
+                       int crit, ret;
+
+                       p = &(control_strings[i][18]);
+                       ret = sscanf(p, "%d", &crit);
+                       if ((ret != 1) || (crit < 0) || (crit > 1)) {
+                               fprintf(stderr, "invalid permissive_modify 
control syntax\n");
+                               fprintf(stderr, " syntax: crit(b)\n");
+                               fprintf(stderr, "   note: b = boolean\n");
+                               return NULL;
+                       }
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       ctrl[i]->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
+                       ctrl[i]->critical = crit;
+                       ctrl[i]->data = NULL;
+
+                       continue;
+               }
+
                /* no controls matched, throw an error */
                fprintf(stderr, "Invalid control name: '%s'\n", 
control_strings[i]);
                return NULL;

Modified: branches/SOC/mkhl/samdb-map/ldb_modules/partition.c
===================================================================
--- branches/SOC/mkhl/samdb-map/ldb_modules/partition.c 2006-08-10 11:51:43 UTC 
(rev 17478)
+++ branches/SOC/mkhl/samdb-map/ldb_modules/partition.c 2006-08-10 15:07:55 UTC 
(rev 17479)
@@ -502,11 +502,12 @@
 {
        int ret, i;
        TALLOC_CTX *mem_ctx = talloc_new(module);
-       static const char *attrs[] = { "partition", "replicateEntries", NULL };
+       static const char *attrs[] = { "partition", "replicateEntries", 
"modules", NULL };
        struct ldb_result *res;
        struct ldb_message *msg;
        struct ldb_message_element *partition_attributes;
        struct ldb_message_element *replicate_attributes;
+       struct ldb_message_element *modules_attributes;
 
        struct partition_private_data *data;
 
@@ -545,6 +546,7 @@
                ldb_set_errstring(module->ldb, 
                                  talloc_asprintf(module, "partition_init: "
                                                  "no partitions specified"));
+               talloc_free(mem_ctx);
                return LDB_ERR_CONSTRAINT_VIOLATION;
        }
        data->partitions = talloc_array(data, struct partition *, 
partition_attributes->num_values + 1);
@@ -559,6 +561,7 @@
                        ldb_set_errstring(module->ldb, 
                                          talloc_asprintf(module, 
"partition_init: "
                                                          "invalid form for 
partition record (missing ':'): %s", base));
+                       talloc_free(mem_ctx);
                        return LDB_ERR_CONSTRAINT_VIOLATION;
                }
                p[0] = '\0';
@@ -567,6 +570,7 @@
                        ldb_set_errstring(module->ldb, 
                                          talloc_asprintf(module, 
"partition_init: "
                                                          "invalid form for 
partition record (missing backend database): %s", base));
+                       talloc_free(mem_ctx);
                        return LDB_ERR_CONSTRAINT_VIOLATION;
                }
                data->partitions[i] = talloc(data->partitions, struct 
partition);
@@ -580,12 +584,14 @@
                        ldb_set_errstring(module->ldb, 
                                          talloc_asprintf(module, 
"partition_init: "
                                                          "invalid DN in 
partition record: %s", base));
+                       talloc_free(mem_ctx);
                        return LDB_ERR_CONSTRAINT_VIOLATION;
                }
 
                data->partitions[i]->backend = 
private_path(data->partitions[i], p);
                ret = ldb_connect_backend(module->ldb, 
data->partitions[i]->backend, NULL, &data->partitions[i]->module);
                if (ret != LDB_SUCCESS) {
+                       talloc_free(mem_ctx);
                        return ret;
                }
        }
@@ -600,6 +606,7 @@
                req = talloc_zero(mem_ctx, struct ldb_request);
                if (req == NULL) {
                        ldb_debug(module->ldb, LDB_DEBUG_ERROR, "partition: Out 
of memory!\n");
+                       talloc_free(mem_ctx);
                        return LDB_ERR_OPERATIONS_ERROR;
                }
                
@@ -609,6 +616,7 @@
                ret = ldb_request(module->ldb, req);
                if (ret != LDB_SUCCESS) {
                        ldb_debug(module->ldb, LDB_DEBUG_ERROR, "partition: 
Unable to register partition with rootdse!\n");
+                       talloc_free(mem_ctx);
                        return LDB_ERR_OTHER;
                }
                talloc_free(req);
@@ -616,9 +624,6 @@
 
        replicate_attributes = ldb_msg_find_element(msg, "replicateEntries");
        if (!replicate_attributes) {
-               ldb_set_errstring(module->ldb, 
-                                 talloc_asprintf(module, "partition_init: "
-                                                 "no entries to replicate 
specified"));
                data->replicate = NULL;
        } else {
                data->replicate = talloc_array(data, struct ldb_dn *, 
replicate_attributes->num_values + 1);
@@ -634,12 +639,78 @@
                                                  talloc_asprintf(module, 
"partition_init: "
                                                                  "invalid DN 
in partition replicate record: %s", 
                                                                  
replicate_attributes->values[i].data));
+                               talloc_free(mem_ctx);
                                return LDB_ERR_CONSTRAINT_VIOLATION;
                        }
                }
                data->replicate[i] = NULL;
        }
 
+       modules_attributes = ldb_msg_find_element(msg, "modules");
+       if (modules_attributes) {
+               for (i=0; i < modules_attributes->num_values; i++) {
+                       struct ldb_dn *base_dn;
+                       int partition_idx;
+                       struct partition *partition = NULL;
+                       const char **modules = NULL;
+
+                       char *base = talloc_strdup(data->partitions, (char 
*)modules_attributes->values[i].data);
+                       char *p = strchr(base, ':');
+                       if (!p) {
+                               ldb_set_errstring(module->ldb, 
+                                                 talloc_asprintf(mem_ctx, 
"partition_init: "
+                                                                 "invalid form 
for partition module record (missing ':'): %s", base));
+                               talloc_free(mem_ctx);
+                               return LDB_ERR_CONSTRAINT_VIOLATION;
+                       }
+                       p[0] = '\0';
+                       p++;
+                       if (!p[0]) {
+                               ldb_set_errstring(module->ldb, 
+                                                 talloc_asprintf(mem_ctx, 
"partition_init: "
+                                                                 "invalid form 
for partition module record (missing backend database): %s", base));
+                               talloc_free(mem_ctx);
+                               return LDB_ERR_CONSTRAINT_VIOLATION;
+                       }
+
+                       modules = ldb_modules_list_from_string(module->ldb, 
mem_ctx,
+                                                              p);
+                       
+                       base_dn = ldb_dn_explode(mem_ctx, base);
+                       if (!base_dn) {
+                               talloc_free(mem_ctx);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+                       
+                       for (partition_idx = 0; 
data->partitions[partition_idx]; partition_idx++) {
+                               if (ldb_dn_compare(module->ldb, 
data->partitions[partition_idx]->dn, 
+                                                  base_dn) == 0) {
+                                       partition = 
data->partitions[partition_idx];
+                                       break;
+                               }
+                       }
+                       
+                       if (!partition) {
+                               ldb_set_errstring(module->ldb, 
+                                                 talloc_asprintf(mem_ctx, 
"partition_init: "
+                                                                 "invalid form 
for partition module record (no such partition): %s", base));
+                               talloc_free(mem_ctx);
+                               return LDB_ERR_CONSTRAINT_VIOLATION;
+                       }
+                       
+                       ret = ldb_load_modules_list(module->ldb, modules, 
partition->module, &partition->module);
+                       if (ret != LDB_SUCCESS) {
+                               talloc_free(mem_ctx);
+                               return ret;
+                       }
+                       ret = ldb_init_module_chain(module->ldb, 
partition->module);
+                       if (ret != LDB_SUCCESS) {
+                               talloc_free(mem_ctx);
+                               return ret;
+                       }
+               }
+       }
+
        module->private_data = data;
        talloc_steal(module, data);
        

Reply via email to