diff options
Diffstat (limited to 'source4/lib')
25 files changed, 884 insertions, 491 deletions
diff --git a/source4/lib/gendb.c b/source4/lib/gendb.c index e0fb9662bb..0aeacbe701 100644 --- a/source4/lib/gendb.c +++ b/source4/lib/gendb.c @@ -23,6 +23,7 @@ #include "includes.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" /* search the sam for the specified attributes - va_list variant @@ -30,14 +31,15 @@ int gendb_search_v(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_dn *basedn, - struct ldb_message ***res, + struct ldb_message ***msgs, const char * const *attrs, const char *format, va_list ap) _PRINTF_ATTRIBUTE(6,0) { enum ldb_scope scope = LDB_SCOPE_SUBTREE; + struct ldb_result *res; char *expr = NULL; - int count; + int ret; if (format) { vasprintf(&expr, format, ap); @@ -48,20 +50,28 @@ int gendb_search_v(struct ldb_context *ldb, scope = LDB_SCOPE_BASE; } - *res = NULL; + res = NULL; + + ret = ldb_search(ldb, basedn, scope, expr, attrs, &res); + + if (ret == LDB_SUCCESS) { + talloc_steal(mem_ctx, res); - count = ldb_search(ldb, basedn, scope, expr, attrs, res); + DEBUG(4,("gendb_search_v: %s %s -> %d\n", + basedn?ldb_dn_linearize(mem_ctx,basedn):"NULL", + expr?expr:"NULL", res->count)); - if (*res) talloc_steal(mem_ctx, *res); + ret = res->count; + *msgs = res->msgs; - DEBUG(4,("gendb_search_v: %s %s -> %d (%s)\n", - basedn?ldb_dn_linearize(mem_ctx,basedn):"NULL", - expr?expr:"NULL", count, - count==-1?ldb_errstring(ldb):"OK")); + } else { + DEBUG(4,("gendb_search_v: search failed: %s", ldb_errstring(ldb))); + ret = -1; + } free(expr); - return count; + return ret; } /* diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 791e66ea51..48911cad6b 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -172,6 +172,52 @@ int ldb_transaction_cancel(struct ldb_context *ldb) } /* + check for an error return from an op + if an op fails, but has not setup an error string, then setup one now +*/ +static int ldb_op_finish(struct ldb_context *ldb, int status) +{ + if (status == LDB_SUCCESS) { + return ldb_transaction_commit(ldb); + } + if (ldb->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_set_errstring(ldb->modules, + talloc_asprintf(ldb, "ldb error %d", status)); + } + ldb_transaction_cancel(ldb); + return status; +} + +/* + start an ldb request + autostarts a transacion if none active and the operation is not a search + returns -1 on errors. +*/ + +int ldb_request(struct ldb_context *ldb, struct ldb_request *request) +{ + int status; + + ldb_reset_err_string(ldb); + + if ((!ldb->transaction_active) && + (request->operation == LDB_REQ_ADD || + request->operation == LDB_REQ_MODIFY || + request->operation == LDB_REQ_DELETE || + request->operation == LDB_REQ_RENAME)) { + + status = ldb_transaction_start(ldb); + if (status != LDB_SUCCESS) return status; + + status = ldb->modules->ops->request(ldb->modules, request); + return ldb_op_finish(ldb, status); + } + + return ldb->modules->ops->request(ldb->modules, request); +} + +/* search the database given a LDAP-like search expression return the number of records found, or -1 on error @@ -183,61 +229,36 @@ int ldb_search(struct ldb_context *ldb, const struct ldb_dn *base, enum ldb_scope scope, const char *expression, - const char * const *attrs, struct ldb_message ***res) + const char * const *attrs, struct ldb_result **res) { + struct ldb_request *request; struct ldb_parse_tree *tree; int ret; + request = talloc(ldb, struct ldb_request); + if (request == NULL) { + ldb_set_errstring(ldb->modules, talloc_strdup(ldb, "Not Enough memory")); + return -1; + } + tree = ldb_parse_tree(ldb, expression); if (tree == NULL) { ldb_set_errstring(ldb->modules, talloc_strdup(ldb, "Unable to parse search expression")); return -1; } - ret = ldb_search_bytree(ldb, base, scope, tree, attrs, res); - talloc_free(tree); - - return ret; -} - -/* - search the database given a search tree - - return the number of records found, or -1 on error - - Use talloc_free to free the ldb_message returned in 'res' - -*/ -int ldb_search_bytree(struct ldb_context *ldb, - const struct ldb_dn *base, - enum ldb_scope scope, - struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_message ***res) -{ - struct ldb_module *module; - FIRST_OP(ldb, search_bytree); + request->operation = LDB_REQ_SEARCH; + request->op.search.base = base; + request->op.search.scope = scope; + request->op.search.tree = tree; + request->op.search.attrs = attrs; + request->op.search.res = res; - ldb_reset_err_string(ldb); + ret = ldb_request(ldb, request); - return module->ops->search_bytree(module, base, scope, tree, attrs, res); -} + talloc_free(tree); -/* - check for an error return from an op - if an op fails, but has not setup an error string, then setup one now -*/ -static int ldb_op_finish(struct ldb_context *ldb, int status) -{ - if (status == LDB_SUCCESS) { - return ldb_transaction_commit(ldb); - } - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_set_errstring(ldb->modules, - talloc_asprintf(ldb, "ldb error %d", status)); - } - ldb_transaction_cancel(ldb); - return status; + return ret; } /* @@ -247,25 +268,22 @@ static int ldb_op_finish(struct ldb_context *ldb, int status) int ldb_add(struct ldb_context *ldb, const struct ldb_message *message) { - struct ldb_module *module; + struct ldb_request *request; int status; - FIRST_OP(ldb, add_record); - - ldb_reset_err_string(ldb); - status = ldb_msg_sanity_check(message); if (status != LDB_SUCCESS) return status; - if (! ldb->transaction_active) { - status = ldb_transaction_start(ldb); - if (status != LDB_SUCCESS) return status; - - status = module->ops->add_record(module, message); - return ldb_op_finish(ldb, status); + request = talloc(ldb, struct ldb_request); + if (request == NULL) { + ldb_set_errstring(ldb->modules, talloc_strdup(ldb, "Not Enough memory")); + return -1; } - return module->ops->add_record(module, message); + request->operation = LDB_REQ_ADD; + request->op.add.message = message; + + return ldb_request(ldb, request); } /* @@ -274,25 +292,22 @@ int ldb_add(struct ldb_context *ldb, int ldb_modify(struct ldb_context *ldb, const struct ldb_message *message) { - struct ldb_module *module; + struct ldb_request *request; int status; - FIRST_OP(ldb, modify_record); - - ldb_reset_err_string(ldb); - status = ldb_msg_sanity_check(message); if (status != LDB_SUCCESS) return status; - if (! ldb->transaction_active) { - status = ldb_transaction_start(ldb); - if (status != LDB_SUCCESS) return status; - - status = module->ops->modify_record(module, message); - return ldb_op_finish(ldb, status); + request = talloc(ldb, struct ldb_request); + if (request == NULL) { + ldb_set_errstring(ldb->modules, talloc_strdup(ldb, "Not Enough memory")); + return -1; } - return module->ops->modify_record(module, message); + request->operation = LDB_REQ_MODIFY; + request->op.mod.message = message; + + return ldb_request(ldb, request); } @@ -301,22 +316,18 @@ int ldb_modify(struct ldb_context *ldb, */ int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn) { - struct ldb_module *module; - int status; - - FIRST_OP(ldb, delete_record); - - ldb_reset_err_string(ldb); - - if (! ldb->transaction_active) { - status = ldb_transaction_start(ldb); - if (status != LDB_SUCCESS) return status; + struct ldb_request *request; - status = module->ops->delete_record(module, dn); - return ldb_op_finish(ldb, status); + request = talloc(ldb, struct ldb_request); + if (request == NULL) { + ldb_set_errstring(ldb->modules, talloc_strdup(ldb, "Not Enough memory")); + return -1; } - return module->ops->delete_record(module, dn); + request->operation = LDB_REQ_DELETE; + request->op.del.dn = dn; + + return ldb_request(ldb, request); } /* @@ -324,22 +335,19 @@ int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn) */ int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn) { - struct ldb_module *module; - int status; - - FIRST_OP(ldb, rename_record); - - ldb_reset_err_string(ldb); - - if (! ldb->transaction_active) { - status = ldb_transaction_start(ldb); - if (status != LDB_SUCCESS) return status; + struct ldb_request *request; - status = module->ops->rename_record(module, olddn, newdn); - return ldb_op_finish(ldb, status); + request = talloc(ldb, struct ldb_request); + if (request == NULL) { + ldb_set_errstring(ldb->modules, talloc_strdup(ldb, "Not Enough memory")); + return -1; } - return module->ops->rename_record(module, olddn, newdn); + request->operation = LDB_REQ_RENAME; + request->op.rename.olddn = olddn; + request->op.rename.newdn = newdn; + + return ldb_request(ldb, request); } diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index f3ca4df9b4..91338c2e10 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -35,6 +35,7 @@ #include "includes.h" #include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" #include "ldb/include/ldb_private.h" #include "dlinklist.h" #include <sys/types.h> @@ -153,7 +154,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) { int ret; const char * const attrs[] = { "@LIST" , NULL}; - struct ldb_message **msg = NULL; + struct ldb_result *res = NULL; struct ldb_dn *mods; mods = ldb_dn_explode(ldb, "@MODULES"); @@ -161,27 +162,27 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) return -1; } - ret = ldb_search(ldb, mods, LDB_SCOPE_BASE, "", attrs, &msg); + ret = ldb_search(ldb, mods, LDB_SCOPE_BASE, "", attrs, &res); talloc_free(mods); - if (ret == 0 || (ret == 1 && msg[0]->num_elements == 0)) { + if (ret == LDB_SUCCESS && (res->count == 0 || res->msgs[0]->num_elements == 0)) { ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db\n"); } else { - if (ret < 0) { + if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out\n", ldb_errstring(ldb)); return -1; } - if (ret > 1) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out\n", ret); - talloc_free(msg); + if (res->count > 1) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out\n", res->count); + talloc_free(res); return -1; } modules = ldb_modules_list_from_string(ldb, - (const char *)msg[0]->elements[0].values[0].data); + (const char *)res->msgs[0]->elements[0].values[0].data); } - talloc_free(msg); + talloc_free(res); } if (modules == NULL) { @@ -228,58 +229,10 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) /* helper functions to call the next module in chain */ -int ldb_next_search_bytree(struct ldb_module *module, - const struct ldb_dn *base, - enum ldb_scope scope, - struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_message ***res) +int ldb_next_request(struct ldb_module *module, struct ldb_request *request) { - FIND_OP(module, search_bytree); - return module->ops->search_bytree(module, base, scope, tree, attrs, res); -} - -int ldb_next_search(struct ldb_module *module, - const struct ldb_dn *base, - enum ldb_scope scope, - const char *expression, - const char * const *attrs, struct ldb_message ***res) -{ - struct ldb_parse_tree *tree; - int ret; - FIND_OP(module, search_bytree); - tree = ldb_parse_tree(module, expression); - if (tree == NULL) { - ldb_set_errstring(module, talloc_strdup(module, "Unable to parse search expression")); - return -1; - } - ret = module->ops->search_bytree(module, base, scope, tree, attrs, res); - talloc_free(tree); - return ret; -} - - -int ldb_next_add_record(struct ldb_module *module, const struct ldb_message *message) -{ - FIND_OP(module, add_record); - return module->ops->add_record(module, message); -} - -int ldb_next_modify_record(struct ldb_module *module, const struct ldb_message *message) -{ - FIND_OP(module, modify_record); - return module->ops->modify_record(module, message); -} - -int ldb_next_delete_record(struct ldb_module *module, const struct ldb_dn *dn) -{ - FIND_OP(module, delete_record); - return module->ops->delete_record(module, dn); -} - -int ldb_next_rename_record(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn) -{ - FIND_OP(module, rename_record); - return module->ops->rename_record(module, olddn, newdn); + FIND_OP(module, request); + return module->ops->request(module, request); } int ldb_next_start_trans(struct ldb_module *module) diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 98a5113390..86e6a021da 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -253,6 +253,65 @@ struct ldb_attrib_handler { #define LDB_SYNTAX_UTC_TIME "1.3.6.1.4.1.1466.115.121.1.53" #define LDB_SYNTAX_OBJECTCLASS "LDB_SYNTAX_OBJECTCLASS" +struct ldb_controls; +struct ldb_credentials; + +enum ldb_request_type { + LDB_REQ_SEARCH, + LDB_REQ_ADD, + LDB_REQ_MODIFY, + LDB_REQ_DELETE, + LDB_REQ_RENAME +}; + +struct ldb_result { + unsigned int count; + struct ldb_message **msgs; +}; + +struct ldb_search { + const struct ldb_dn *base; + enum ldb_scope scope; + struct ldb_parse_tree *tree; + const char * const *attrs; + struct ldb_result **res; +}; + +struct ldb_add { + const struct ldb_message *message; +}; + +struct ldb_modify { + const struct ldb_message *message; +}; + +struct ldb_delete { + const struct ldb_dn *dn; +}; + +struct ldb_rename { + const struct ldb_dn *olddn; + const struct ldb_dn *newdn; +}; + +struct ldb_request { + + int operation; + + union { + struct ldb_search search; + struct ldb_add add; + struct ldb_modify mod; + struct ldb_delete del; + struct ldb_rename rename; + } op; + + struct ldb_controls *controls; + struct ldb_credentials *creds; +}; + +int ldb_request(struct ldb_context *ldb, struct ldb_request *request); + /* initialise a ldb context */ @@ -281,7 +340,7 @@ int ldb_search(struct ldb_context *ldb, const struct ldb_dn *base, enum ldb_scope scope, const char *expression, - const char * const *attrs, struct ldb_message ***res); + const char * const *attrs, struct ldb_result **res); /* like ldb_search() but takes a parse tree @@ -290,7 +349,7 @@ int ldb_search_bytree(struct ldb_context *ldb, const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_message ***res); + const char * const *attrs, struct ldb_result **res); /* add a record to the database. Will fail if a record with the given class and key diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index 7b31bf1e31..94ee10860b 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -56,12 +56,7 @@ struct ldb_module { */ struct ldb_module_ops { const char *name; - int (*search_bytree)(struct ldb_module *, const struct ldb_dn *, enum ldb_scope, - struct ldb_parse_tree *, const char * const [], struct ldb_message ***); - int (*add_record)(struct ldb_module *, const struct ldb_message *); - int (*modify_record)(struct ldb_module *, const struct ldb_message *); - int (*delete_record)(struct ldb_module *, const struct ldb_dn *); - int (*rename_record)(struct ldb_module *, const struct ldb_dn *, const struct ldb_dn *); + int (*request)(struct ldb_module *, struct ldb_request *); int (*start_transaction)(struct ldb_module *); int (*end_transaction)(struct ldb_module *); int (*del_transaction)(struct ldb_module *); @@ -123,20 +118,7 @@ typedef struct ldb_module *(*ldb_module_init_function)(struct ldb_context *ldb, /* The following definitions come from lib/ldb/common/ldb_modules.c */ int ldb_load_modules(struct ldb_context *ldb, const char *options[]); -int ldb_next_search(struct ldb_module *module, - const struct ldb_dn *base, - enum ldb_scope scope, - const char *expression, - const char * const *attrs, struct ldb_message ***res); -int ldb_next_search_bytree(struct ldb_module *module, - const struct ldb_dn *base, - enum ldb_scope scope, - struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_message ***res); -int ldb_next_add_record(struct ldb_module *module, const struct ldb_message *message); -int ldb_next_modify_record(struct ldb_module *module, const struct ldb_message *message); -int ldb_next_delete_record(struct ldb_module *module, const struct ldb_dn *dn); -int ldb_next_rename_record(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn); +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); int ldb_next_del_trans(struct ldb_module *module); diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c index 06ff79b9a0..cc9b5e65db 100644 --- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c +++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c @@ -148,7 +148,7 @@ static void ildb_rootdse(struct ldb_module *module); */ static int ildb_search_bytree(struct ldb_module *module, const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_message ***res) + const char * const *attrs, struct ldb_result **res) { struct ildb_private *ildb = module->private_data; int count, i; @@ -176,34 +176,46 @@ static int ildb_search_bytree(struct ldb_module *module, const struct ldb_dn *ba } if (search_base == NULL) { ldb_set_errstring(module, talloc_asprintf(module, "Unable to determine baseDN")); - return -1; + return LDB_ERR_OTHER; } if (tree == NULL) { ldb_set_errstring(module, talloc_asprintf(module, "Invalid expression parse tree")); - return -1; + return LDB_ERR_OTHER; } + (*res) = talloc(ildb, struct ldb_result); + if (! *res) { + return LDB_ERR_OTHER; + } + (*res)->count = 0; + (*res)->msgs = NULL; + status = ildap_search_bytree(ildb->ldap, search_base, scope, tree, attrs, 0, &ldapres); talloc_free(search_base); if (!NT_STATUS_IS_OK(status)) { ildb_map_error(ildb, status); - return -1; + return LDB_ERR_OTHER; } count = ildap_count_entries(ildb->ldap, ldapres); - if (count == -1 || count == 0) { + if (count == -1) { talloc_free(ldapres); - return count; + return LDB_ERR_OTHER; } - (*res) = talloc_array(ildb, struct ldb_message *, count+1); - if (! *res) { + if (count == 0) { talloc_free(ldapres); - return -1; + return LDB_SUCCESS; + } + + (*res)->msgs = talloc_array(*res, struct ldb_message *, count + 1); + if (! (*res)->msgs) { + talloc_free(ldapres); + return LDB_ERR_OTHER; } - (*res)[0] = NULL; + (*res)->msgs[0] = NULL; /* loop over all messages */ for (i=0;i<count;i++) { @@ -212,28 +224,29 @@ static int ildb_search_bytree(struct ldb_module *module, const struct ldb_dn *ba msg = ldapres[i]; search = &msg->r.SearchResultEntry; - (*res)[i] = talloc(*res, struct ldb_message); - if (!(*res)[i]) { + (*res)->msgs[i] = talloc(*res, struct ldb_message); + if (!(*res)->msgs[i]) { goto failed; } - (*res)[i+1] = NULL; + (*res)->msgs[i+1] = NULL; - (*res)[i]->dn = ldb_dn_explode((*res)[i], search->dn); - if ((*res)[i]->dn == NULL) { + (*res)->msgs[i]->dn = ldb_dn_explode((*res)->msgs[i], search->dn); + if ((*res)->msgs[i]->dn == NULL) { goto failed; } - (*res)[i]->num_elements = search->num_attributes; - (*res)[i]->elements = talloc_steal((*res)[i], search->attributes); - (*res)[i]->private_data = NULL; + (*res)->msgs[i]->num_elements = search->num_attributes; + (*res)->msgs[i]->elements = talloc_steal((*res)->msgs[i], search->attributes); + (*res)->msgs[i]->private_data = NULL; } talloc_free(ldapres); - return count; + (*res)->count = count; + return LDB_SUCCESS; failed: if (*res) talloc_free(*res); - return -1; + return LDB_ERR_OTHER; } @@ -384,13 +397,41 @@ static int ildb_del_trans(struct ldb_module *module) return 0; } +static int ildb_request(struct ldb_module *module, struct ldb_request *req) +{ + switch (req->operation) { + + case LDB_REQ_SEARCH: + return ildb_search_bytree(module, + req->op.search.base, + req->op.search.scope, + req->op.search.tree, + req->op.search.attrs, + req->op.search.res); + + case LDB_REQ_ADD: + return ildb_add(module, req->op.add.message); + + case LDB_REQ_MODIFY: + return ildb_modify(module, req->op.mod.message); + + case LDB_REQ_DELETE: + return ildb_delete(module, req->op.del.dn); + + case LDB_REQ_RENAME: + return ildb_rename(module, + req->op.rename.olddn, + req->op.rename.newdn); + + default: + return -1; + + } +} + static const struct ldb_module_ops ildb_ops = { .name = "ldap", - .search_bytree = ildb_search_bytree, - .add_record = ildb_add, - .modify_record = ildb_modify, - .delete_record = ildb_delete, - .rename_record = ildb_rename, + .request = ildb_request, .start_transaction = ildb_start_trans, .end_transaction = ildb_end_trans, .del_transaction = ildb_del_trans @@ -403,16 +444,16 @@ static const struct ldb_module_ops ildb_ops = { static void ildb_rootdse(struct ldb_module *module) { struct ildb_private *ildb = module->private_data; - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; struct ldb_dn *empty_dn = ldb_dn_new(ildb); int ret; ret = ildb_search_bytree(module, empty_dn, LDB_SCOPE_BASE, ldb_parse_tree(empty_dn, "dn=dc=rootDSE"), NULL, &res); - if (ret == 1) { - ildb->rootDSE = talloc_steal(ildb, res[0]); + if (ret == LDB_SUCCESS && res->count == 1) { + ildb->rootDSE = talloc_steal(ildb, res->msgs[0]); } - if (ret != -1) talloc_free(res); + if (ret == LDB_SUCCESS) talloc_free(res); talloc_free(empty_dn); } diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index 268e2b0291..893ad0dd2a 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -34,6 +34,7 @@ #include "includes.h" #include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" #include "ldb/include/ldb_private.h" #include "ldb/ldb_ldap/ldb_ldap.h" @@ -176,7 +177,7 @@ static int lldb_add_msg_attr(struct ldb_context *ldb, */ static int lldb_search_bytree(struct ldb_module *module, const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_message ***res) + const char * const *attrs, struct ldb_result **res) { struct ldb_context *ldb = module->ldb; struct lldb_private *lldb = module->private_data; @@ -211,6 +212,14 @@ static int lldb_search_bytree(struct ldb_module *module, const struct ldb_dn *ba break; } + (*res) = talloc(lldb, struct ldb_result); + if (! *res) { + errno = ENOMEM; + return LDB_ERR_OTHER; + } + (*res)->count = 0; + (*res)->msgs = NULL; + lldb->last_rc = ldap_search_s(lldb->ldap, search_base, ldap_scope, expression, discard_const_p(char *, attrs), @@ -218,23 +227,24 @@ static int lldb_search_bytree(struct ldb_module *module, const struct ldb_dn *ba talloc_free(search_base); if (lldb->last_rc != LDAP_SUCCESS) { ldb_set_errstring(module, talloc_strdup(module, ldap_err2string(lldb->last_rc))); - return -1; + return lldb->last_rc; } count = ldap_count_entries(lldb->ldap, ldapres); if (count == -1 || count == 0) { ldap_msgfree(ldapres); - return count; + return LDB_SUCCESS; } - (*res) = talloc_array(lldb, struct ldb_message *, count+1); - if (! *res) { + (*res)->msgs = talloc_array(*res, struct ldb_message *, count+1); + if (! (*res)->msgs) { ldap_msgfree(ldapres); + talloc_free(*res); errno = ENOMEM; - return -1; + return LDB_ERR_OTHER; } - (*res)[0] = NULL; + (*res)->msgs[0] = NULL; msg_count = 0; @@ -251,27 +261,27 @@ static int lldb_search_bytree(struct ldb_module *module, const struct ldb_dn *ba break; } - (*res)[msg_count] = talloc(*res, struct ldb_message); - if (!(*res)[msg_count]) { + (*res)->msgs[msg_count] = talloc((*res)->msgs, struct ldb_message); + if (!(*res)->msgs[msg_count]) { goto failed; } - (*res)[msg_count+1] = NULL; + (*res)->msgs[msg_count+1] = NULL; dn = ldap_get_dn(lldb->ldap, msg); if (!dn) { goto failed; } - (*res)[msg_count]->dn = ldb_dn_explode((*res)[msg_count], dn); + (*res)->msgs[msg_count]->dn = ldb_dn_explode((*res)->msgs[msg_count], dn); ldap_memfree(dn); - if (!(*res)[msg_count]->dn) { + if (!(*res)->msgs[msg_count]->dn) { goto failed; } - (*res)[msg_count]->num_elements = 0; - (*res)[msg_count]->elements = NULL; - (*res)[msg_count]->private_data = NULL; + (*res)->msgs[msg_count]->num_elements = 0; + (*res)->msgs[msg_count]->elements = NULL; + (*res)->msgs[msg_count]->private_data = NULL; /* loop over all attributes */ for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr); @@ -281,7 +291,7 @@ static int lldb_search_bytree(struct ldb_module *module, const struct ldb_dn *ba bval = ldap_get_values_len(lldb->ldap, msg, attr); if (bval) { - lldb_add_msg_attr(ldb, (*res)[msg_count], attr, bval); + lldb_add_msg_attr(ldb, (*res)->msgs[msg_count], attr, bval); ldap_value_free_len(bval); } @@ -294,11 +304,12 @@ static int lldb_search_bytree(struct ldb_module *module, const struct ldb_dn *ba ldap_msgfree(ldapres); - return msg_count; + (*res)->count = msg_count; + return LDB_SUCCESS; failed: if (*res) talloc_free(*res); - return -1; + return LDB_ERR_OTHER; } @@ -470,13 +481,41 @@ static int lldb_del_trans(struct ldb_module *module) return 0; } +static int lldb_request(struct ldb_module *module, struct ldb_request *req) +{ + switch (req->operation) { + + case LDB_REQ_SEARCH: + return lldb_search_bytree(module, + req->op.search.base, + req->op.search.scope, + req->op.search.tree, + req->op.search.attrs, + req->op.search.res); + + case LDB_REQ_ADD: + return lldb_add(module, req->op.add.message); + + case LDB_REQ_MODIFY: + return lldb_modify(module, req->op.mod.message); + + case LDB_REQ_DELETE: + return lldb_delete(module, req->op.del.dn); + + case LDB_REQ_RENAME: + return lldb_rename(module, + req->op.rename.olddn, + req->op.rename.newdn); + + default: + return -1; + + } +} + static const struct ldb_module_ops lldb_ops = { .name = "ldap", - .search_bytree = lldb_search_bytree, - .add_record = lldb_add, - .modify_record = lldb_modify, - .delete_record = lldb_delete, - .rename_record = lldb_rename, + .request = lldb_request, .start_transaction = lldb_start_trans, .end_transaction = lldb_end_trans, .del_transaction = lldb_del_trans diff --git a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c index 1054722178..1d23478941 100644 --- a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c +++ b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c @@ -810,7 +810,7 @@ done: /* search for matching records, by tree */ static int lsqlite3_search_bytree(struct ldb_module * module, const struct ldb_dn* basedn, enum ldb_scope scope, struct ldb_parse_tree * tree, - const char * const * attrs, struct ldb_message *** res) + const char * const * attrs, struct ldb_result ** res) { TALLOC_CTX *local_ctx; struct lsqlite3_private *lsqlite3 = module->private_data; @@ -973,21 +973,25 @@ static int lsqlite3_search_bytree(struct ldb_module * module, const struct ldb_d for (i = 0; i < msgs.count; i++) { msgs.msgs[i] = ldb_msg_canonicalize(module->ldb, msgs.msgs[i]); if (msgs.msgs[i] == NULL) { - ret = LDB_ERR_OTHER; goto failed; } } - *res = talloc_steal(module, msgs.msgs); - ret = msgs.count; + *res = talloc(module, struct ldb_result); + if (! *res) { + goto failed; + } + + (*res)->msgs = talloc_steal(*res, msgs.msgs); + (*res)->count = msgs.count; talloc_free(local_ctx); - return ret; + return LDB_SUCCESS; /* If error, return error code; otherwise return number of results */ failed: talloc_free(local_ctx); - return -1; + return LDB_ERR_OTHER; } @@ -1777,17 +1781,45 @@ destructor(void *p) } +static int lsqlite3_request(struct ldb_module *module, struct ldb_request *req) +{ + switch (req->operation) { + + case LDB_REQ_SEARCH: + return lsqlite3_search_bytree(module, + req->op.search.base, + req->op.search.scope, + req->op.search.tree, + req->op.search.attrs, + req->op.search.res); + + case LDB_REQ_ADD: + return lsqlite3_add(module, req->op.add.message); + + case LDB_REQ_MODIFY: + return lsqlite3_modify(module, req->op.mod.message); + + case LDB_REQ_DELETE: + return lsqlite3_delete(module, req->op.del.dn); + + case LDB_REQ_RENAME: + return lsqlite3_rename(module, + req->op.rename.olddn, + req->op.rename.newdn); + + default: + return LDB_ERR_OPERATIONS_ERROR; + + } +} + /* * Table of operations for the sqlite3 backend */ static const struct ldb_module_ops lsqlite3_ops = { .name = "sqlite", - .search_bytree = lsqlite3_search_bytree, - .add_record = lsqlite3_add, - .modify_record = lsqlite3_modify, - .delete_record = lsqlite3_delete, - .rename_record = lsqlite3_rename, + .request = lsqlite3_request, .start_transaction = lsqlite3_start_trans, .end_transaction = lsqlite3_end_trans, .del_transaction = lsqlite3_del_trans diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index de9665cb4d..75514fac83 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -34,6 +34,7 @@ #include "includes.h" #include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" #include "ldb/include/ldb_private.h" #include "ldb/ldb_tdb/ldb_tdb.h" @@ -629,10 +630,9 @@ static int ldb_index_filter(struct ldb_module *module, struct ldb_parse_tree *tr const struct ldb_dn *base, enum ldb_scope scope, const struct dn_list *dn_list, - const char * const attrs[], struct ldb_message ***res) + const char * const attrs[], struct ldb_result *res) { unsigned int i; - int count = 0; for (i = 0; i < dn_list->count; i++) { struct ldb_message *msg; @@ -641,13 +641,13 @@ static int ldb_index_filter(struct ldb_module *module, struct ldb_parse_tree *tr msg = talloc(module, struct ldb_message); if (msg == NULL) { - return -1; + return LDB_ERR_OTHER; } dn = ldb_dn_explode(msg, dn_list->dn[i]); if (dn == NULL) { talloc_free(msg); - return -1; + return LDB_ERR_OTHER; } ret = ltdb_search_dn1(module, dn, msg); @@ -661,20 +661,20 @@ static int ldb_index_filter(struct ldb_module *module, struct ldb_parse_tree *tr if (ret == -1) { /* an internal error */ talloc_free(msg); - return -1; + return LDB_ERR_OTHER; } ret = 0; if (ldb_match_msg(module->ldb, msg, tree, base, scope) == 1) { - ret = ltdb_add_attr_results(module, msg, attrs, &count, res); + ret = ltdb_add_attr_results(module, msg, attrs, &(res->count), &(res->msgs)); } talloc_free(msg); if (ret != 0) { - return -1; + return LDB_ERR_OTHER; } } - return count; + return LDB_SUCCESS; } /* @@ -686,7 +686,7 @@ int ltdb_search_indexed(struct ldb_module *module, const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const attrs[], struct ldb_message ***res) + const char * const attrs[], struct ldb_result **res) { struct ltdb_private *ltdb = module->private_data; struct dn_list *dn_list; @@ -703,6 +703,13 @@ int ltdb_search_indexed(struct ldb_module *module, return -1; } + *res = talloc(module, struct ldb_result); + if (*res == NULL) { + return LDB_ERR_OTHER; + } + (*res)->count = 0; + (*res)->msgs = NULL; + if (scope == LDB_SCOPE_BASE) { /* with BASE searches only one DN can match */ dn_list->dn = talloc_array(dn_list, char *, 1); @@ -725,7 +732,7 @@ int ltdb_search_indexed(struct ldb_module *module, /* we've got a candidate list - now filter by the full tree and extract the needed attributes */ ret = ldb_index_filter(module, tree, base, scope, dn_list, - attrs, res); + attrs, *res); } talloc_free(dn_list); diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index 97f8a7d0be..01a87e00b1 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -299,7 +299,7 @@ static int ltdb_unlock_read(struct ldb_module *module) */ int ltdb_add_attr_results(struct ldb_module *module, struct ldb_message *msg, const char * const attrs[], - int *count, + unsigned int *count, struct ldb_message ***res) { struct ldb_context *ldb = module->ldb; @@ -339,8 +339,8 @@ struct ltdb_search_info { enum ldb_scope scope; const char * const *attrs; struct ldb_message **msgs; - int failures; - int count; + unsigned int failures; + unsigned int count; }; @@ -406,15 +406,22 @@ static int ltdb_search_full(struct ldb_module *module, const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const attrs[], struct ldb_message ***res) + const char * const attrs[], struct ldb_result **res) { struct ltdb_private *ltdb = module->private_data; - int ret, count; + struct ldb_result *result; + int ret; struct ltdb_search_info *sinfo; + result = talloc(ltdb, struct ldb_result); + if (result == NULL) { + return LDB_ERR_OTHER; + } + sinfo = talloc(ltdb, struct ltdb_search_info); if (sinfo == NULL) { - return -1; + talloc_free(result); + return LDB_ERR_OTHER; } sinfo->tree = tree; @@ -429,16 +436,18 @@ static int ltdb_search_full(struct ldb_module *module, ret = tdb_traverse_read(ltdb->tdb, search_func, sinfo); if (ret == -1) { + talloc_free(result); talloc_free(sinfo); return -1; } - *res = talloc_steal(ltdb, sinfo->msgs); - count = sinfo->count; + result->msgs = talloc_steal(result, sinfo->msgs); + result->count = sinfo->count; + *res = result; talloc_free(sinfo); - return count; + return LDB_SUCCESS; } @@ -448,7 +457,7 @@ static int ltdb_search_full(struct ldb_module *module, */ int ltdb_search_bytree(struct ldb_module *module, const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const attrs[], struct ldb_message ***res) + const char * const attrs[], struct ldb_result **res) { int ret; diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 5b2feb741b..d1e60e0f5d 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -733,13 +733,41 @@ static int ltdb_del_trans(struct ldb_module *module) return LDB_SUCCESS; } +static int ltdb_request(struct ldb_module *module, struct ldb_request *req) +{ + switch (req->operation) { + + case LDB_REQ_SEARCH: + return ltdb_search_bytree(module, + req->op.search.base, + req->op.search.scope, + req->op.search.tree, + req->op.search.attrs, + req->op.search.res); + + case LDB_REQ_ADD: + return ltdb_add(module, req->op.add.message); + + case LDB_REQ_MODIFY: + return ltdb_modify(module, req->op.mod.message); + + case LDB_REQ_DELETE: + return ltdb_delete(module, req->op.del.dn); + + case LDB_REQ_RENAME: + return ltdb_rename(module, + req->op.rename.olddn, + req->op.rename.newdn); + + default: + return LDB_ERR_OPERATIONS_ERROR; + + } +} + static const struct ldb_module_ops ltdb_ops = { .name = "tdb", - .search_bytree = ltdb_search_bytree, - .add_record = ltdb_add, - .modify_record = ltdb_modify, - .delete_record = ltdb_delete, - .rename_record = ltdb_rename, + .request = ltdb_request, .start_transaction = ltdb_start_trans, .end_transaction = ltdb_end_trans, .del_transaction = ltdb_del_trans diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 2819d865d3..54c58517bd 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -57,7 +57,7 @@ int ltdb_search_indexed(struct ldb_module *module, const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const attrs[], struct ldb_message ***res); + const char * const attrs[], struct ldb_result **res); int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg); int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg); int ltdb_reindex(struct ldb_module *module); @@ -81,11 +81,11 @@ void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg); int ltdb_search_dn1(struct ldb_module *module, const struct ldb_dn *dn, struct ldb_message *msg); int ltdb_add_attr_results(struct ldb_module *module, struct ldb_message *msg, const char * const attrs[], - int *count, + unsigned int *count, struct ldb_message ***res); int ltdb_search_bytree(struct ldb_module *module, const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const attrs[], struct ldb_message ***res); + const char * const attrs[], struct ldb_result **res); /* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c */ diff --git a/source4/lib/ldb/modules/ldb_map.c b/source4/lib/ldb/modules/ldb_map.c index 48aa7e2ef5..49261d155c 100644 --- a/source4/lib/ldb/modules/ldb_map.c +++ b/source4/lib/ldb/modules/ldb_map.c @@ -24,6 +24,7 @@ #include "includes.h" #include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" #include "ldb/include/ldb_private.h" #include "ldb/modules/ldb_map.h" @@ -687,8 +688,10 @@ static struct ldb_message *ldb_map_message_incoming(struct ldb_module *module, c /* rename a record */ -static int map_rename(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn) +static int map_rename(struct ldb_module *module, struct ldb_request *req) { + const struct ldb_dn *olddn = req->op.rename.olddn; + const struct ldb_dn *newdn = req->op.rename.newdn; struct ldb_map_context *privdat = map_get_privdat(module); struct ldb_dn *n_olddn, *n_newdn; int ret; @@ -699,9 +702,9 @@ static int map_rename(struct ldb_module *module, const struct ldb_dn *olddn, con ret = ldb_rename(privdat->mapped_ldb, n_olddn, n_newdn); if (ret != -1) { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Mapped record renamed"); - ldb_next_rename_record(module, olddn, newdn); + ldb_next_request(module, req); } else { - ret = ldb_next_rename_record(module, olddn, newdn); + ret = ldb_next_request(module, req); if (ret != -1) { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Fallback record renamed"); @@ -718,8 +721,9 @@ static int map_rename(struct ldb_module *module, const struct ldb_dn *olddn, con /* delete a record */ -static int map_delete(struct ldb_module *module, const struct ldb_dn *dn) +static int map_delete(struct ldb_module *module, struct ldb_request *req) { + const struct ldb_dn *dn = req->op.del.dn; struct ldb_map_context *privdat = map_get_privdat(module); struct ldb_dn *newdn; int ret; @@ -730,13 +734,15 @@ static int map_delete(struct ldb_module *module, const struct ldb_dn *dn) if (ret != -1) { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Mapped record deleted"); } else { - ret = ldb_next_delete_record(module, dn); + ret = ldb_next_request(module, req); if (ret != -1) { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Fallback record deleted"); } } - ldb_next_delete_record(module, newdn); + req->op.del.dn = newdn; + ret = ldb_next_request(module, req); + req->op.del.dn = dn; talloc_free(newdn); @@ -744,12 +750,11 @@ static int map_delete(struct ldb_module *module, const struct ldb_dn *dn) } /* search fallback database */ -static int map_search_fb(struct ldb_module *module, const struct ldb_dn *base, - enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_message ***res) +static int map_search_fb(struct ldb_module *module, struct ldb_request *req) { - int ret; + struct ldb_parse_tree *tree = req->op.search.tree; struct ldb_parse_tree t_and, t_not, t_present, *childs[2]; + int ret; char *ismapped; t_present.operation = LDB_OP_PRESENT; @@ -764,8 +769,10 @@ static int map_search_fb(struct ldb_module *module, const struct ldb_dn *base, t_and.operation = LDB_OP_AND; t_and.u.list.num_elements = 2; t_and.u.list.elements = childs; - - ret = ldb_next_search_bytree(module, base, scope, &t_and, attrs, res); + + req->op.search.tree = &t_and; + ret = ldb_next_request(module, req); + req->op.search.tree = tree; talloc_free(ismapped); @@ -773,13 +780,17 @@ static int map_search_fb(struct ldb_module *module, const struct ldb_dn *base, } /* Search in the database against which we are mapping */ -static int map_search_mp(struct ldb_module *module, const struct ldb_dn *base, - enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_message ***res) +static int map_search_mp(struct ldb_module *module, struct ldb_request *req) { + const struct ldb_dn *base = req->op.search.base; + enum ldb_scope scope = req->op.search.scope; + struct ldb_parse_tree *tree = req->op.search.tree; + const char * const *attrs = req->op.search.attrs; + struct ldb_result **res = req->op.search.res; + struct ldb_request new_req; struct ldb_parse_tree *new_tree; struct ldb_dn *new_base; - struct ldb_message **newres; + struct ldb_result *newres; const char **newattrs; int mpret, ret; struct ldb_map_context *privdat = map_get_privdat(module); @@ -801,15 +812,22 @@ static int map_search_mp(struct ldb_module *module, const struct ldb_dn *base, newattrs = ldb_map_attrs(module, attrs); new_base = map_local_dn(module, module, base); - mpret = ldb_search_bytree(privdat->mapped_ldb, new_base, scope, new_tree, newattrs, &newres); + memset((char *)&(new_req), 0, sizeof(new_req)); + new_req.operation = LDB_REQ_SEARCH; + new_req.op.search.base = new_base; + new_req.op.search.scope = scope; + new_req.op.search.tree = new_tree; + new_req.op.search.attrs = newattrs; + new_req.op.search.res = &newres; + mpret = ldb_request(privdat->mapped_ldb, req); talloc_free(new_base); talloc_free(new_tree); talloc_free(newattrs); - if (mpret == -1) { + if (mpret != LDB_SUCCESS) { ldb_set_errstring(module, talloc_strdup(module, ldb_errstring(privdat->mapped_ldb))); - return -1; + return mpret; } /* @@ -817,23 +835,34 @@ static int map_search_mp(struct ldb_module *module, const struct ldb_dn *base, - test if (full expression) is now true */ - *res = talloc_array(module, struct ldb_message *, mpret); + *res = talloc(module, struct ldb_result); + (*res)->msgs = talloc_array(module, struct ldb_message *, newres->count); + (*res)->count = newres->count; ret = 0; for (i = 0; i < mpret; i++) { + struct ldb_request mergereq; struct ldb_message *merged; - struct ldb_message **extrares = NULL; + struct ldb_result *extrares = NULL; int extraret; /* Always get special DN's from the fallback database */ - if (ldb_dn_is_special(newres[i]->dn)) + if (ldb_dn_is_special(newres->msgs[i]->dn)) continue; - merged = ldb_map_message_incoming(module, attrs, newres[i]); + merged = ldb_map_message_incoming(module, attrs, newres->msgs[i]); /* Merge with additional data from fallback database */ - extraret = ldb_next_search(module, merged->dn, LDB_SCOPE_BASE, "", NULL, &extrares); + memset((char *)&(mergereq), 0, sizeof(mergereq)); /* zero off the request structure */ + mergereq.operation = LDB_REQ_SEARCH; + mergereq.op.search.base = merged->dn; + mergereq.op.search.scope = LDB_SCOPE_BASE; + mergereq.op.search.tree = ldb_parse_tree(module, ""); + mergereq.op.search.attrs = NULL; + mergereq.op.search.res = &extrares; + + extraret = ldb_next_request(module, &mergereq); if (extraret == -1) { ldb_debug(module->ldb, LDB_DEBUG_ERROR, "Error searching for extra data!\n"); @@ -848,13 +877,13 @@ static int map_search_mp(struct ldb_module *module, const struct ldb_dn *base, if (extraret == 1) { int j; ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Extra data found for remote DN: %s", ldb_dn_linearize(merged, merged->dn)); - for (j = 0; j < extrares[0]->num_elements; j++) { - ldb_msg_add(merged, &(extrares[0]->elements[j]), extrares[0]->elements[j].flags); + for (j = 0; j < extrares->msgs[0]->num_elements; j++) { + ldb_msg_add(merged, &(extrares->msgs[0]->elements[j]), extrares->msgs[0]->elements[j].flags); } } if (ldb_match_msg(module->ldb, merged, tree, base, scope) != 0) { - (*res)[ret] = merged; + (*res)->msgs[ret] = merged; ret++; } else { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Discarded merged message because it did not match"); @@ -863,45 +892,51 @@ static int map_search_mp(struct ldb_module *module, const struct ldb_dn *base, talloc_free(newres); - return ret; + (*res)->count = ret; + return LDB_SUCCESS; } /* search for matching records using a ldb_parse_tree */ -static int map_search_bytree(struct ldb_module *module, const struct ldb_dn *base, - enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_message ***res) +static int map_search_bytree(struct ldb_module *module, struct ldb_request *req) { - struct ldb_message **fbres, **mpres = NULL; - int i; - int ret_fb, ret_mp; + const struct ldb_dn *base = req->op.search.base; + struct ldb_result **res = req->op.search.res; + struct ldb_result *fbres, *mpres = NULL; + int i, ret; - ret_fb = map_search_fb(module, base, scope, tree, attrs, &fbres); - if (ret_fb == -1) - return -1; + req->op.search.res = &fbres; + ret = map_search_fb(module, req); + req->op.search.res = res; + if (ret != LDB_SUCCESS) + return ret; /* special dn's are never mapped.. */ if (ldb_dn_is_special(base)) { *res = fbres; - return ret_fb; + return ret; } - ret_mp = map_search_mp(module, base, scope, tree, attrs, &mpres); - if (ret_mp == -1) { - return -1; + req->op.search.res = &mpres; + ret = map_search_mp(module, req); + req->op.search.res = res; + if (ret != LDB_SUCCESS) { + return ret; } /* Merge results */ - *res = talloc_array(module, struct ldb_message *, ret_fb + ret_mp); + *res = talloc(module, struct ldb_result); + (*res)->msgs = talloc_array(*res, struct ldb_message *, fbres->count + mpres->count); - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Merging %d mapped and %d fallback messages", ret_mp, ret_fb); + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Merging %d mapped and %d fallback messages", mpres->count, fbres->count); - for (i = 0; i < ret_fb; i++) (*res)[i] = fbres[i]; - for (i = 0; i < ret_mp; i++) (*res)[ret_fb+i] = mpres[i]; + for (i = 0; i < fbres->count; i++) (*res)->msgs[i] = fbres->msgs[i]; + for (i = 0; i < mpres->count; i++) (*res)->msgs[fbres->count + i] = mpres->msgs[i]; - return ret_fb + ret_mp; + (*res)->count = fbres->count + mpres->count; + return LDB_SUCCESS; } static int msg_contains_objectclass(const struct ldb_message *msg, const char *name) @@ -921,19 +956,20 @@ static int msg_contains_objectclass(const struct ldb_message *msg, const char *n /* add a record */ -static int map_add(struct ldb_module *module, const struct ldb_message *msg) +static int map_add(struct ldb_module *module, struct ldb_request *req) { - int ret; + const struct ldb_message *msg = req->op.add.message; struct ldb_map_context *privdat = map_get_privdat(module); struct ldb_message *fb, *mp; struct ldb_message_element *ocs; + int ret; int i; ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_add"); if (ldb_dn_is_special(msg->dn)) { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_add: Added fallback record"); - return ldb_next_add_record(module, msg); + return ldb_next_request(module, req); } mp = talloc_zero(module, struct ldb_message); @@ -981,7 +1017,7 @@ static int map_add(struct ldb_module *module, const struct ldb_message *msg) ocs = ldb_msg_find_element(mp, "objectClass"); if (ocs->num_values == 1) { /* Only top */ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_add: Added fallback record"); - return ldb_next_add_record(module, msg); + return ldb_next_request(module, req); } /* @@ -1098,7 +1134,10 @@ static int map_add(struct ldb_module *module, const struct ldb_message *msg) ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_add: Added mapped record"); ldb_msg_add_string(fb, "isMapped", "TRUE"); - ret = ldb_next_add_record(module, fb); + + req->op.add.message = fb; + ret = ldb_next_request(module, req); + req->op.add.message = msg; if (ret == -1) { ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Adding fallback record failed: %s", ldb_errstring(module->ldb)); return -1; @@ -1114,8 +1153,9 @@ static int map_add(struct ldb_module *module, const struct ldb_message *msg) /* modify a record */ -static int map_modify(struct ldb_module *module, const struct ldb_message *msg) +static int map_modify(struct ldb_module *module, struct ldb_request *req) { + const struct ldb_message *msg = req->op.mod.message; struct ldb_map_context *privdat = map_get_privdat(module); struct ldb_message *fb, *mp; struct ldb_message_element *elm; @@ -1125,7 +1165,7 @@ static int map_modify(struct ldb_module *module, const struct ldb_message *msg) ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_modify"); if (ldb_dn_is_special(msg->dn)) - return ldb_next_modify_record(module, msg); + return ldb_next_request(module, req); fb = talloc_zero(module, struct ldb_message); fb->dn = talloc_reference(fb, msg->dn); @@ -1217,11 +1257,16 @@ static int map_modify(struct ldb_module *module, const struct ldb_message *msg) if (fb->num_elements > 0) { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Modifying fallback record with %d elements", fb->num_elements); - fb_ret = ldb_next_modify_record(module, fb); + req->op.mod.message = fb; + fb_ret = ldb_next_request(module, req); if (fb_ret == -1) { ldb_msg_add_string(fb, "isMapped", "TRUE"); - fb_ret = ldb_next_add_record(module, fb); + req->operation = LDB_REQ_ADD; + req->op.add.message = fb; + fb_ret = ldb_next_request(module, req); + req->operation = LDB_REQ_MODIFY; } + req->op.mod.message = msg; } else fb_ret = 0; talloc_free(fb); @@ -1234,19 +1279,42 @@ static int map_modify(struct ldb_module *module, const struct ldb_message *msg) return (mp_ret == -1 || fb_ret == -1)?-1:0; } + +static int map_request(struct ldb_module *module, struct ldb_request *req) +{ + switch (req->operation) { + + case LDB_REQ_SEARCH: + return map_search_bytree(module, req); + + case LDB_REQ_ADD: + return map_add(module, req); + + case LDB_REQ_MODIFY: + return map_modify(module, req); + + case LDB_REQ_DELETE: + return map_delete(module, req); + + case LDB_REQ_RENAME: + return map_rename(module, req); + + default: + return ldb_next_request(module, req); + + } +} + + static const struct ldb_module_ops map_ops = { .name = "map", - .search_bytree = map_search_bytree, - .add_record = map_add, - .modify_record = map_modify, - .delete_record = map_delete, - .rename_record = map_rename + .request = map_request }; static char *map_find_url(struct ldb_context *ldb, const char *name) { const char * const attrs[] = { "@MAP_URL" , NULL}; - struct ldb_message **msg = NULL; + struct ldb_result *result = NULL; struct ldb_dn *mods; char *url; int ret; @@ -1257,16 +1325,16 @@ static char *map_find_url(struct ldb_context *ldb, const char *name) return NULL; } - ret = ldb_search(ldb, mods, LDB_SCOPE_BASE, "", attrs, &msg); + ret = ldb_search(ldb, mods, LDB_SCOPE_BASE, "", attrs, &result); talloc_free(mods); - if (ret < 1) { + if (ret != LDB_SUCCESS || result->count == 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Not enough results found looking for @MAP"); return NULL; } - url = talloc_strdup(ldb, ldb_msg_find_string(msg[0], "@MAP_URL", NULL)); + url = talloc_strdup(ldb, ldb_msg_find_string(result->msgs[0], "@MAP_URL", NULL)); - talloc_free(msg); + talloc_free(result); return url; } diff --git a/source4/lib/ldb/modules/operational.c b/source4/lib/ldb/modules/operational.c index 8a06e20c29..7c554e8541 100644 --- a/source4/lib/ldb/modules/operational.c +++ b/source4/lib/ldb/modules/operational.c @@ -76,6 +76,7 @@ #include "includes.h" #include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" #include "ldb/include/ldb_private.h" #include <time.h> @@ -174,23 +175,20 @@ failed: /* hook search operations */ -static int operational_search_bytree(struct ldb_module *module, - const struct ldb_dn *base, - enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const *attrs, - struct ldb_message ***res) +static int operational_search_bytree(struct ldb_module *module, struct ldb_request *req) { int i, r, a; int ret; + const char * const *attrs = req->op.search.attrs; const char **search_attrs = NULL; - (*res) = NULL; + *(req->op.search.res) = NULL; /* replace any attributes in the parse tree that are searchable, but are stored using a different name in the backend */ for (i=0;i<ARRAY_SIZE(parse_tree_sub);i++) { - ldb_parse_tree_attr_replace(tree, + ldb_parse_tree_attr_replace(req->op.search.tree, parse_tree_sub[i].attr, parse_tree_sub[i].replace); } @@ -213,18 +211,22 @@ static int operational_search_bytree(struct ldb_module *module, } } - + /* use new set of attrs if any */ + if (search_attrs) req->op.search.attrs = search_attrs; /* perform the search */ - ret = ldb_next_search_bytree(module, base, scope, tree, - search_attrs?search_attrs:attrs, res); - if (ret <= 0) { + ret = ldb_next_request(module, req); + /* set back saved attrs if needed */ + if (search_attrs) req->op.search.attrs = attrs; + + /* check operation result */ + if (ret != LDB_SUCCESS) { return ret; } /* for each record returned post-process to add any derived attributes that have been asked for */ - for (r=0;r<ret;r++) { - if (operational_search_post_process(module, (*res)[r], attrs) != 0) { + for (r = 0; r < (*(req->op.search.res))->count; r++) { + if (operational_search_post_process(module, (*(req->op.search.res))->msgs[r], attrs) != 0) { goto failed; } } @@ -235,9 +237,9 @@ static int operational_search_bytree(struct ldb_module *module, failed: talloc_free(search_attrs); - talloc_free(*res); + talloc_free(*(req->op.search.res)); ldb_oom(module->ldb); - return -1; + return LDB_ERR_OTHER; } /* @@ -273,15 +275,15 @@ static int add_time_element(struct ldb_message *msg, const char *attr, time_t t) /* hook add record ops */ -static int operational_add_record(struct ldb_module *module, - const struct ldb_message *msg) +static int operational_add(struct ldb_module *module, struct ldb_request *req) { + const struct ldb_message *msg = req->op.add.message; time_t t = time(NULL); struct ldb_message *msg2; int ret; if (ldb_dn_is_special(msg->dn)) { - return ldb_next_add_record(module, msg); + return ldb_next_request(module, req); } /* we have to copy the message as the caller might have it as a const */ @@ -294,7 +296,13 @@ static int operational_add_record(struct ldb_module *module, talloc_free(msg2); return -1; } - ret = ldb_next_add_record(module, msg2); + /* use the new structure for the call chain below this point */ + req->op.add.message = msg2; + /* go on with the call chain */ + ret = ldb_next_request(module, req); + /* put back saved message */ + req->op.add.message = msg; + /* free temproary compy */ talloc_free(msg2); return ret; } @@ -302,15 +310,15 @@ static int operational_add_record(struct ldb_module *module, /* hook modify record ops */ -static int operational_modify_record(struct ldb_module *module, - const struct ldb_message *msg) +static int operational_modify(struct ldb_module *module, struct ldb_request *req) { + const struct ldb_message *msg = req->op.mod.message; time_t t = time(NULL); struct ldb_message *msg2; int ret; if (ldb_dn_is_special(msg->dn)) { - return ldb_next_modify_record(module, msg); + return ldb_next_request(module, req); } /* we have to copy the message as the caller might have it as a const */ @@ -322,16 +330,40 @@ static int operational_modify_record(struct ldb_module *module, talloc_free(msg2); return -1; } - ret = ldb_next_modify_record(module, msg2); + /* use the new structure for the call chain below this point */ + req->op.mod.message = msg2; + /* go on with the call chain */ + ret = ldb_next_request(module, req); + /* put back saved message */ + req->op.mod.message = msg; + /* free temproary compy */ talloc_free(msg2); return ret; } + +static int operational_request(struct ldb_module *module, struct ldb_request *req) +{ + switch (req->operation) { + + case LDB_REQ_SEARCH: + return operational_search_bytree(module, req); + + case LDB_REQ_ADD: + return operational_add(module, req); + + case LDB_REQ_MODIFY: + return operational_modify(module, req); + + default: + return ldb_next_request(module, req); + + } +} + static const struct ldb_module_ops operational_ops = { .name = "operational", - .search_bytree = operational_search_bytree, - .add_record = operational_add_record, - .modify_record = operational_modify_record + .request = operational_request }; diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c index c51aa74244..42faf6629c 100644 --- a/source4/lib/ldb/modules/rdn_name.c +++ b/source4/lib/ldb/modules/rdn_name.c @@ -37,14 +37,6 @@ #include "ldb/include/ldb_private.h" #include <time.h> -static int rdn_name_search_bytree(struct ldb_module *module, const struct ldb_dn *base, - enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_message ***res) -{ - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_search\n"); - return ldb_next_search_bytree(module, base, scope, tree, attrs, res); -} - static struct ldb_message_element *rdn_name_find_attribute(const struct ldb_message *msg, const char *name) { int i; @@ -58,9 +50,9 @@ static struct ldb_message_element *rdn_name_find_attribute(const struct ldb_mess return NULL; } -/* add_record: add crateTimestamp/modifyTimestamp attributes */ -static int rdn_name_add_record(struct ldb_module *module, const struct ldb_message *msg) +static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) { + const struct ldb_message *msg = req->op.add.message; struct ldb_message *msg2; struct ldb_message_element *attribute; struct ldb_dn_component *rdn; @@ -70,12 +62,12 @@ static int rdn_name_add_record(struct ldb_module *module, const struct ldb_messa /* do not manipulate our control entries */ if (ldb_dn_is_special(msg->dn)) { - return ldb_next_add_record(module, msg); + return ldb_next_request(module, req); } /* Perhaps someone above us knows better */ if ((attribute = rdn_name_find_attribute(msg, "name")) != NULL ) { - return ldb_next_add_record(module, msg); + return ldb_next_request(module, req); } msg2 = talloc(module, struct ldb_message); @@ -128,15 +120,18 @@ static int rdn_name_add_record(struct ldb_module *module, const struct ldb_messa } } - ret = ldb_next_add_record(module, msg2); + req->op.add.message = msg2; + ret = ldb_next_request(module, req); + req->op.add.message = msg; + talloc_free(msg2); return ret; } -/* modify_record: change modifyTimestamp as well */ -static int rdn_name_modify_record(struct ldb_module *module, const struct ldb_message *msg) +static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) { + const struct ldb_message *msg = req->op.mod.message; struct ldb_message *msg2; struct ldb_message_element *attribute; struct ldb_dn_component *rdn; @@ -146,12 +141,12 @@ static int rdn_name_modify_record(struct ldb_module *module, const struct ldb_me /* do not manipulate our control entries */ if (ldb_dn_is_special(msg->dn)) { - return ldb_next_modify_record(module, msg); + return ldb_next_request(module, req); } /* Perhaps someone above us knows better */ if ((attribute = rdn_name_find_attribute(msg, "name")) != NULL ) { - return ldb_next_modify_record(module, msg); + return ldb_next_request(module, req); } msg2 = talloc(module, struct ldb_message); @@ -186,24 +181,35 @@ static int rdn_name_modify_record(struct ldb_module *module, const struct ldb_me attribute->flags = LDB_FLAG_MOD_REPLACE; - ret = ldb_next_modify_record(module, msg2); + req->op.add.message = msg2; + ret = ldb_next_request(module, req); + req->op.add.message = msg; + talloc_free(msg2); return ret; } -static int rdn_name_rename_record(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn) +static int rdn_name_request(struct ldb_module *module, struct ldb_request *req) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_rename_record\n"); - return ldb_next_rename_record(module, olddn, newdn); + switch (req->operation) { + + case LDB_REQ_ADD: + return rdn_name_add(module, req); + + case LDB_REQ_MODIFY: + return rdn_name_modify(module, req); + + + default: + return ldb_next_request(module, req); + + } } static const struct ldb_module_ops rdn_name_ops = { .name = "rdn_name", - .search_bytree = rdn_name_search_bytree, - .add_record = rdn_name_add_record, - .modify_record = rdn_name_modify_record, - .rename_record = rdn_name_rename_record + .request = rdn_name_request }; diff --git a/source4/lib/ldb/modules/schema.c b/source4/lib/ldb/modules/schema.c index 27177116c2..fd96a6cfba 100644 --- a/source4/lib/ldb/modules/schema.c +++ b/source4/lib/ldb/modules/schema.c @@ -128,7 +128,7 @@ static int get_msg_attributes(struct schema_structures *ss, const struct ldb_mes static int get_entry_attributes(struct ldb_context *ldb, const struct ldb_dn *dn, struct schema_structures *ss) { - struct ldb_message **srch; + struct ldb_result *srch; int ret; ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &srch); @@ -138,7 +138,7 @@ static int get_entry_attributes(struct ldb_context *ldb, const struct ldb_dn *dn talloc_steal(ss, srch); /* set flags to 0 as flags on search have undefined values */ - ret = get_msg_attributes(ss, *srch, 0); + ret = get_msg_attributes(ss, *(srch->msgs), 0); if (ret != 0) { talloc_free(srch); return ret; @@ -187,7 +187,7 @@ static int add_attribute_uniq(void *mem_ctx, struct schema_attribute_list *list, recursively get parent objectlasses attributes */ static int get_attr_list_recursive(struct ldb_module *module, struct schema_structures *schema_struct) { - struct ldb_message **srch; + struct ldb_result *srch; int i, j; int ret; @@ -226,20 +226,20 @@ static int get_attr_list_recursive(struct ldb_module *module, struct schema_stru /* Add inherited classes eliminating duplicates */ /* fill in required_attrs and optional_attrs attribute lists */ - for (j = 0; j < (*srch)->num_elements; j++) { + for (j = 0; j < srch->msgs[0]->num_elements; j++) { int is_aux, is_class; is_aux = 0; is_class = 0; - if (ldb_attr_cmp((*srch)->elements[j].name, "systemAuxiliaryclass") == 0) { + if (ldb_attr_cmp(srch->msgs[0]->elements[j].name, "systemAuxiliaryclass") == 0) { is_aux = SCHEMA_FLAG_AUXILIARY; is_class = 1; } - if (ldb_attr_cmp((*srch)->elements[j].name, "auxiliaryClass") == 0) { + if (ldb_attr_cmp(srch->msgs[0]->elements[j].name, "auxiliaryClass") == 0) { is_aux = SCHEMA_FLAG_AUXILIARY; is_class = 1; } - if (ldb_attr_cmp((*srch)->elements[j].name, "subClassOf") == 0) { + if (ldb_attr_cmp(srch->msgs[0]->elements[j].name, "subClassOf") == 0) { is_class = 1; } @@ -247,28 +247,28 @@ static int get_attr_list_recursive(struct ldb_module *module, struct schema_stru if (add_attribute_uniq(schema_struct, &schema_struct->objectclasses, is_aux, - &(*srch)->elements[j]) != 0) { + &srch->msgs[0]->elements[j]) != 0) { return -1; } } else { - if (ldb_attr_cmp((*srch)->elements[j].name, "mustContain") == 0 || - ldb_attr_cmp((*srch)->elements[j].name, "SystemMustContain") == 0) { + if (ldb_attr_cmp(srch->msgs[0]->elements[j].name, "mustContain") == 0 || + ldb_attr_cmp(srch->msgs[0]->elements[j].name, "SystemMustContain") == 0) { if (add_attribute_uniq(schema_struct, &schema_struct->required_attrs, SCHEMA_FLAG_RESET, - &(*srch)->elements[j]) != 0) { + &srch->msgs[0]->elements[j]) != 0) { return -1; } } - if (ldb_attr_cmp((*srch)->elements[j].name, "mayContain") == 0 || - ldb_attr_cmp((*srch)->elements[j].name, "SystemMayContain") == 0) { + if (ldb_attr_cmp(srch->msgs[0]->elements[j].name, "mayContain") == 0 || + ldb_attr_cmp(srch->msgs[0]->elements[j].name, "SystemMayContain") == 0) { if (add_attribute_uniq(schema_struct, &schema_struct->optional_attrs, SCHEMA_FLAG_RESET, - &(*srch)->elements[j]) != 0) { + &srch->msgs[0]->elements[j]) != 0) { return -1; } } @@ -279,17 +279,10 @@ static int get_attr_list_recursive(struct ldb_module *module, struct schema_stru return 0; } -/* search */ -static int schema_search_bytree(struct ldb_module *module, const struct ldb_dn *base, - enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_message ***res) -{ - return ldb_next_search_bytree(module, base, scope, tree, attrs, res); -} - /* add_record */ -static int schema_add_record(struct ldb_module *module, const struct ldb_message *msg) +static int schema_add(struct ldb_module *module, struct ldb_request *req) { + const struct ldb_message *msg = req->op.add.message; struct schema_structures *entry_structs; unsigned int i; int ret; @@ -304,7 +297,7 @@ static int schema_add_record(struct ldb_module *module, const struct ldb_message /* do not check on our control entries */ if (ldb_dn_is_special(msg->dn)) { - return ldb_next_add_record(module, msg); + return ldb_next_request(module, req); } /* TODO: check parent exists */ @@ -366,12 +359,13 @@ static int schema_add_record(struct ldb_module *module, const struct ldb_message talloc_free(entry_structs); - return ldb_next_add_record(module, msg); + return ldb_next_request(module, req); } /* modify_record */ -static int schema_modify_record(struct ldb_module *module, const struct ldb_message *msg) +static int schema_modify(struct ldb_module *module, struct ldb_request *req) { + const struct ldb_message *msg = req->op.mod.message; struct schema_structures *entry_structs; unsigned int i; int ret; @@ -387,7 +381,7 @@ static int schema_modify_record(struct ldb_module *module, const struct ldb_mess /* do not check on our control entries */ if (ldb_dn_is_special(msg->dn)) { - return ldb_next_add_record(module, msg); + return ldb_next_request(module, req); } /* allocate object structs */ @@ -466,29 +460,28 @@ static int schema_modify_record(struct ldb_module *module, const struct ldb_mess talloc_free(entry_structs); - return ldb_next_modify_record(module, msg); + return ldb_next_request(module, req); } -/* delete_record */ -static int schema_delete_record(struct ldb_module *module, const struct ldb_dn *dn) +static int schema_request(struct ldb_module *module, struct ldb_request *req) { -/* struct private_data *data = (struct private_data *)module->private_data; */ - return ldb_next_delete_record(module, dn); -} + switch (req->operation) { -/* rename_record */ -static int schema_rename_record(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn) -{ - return ldb_next_rename_record(module, olddn, newdn); + case LDB_REQ_ADD: + return schema_add(module, req); + + case LDB_REQ_MODIFY: + return schema_modify(module, req); + + default: + return ldb_next_request(module, req); + + } } static const struct ldb_module_ops schema_ops = { .name = "schema", - .search_bytree = schema_search_bytree, - .add_record = schema_add_record, - .modify_record = schema_modify_record, - .delete_record = schema_delete_record, - .rename_record = schema_rename_record + .request = schema_request }; #ifdef HAVE_DLOPEN_DISABLED diff --git a/source4/lib/ldb/modules/skel.c b/source4/lib/ldb/modules/skel.c index f882a840e1..a3dcfc21bb 100644 --- a/source4/lib/ldb/modules/skel.c +++ b/source4/lib/ldb/modules/skel.c @@ -44,7 +44,7 @@ struct private_data { /* search */ static int skel_search(struct ldb_module *module, const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_message ***res) + const char * const *attrs, struct ldb_result **res) { return ldb_next_search(module, base, scope, tree, attrs, res); } @@ -100,13 +100,41 @@ static int skel_destructor(void *module_ctx) return 0; } +static int skel_request(struct ldb_module *module, struct ldb_request *req) +{ + switch (req->operation) { + + case LDB_REQ_SEARCH: + return skel_search_bytree(module, + req->op.search->base, + req->op.search->scope, + req->op.search->tree, + req->op.search->attrs, + req->op.search->res); + + case LDB_REQ_ADD: + return skel_add(module, req->op.add->message); + + case LDB_REQ_MODIFY: + return skel_modify(module, req->op.mod->message); + + case LDB_REQ_DELETE: + return skel_delete(module, req->op.del->dn); + + case LDB_REQ_RENAME: + return skel_rename(module, + req->op.rename->olddn, + req->op.rename->newdn); + + default: + return ldb_next_request(module, req); + + } +} + static const struct ldb_module_ops skel_ops = { .name = "skel", - .search_bytree = skel_search_bytree, - .add_record = skel_add_record, - .modify_record = skel_modify_record, - .delete_record = skel_delete_record, - .rename_record = skel_rename_record, + .request = skel_request, .start_transaction = skel_start_trans, .end_transaction = skel_end_trans, .del_transaction = skel_del_trans, diff --git a/source4/lib/ldb/tests/slapd.conf b/source4/lib/ldb/tests/slapd.conf index fc9d659b0b..332b3f9063 100644 --- a/source4/lib/ldb/tests/slapd.conf +++ b/source4/lib/ldb/tests/slapd.conf @@ -14,8 +14,8 @@ access to * by * write allow update_anon bind_anon_dn -modulepath /usr/lib/ldap -moduleload back_bdb +#modulepath /usr/lib/ldap +#moduleload back_bdb defaultsearchbase "o=University of Michigan,c=TEST" diff --git a/source4/lib/ldb/tools/ldbdel.c b/source4/lib/ldb/tools/ldbdel.c index bd40fccbdb..6da8d0269f 100644 --- a/source4/lib/ldb/tools/ldbdel.c +++ b/source4/lib/ldb/tools/ldbdel.c @@ -34,6 +34,7 @@ #include "includes.h" #include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" #include "ldb/include/ldb_private.h" #include "ldb/tools/cmdline.h" @@ -45,13 +46,13 @@ static int ldb_delete_recursive(struct ldb_context *ldb, const struct ldb_dn *dn { int ret, i, total=0; const char *attrs[] = { NULL }; - struct ldb_message **res; + struct ldb_result *res; ret = ldb_search(ldb, dn, LDB_SCOPE_SUBTREE, "distinguishedName=*", attrs, &res); - if (ret <= 0) return -1; + if (ret != LDB_SUCCESS) return -1; - for (i=0;i<ret;i++) { - if (ldb_delete(ldb, res[i]->dn) == 0) { + for (i = 0; i < res->count; i++) { + if (ldb_delete(ldb, res->msgs[i]->dn) == 0) { total++; } } diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c index bc629fef93..570179c2e1 100644 --- a/source4/lib/ldb/tools/ldbedit.c +++ b/source4/lib/ldb/tools/ldbedit.c @@ -34,6 +34,7 @@ #include "includes.h" #include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" #include "ldb/include/ldb_private.h" #include "ldb/tools/cmdline.h" @@ -280,7 +281,7 @@ static void usage(void) int main(int argc, const char **argv) { struct ldb_context *ldb; - struct ldb_message **msgs; + struct ldb_result *result = NULL; struct ldb_dn *basedn = NULL; int ret; const char *expression = "(|(objectclass=*)(distinguishedName=*))"; @@ -310,21 +311,21 @@ static void usage(void) } } - ret = ldb_search(ldb, basedn, options->scope, expression, attrs, &msgs); - if (ret == -1) { + ret = ldb_search(ldb, basedn, options->scope, expression, attrs, &result); + if (ret != LDB_SUCCESS) { printf("search failed - %s\n", ldb_errstring(ldb)); exit(1); } - if (ret == 0) { + if (result->count == 0) { printf("no matching records - cannot edit\n"); return 0; } - do_edit(ldb, msgs, ret, options->editor); + do_edit(ldb, result->msgs, result->count, options->editor); - if (ret > 0) { - ret = talloc_free(msgs); + if (result) { + ret = talloc_free(result); if (ret == -1) { fprintf(stderr, "talloc_free failed\n"); exit(1); diff --git a/source4/lib/ldb/tools/ldbsearch.c b/source4/lib/ldb/tools/ldbsearch.c index 4abc7269d5..f8c06f0fa4 100644 --- a/source4/lib/ldb/tools/ldbsearch.c +++ b/source4/lib/ldb/tools/ldbsearch.c @@ -34,6 +34,7 @@ #include "includes.h" #include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" #include "ldb/include/ldb_private.h" #include "ldb/tools/cmdline.h" @@ -71,10 +72,10 @@ static int do_search(struct ldb_context *ldb, const char * const *attrs) { int ret, i; - struct ldb_message **msgs; + struct ldb_result *result = NULL; - ret = ldb_search(ldb, basedn, scope, expression, attrs, &msgs); - if (ret == -1) { + ret = ldb_search(ldb, basedn, scope, expression, attrs, &result); + if (ret != LDB_SUCCESS) { printf("search failed - %s\n", ldb_errstring(ldb)); return -1; } @@ -83,16 +84,16 @@ static int do_search(struct ldb_context *ldb, ldbsearch_ldb = ldb; if (sort_attribs) { - qsort(msgs, ret, sizeof(struct ldb_message *), + qsort(result->msgs, ret, sizeof(struct ldb_message *), (comparison_fn_t)do_compare_msg); } - for (i=0;i<ret;i++) { + for (i = 0; i < result->count; i++) { struct ldb_ldif ldif; printf("# record %d\n", i+1); ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = msgs[i]; + ldif.msg = result->msgs[i]; if (sort_attribs) { /* @@ -106,8 +107,8 @@ static int do_search(struct ldb_context *ldb, ldb_ldif_write_file(ldb, stdout, &ldif); } - if (ret > 0) { - ret = talloc_free(msgs); + if (result) { + ret = talloc_free(result); if (ret == -1) { fprintf(stderr, "talloc_free failed\n"); exit(1); diff --git a/source4/lib/ldb/tools/ldbtest.c b/source4/lib/ldb/tools/ldbtest.c index cda912c9b2..7abc1bfcef 100644 --- a/source4/lib/ldb/tools/ldbtest.c +++ b/source4/lib/ldb/tools/ldbtest.c @@ -34,6 +34,7 @@ #include "includes.h" #include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" #include "ldb/include/ldb_private.h" #include "ldb/tools/cmdline.h" @@ -228,29 +229,26 @@ static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn, int nreco for (i=0;i<nsearches;i++) { int uid = (i * 700 + 17) % (nrecords * 2); char *expr; - struct ldb_message **res; + struct ldb_result *res = NULL; int ret; asprintf(&expr, "(uid=TEST%d)", uid); ret = ldb_search(ldb, basedn, LDB_SCOPE_SUBTREE, expr, NULL, &res); - if (uid < nrecords && ret != 1) { + if (ret != LDB_SUCCESS || (uid < nrecords && res->count != 1)) { printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb)); exit(1); } - if (uid >= nrecords && ret > 0) { + if (uid >= nrecords && res->count > 0) { printf("Found %s !? - %d\n", expr, ret); exit(1); } - if (ret > 0) { - talloc_free(res); - } - - printf("testing uid %d/%d - %d \r", i, uid, ret); + printf("testing uid %d/%d - %d \r", i, uid, res->count); fflush(stdout); + talloc_free(res); free(expr); } @@ -295,7 +293,7 @@ be indexed static void start_test_index(struct ldb_context **ldb) { struct ldb_message *msg; - struct ldb_message **res; + struct ldb_result *res = NULL; struct ldb_dn *indexlist; struct ldb_dn *basedn; int ret; @@ -349,8 +347,12 @@ static void start_test_index(struct ldb_context **ldb) } ret = ldb_search(*ldb, basedn, LDB_SCOPE_SUBTREE, "uid=test", NULL, &res); - if (ret != 1) { - printf("Should have found 1 record - found %d\n", ret); + if (ret != LDB_SUCCESS) { + printf("Search with (uid=test) filter failed!\n"); + exit(1); + } + if(res->count != 1) { + printf("Should have found 1 record - found %d\n", res->count); exit(1); } diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index faf99b42f9..f1c3187aa5 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -21,6 +21,7 @@ #include "includes.h" #include "registry.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" #include "db_wrap.h" #include "librpc/gen_ndr/winreg.h" @@ -165,12 +166,19 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, const struct registry_ke /* Do a search if necessary */ if (kd->subkeys == NULL) { - kd->subkey_count = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &kd->subkeys); + struct ldb_result *res; + int ret; - if(kd->subkey_count < 0) { + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res); + + if (ret != LDB_SUCCESS) { DEBUG(0, ("Error getting subkeys for '%s': %s\n", ldb_dn_linearize(mem_ctx, kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } + + kd->subkey_count = res->count; + kd->subkeys = talloc_steal(kd, res->msgs); + talloc_free(res); } if (idx >= kd->subkey_count) return WERR_NO_MORE_ITEMS; @@ -195,12 +203,18 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct registry_key /* Do the search if necessary */ if (kd->values == NULL) { - kd->value_count = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL,&kd->values); + struct ldb_result *res; + int ret; + + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL, &res); - if(kd->value_count < 0) { + if (ret != LDB_SUCCESS) { DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_linearize(mem_ctx, kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } + kd->value_count = res->count; + kd->values = talloc_steal(kd, res->msgs); + talloc_free(res); } if(idx >= kd->value_count) return WERR_NO_MORE_ITEMS; @@ -215,29 +229,29 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct registry_key static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *h, const char *name, struct registry_key **key) { struct ldb_context *c = talloc_get_type(h->hive->backend_data, struct ldb_context); - struct ldb_message **msg; + struct ldb_result *res; struct ldb_dn *ldap_path; int ret; struct ldb_key_data *newkd; ldap_path = reg_path_to_ldb(mem_ctx, h, name, NULL); - ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &msg); + ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res); - if(ret == 0) { - return WERR_BADFILE; - } else if(ret < 0) { + if (ret != LDB_SUCCESS) { DEBUG(0, ("Error opening key '%s': %s\n", ldb_dn_linearize(ldap_path, ldap_path), ldb_errstring(c))); return WERR_FOOBAR; + } else if (res->count == 0) { + return WERR_BADFILE; } *key = talloc(mem_ctx, struct registry_key); talloc_set_destructor(*key, reg_close_ldb_key); (*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')?strchr(name, '\\'):name); (*key)->backend_data = newkd = talloc_zero(*key, struct ldb_key_data); - newkd->dn = ldb_dn_copy(mem_ctx, msg[0]->dn); + newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn); - talloc_free(msg); + talloc_free(res); return WERR_OK; } diff --git a/source4/lib/tdb/include/tdbconfig.h.in b/source4/lib/tdb/include/tdbconfig.h.in index c4f42af803..d6d2c09b3c 100644 --- a/source4/lib/tdb/include/tdbconfig.h.in +++ b/source4/lib/tdb/include/tdbconfig.h.in @@ -1,19 +1,58 @@ -/* include/tdbconfig.h.in. Generated automatically from configure.in by autoheader 2.13. */ +/* include/tdbconfig.h.in. Generated from configure.in by autoheader. */ -/* Define if you have a working `mmap' system call. */ -#undef HAVE_MMAP - -/* Define if you have the getpagesize function. */ +/* Define to 1 if you have the `getpagesize' function. */ #undef HAVE_GETPAGESIZE -/* Define if you have the mmap function. */ +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mmap' function. */ #undef HAVE_MMAP -/* Define if you have the pread function. */ +/* Define to 1 if you have the `pread' function. */ #undef HAVE_PREAD -/* Define if you have the pwrite function. */ +/* Define to 1 if you have the `pwrite' function. */ #undef HAVE_PWRITE -/* Define if you have the <unistd.h> header file. */ +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS diff --git a/source4/lib/util_str.c b/source4/lib/util_str.c index ba952df9f6..1ccdf49dc4 100644 --- a/source4/lib/util_str.c +++ b/source4/lib/util_str.c @@ -663,6 +663,46 @@ char *strrchr_m(const char *s, char c) return ret; } +BOOL strhaslower(const char *string) +{ + while (*string) { + size_t c_size; + codepoint_t s; + codepoint_t t; + + s = next_codepoint(string, &c_size); + string += c_size; + + t = tolower_w(s); + + if (s == t) { /* the source was alreay lower case */ + return True; /* that means it has lower case chars */ + } + } + + return False; +} + +BOOL strhasupper(const char *string) +{ + while (*string) { + size_t c_size; + codepoint_t s; + codepoint_t t; + + s = next_codepoint(string, &c_size); + string += c_size; + + t = toupper_w(s); + + if (s == t) { /* the source was alreay upper case */ + return True; /* that means it has upper case chars */ + } + } + + return False; +} + /** Convert a string to lower case, allocated with talloc **/ |