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);
