From 5c9590587197dcb95007fdc54318187d5716c7c6 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 8 Nov 2005 00:11:45 +0000 Subject: r11567: Ldb API change patch. This patch changes the way lsb_search is called and the meaning of the returned integer. The last argument of ldb_search is changed from struct ldb_message to struct ldb_result which contains a pointer to a struct ldb_message list and a count of the number of messages. The return is not the count of messages anymore but instead it is an ldb error value. I tryed to keep the patch as tiny as possible bu as you can guess I had to change a good amount of places. I also tried to double check all my changes being sure that the calling functions would still behave as before. But this patch is big enough that I fear some bug may have been introduced anyway even if it passes the test suite. So if you are currently working on any file being touched please give it a deep look and blame me for any error. Simo. (This used to be commit 22c8c97e6fb466b41859e090e959d7f1134be780) --- source4/auth/gensec/schannel_state.c | 21 +-- source4/dsdb/samdb/cracknames.c | 21 +-- source4/dsdb/samdb/ldb_modules/objectguid.c | 36 +++-- source4/dsdb/samdb/ldb_modules/proxy.c | 96 ++++++++------ source4/dsdb/samdb/ldb_modules/samldb.c | 83 +++++------- source4/kdc/hdb-ldb.c | 70 +++++----- source4/ldap_server/ldap_rootdse.c | 38 +++--- source4/ldap_server/ldap_simple_ldb.c | 126 ++++++++++-------- source4/lib/gendb.c | 30 +++-- source4/lib/ldb/common/ldb.c | 192 ++++++++++++++------------- source4/lib/ldb/common/ldb_modules.c | 73 ++-------- source4/lib/ldb/include/ldb.h | 63 ++++++++- source4/lib/ldb/include/ldb_private.h | 22 +--- source4/lib/ldb/ldb_ildap/ldb_ildap.c | 99 ++++++++++---- source4/lib/ldb/ldb_ldap/ldb_ldap.c | 85 ++++++++---- source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c | 54 ++++++-- source4/lib/ldb/ldb_tdb/ldb_index.c | 27 ++-- source4/lib/ldb/ldb_tdb/ldb_search.c | 29 ++-- source4/lib/ldb/ldb_tdb/ldb_tdb.c | 38 +++++- source4/lib/ldb/ldb_tdb/ldb_tdb.h | 6 +- source4/lib/ldb/modules/ldb_map.c | 198 +++++++++++++++++++--------- source4/lib/ldb/modules/operational.c | 84 ++++++++---- source4/lib/ldb/modules/rdn_name.c | 56 ++++---- source4/lib/ldb/modules/schema.c | 77 +++++------ source4/lib/ldb/modules/skel.c | 40 +++++- source4/lib/ldb/tests/slapd.conf | 4 +- source4/lib/ldb/tools/ldbdel.c | 9 +- source4/lib/ldb/tools/ldbedit.c | 15 ++- source4/lib/ldb/tools/ldbsearch.c | 17 +-- source4/lib/ldb/tools/ldbtest.c | 24 ++-- source4/lib/registry/reg_backend_ldb.c | 36 +++-- source4/lib/tdb/include/tdbconfig.h.in | 57 ++++++-- source4/lib/util_str.c | 40 ++++++ source4/libnet/libnet_join.c | 15 ++- source4/nbt_server/wins/winsdb.c | 37 +++--- source4/rpc_server/spoolss/dcesrv_spoolss.c | 12 -- source4/scripting/ejs/smbcalls_ldb.c | 7 +- source4/wrepl_server/wrepl_in_call.c | 21 ++- source4/wrepl_server/wrepl_server.c | 61 ++++----- 39 files changed, 1212 insertions(+), 807 deletions(-) diff --git a/source4/auth/gensec/schannel_state.c b/source4/auth/gensec/schannel_state.c index 5c789b3f2e..83776c4187 100644 --- a/source4/auth/gensec/schannel_state.c +++ b/source4/auth/gensec/schannel_state.c @@ -24,6 +24,7 @@ #include "system/time.h" #include "auth/auth.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" #include "db_wrap.h" /* @@ -146,7 +147,7 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, struct creds_CredentialState **creds) { struct ldb_context *ldb; - struct ldb_message **res; + struct ldb_result *res; int ret; const struct ldb_val *val; char *expr=NULL; @@ -168,12 +169,12 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, } ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, expr, NULL, &res); - if (ret != 1) { + if (ret != LDB_SUCCESS || res->count != 1) { talloc_free(ldb); return NT_STATUS_INVALID_HANDLE; } - val = ldb_msg_find_ldb_val(res[0], "sessionKey"); + val = ldb_msg_find_ldb_val(res->msgs[0], "sessionKey"); if (val == NULL || val->length != 16) { DEBUG(1,("schannel: record in schannel DB must contain a sessionKey of length 16, when searching for client: %s\n", computer_name)); talloc_free(ldb); @@ -182,7 +183,7 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, memcpy((*creds)->session_key, val->data, 16); - val = ldb_msg_find_ldb_val(res[0], "seed"); + val = ldb_msg_find_ldb_val(res->msgs[0], "seed"); if (val == NULL || val->length != 8) { DEBUG(1,("schannel: record in schannel DB must contain a vaid seed of length 8, when searching for client: %s\n", computer_name)); talloc_free(ldb); @@ -191,17 +192,17 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, memcpy((*creds)->seed.data, val->data, 8); - (*creds)->negotiate_flags = ldb_msg_find_int(res[0], "negotiateFlags", 0); + (*creds)->negotiate_flags = ldb_msg_find_int(res->msgs[0], "negotiateFlags", 0); - (*creds)->secure_channel_type = ldb_msg_find_int(res[0], "secureChannelType", 0); + (*creds)->secure_channel_type = ldb_msg_find_int(res->msgs[0], "secureChannelType", 0); - (*creds)->account_name = talloc_reference(*creds, ldb_msg_find_string(res[0], "accountName", NULL)); + (*creds)->account_name = talloc_reference(*creds, ldb_msg_find_string(res->msgs[0], "accountName", NULL)); - (*creds)->computer_name = talloc_reference(*creds, ldb_msg_find_string(res[0], "computerName", NULL)); + (*creds)->computer_name = talloc_reference(*creds, ldb_msg_find_string(res->msgs[0], "computerName", NULL)); - (*creds)->domain = talloc_reference(*creds, ldb_msg_find_string(res[0], "flatname", NULL)); + (*creds)->domain = talloc_reference(*creds, ldb_msg_find_string(res->msgs[0], "flatname", NULL)); - (*creds)->sid = samdb_result_dom_sid(*creds, res[0], "objectSid"); + (*creds)->sid = samdb_result_dom_sid(*creds, res->msgs[0], "objectSid"); talloc_free(ldb); diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c index 16afccda81..a377e3fe1d 100644 --- a/source4/dsdb/samdb/cracknames.c +++ b/source4/dsdb/samdb/cracknames.c @@ -28,6 +28,7 @@ #include "rpc_server/common/common.h" #include "rpc_server/drsuapi/dcesrv_drsuapi.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" #include "system/kerberos.h" #include "auth/kerberos/kerberos.h" @@ -48,8 +49,8 @@ static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, stru char **alias_to) { int i; - int count; - struct ldb_message **msg; + int ret; + struct ldb_result *res; struct ldb_message_element *spnmappings; struct ldb_dn *service_dn = ldb_dn_string_compose(mem_ctx, samdb_base_dn(mem_ctx), "CN=Directory Service,CN=Windows NT" @@ -60,19 +61,19 @@ static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, stru NULL }; - count = ldb_search(ldb_ctx, service_dn, LDB_SCOPE_BASE, "(objectClass=nTDSService)", - directory_attrs, &msg); - talloc_steal(mem_ctx, msg); + ret = ldb_search(ldb_ctx, service_dn, LDB_SCOPE_BASE, "(objectClass=nTDSService)", + directory_attrs, &res); + talloc_steal(mem_ctx, res); - if (count < 1) { - DEBUG(1, ("ldb_search: dn: %s not found: %d", service_dn_str, count)); + if (ret != LDB_SUCCESS) { + DEBUG(1, ("ldb_search: dn: %s not found: %s", service_dn_str, ldb_errstring(ldb_ctx))); return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - } else if (count > 1) { - DEBUG(1, ("ldb_search: dn: %s found %d times!", service_dn_str, count)); + } else if (res->count > 1) { + DEBUG(1, ("ldb_search: dn: %s found %d times!", service_dn_str, res->count)); return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; } - spnmappings = ldb_msg_find_element(msg[0], "sPNMappings"); + spnmappings = ldb_msg_find_element(res->msgs[0], "sPNMappings"); if (!spnmappings || spnmappings->num_values == 0) { DEBUG(1, ("ldb_search: dn: %s no sPNMappings attribute", service_dn_str)); return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; diff --git a/source4/dsdb/samdb/ldb_modules/objectguid.c b/source4/dsdb/samdb/ldb_modules/objectguid.c index 70bbaf179c..0d5ae69219 100644 --- a/source4/dsdb/samdb/ldb_modules/objectguid.c +++ b/source4/dsdb/samdb/ldb_modules/objectguid.c @@ -38,14 +38,6 @@ #include "ldb/include/ldb_private.h" #include "librpc/gen_ndr/ndr_misc.h" -static int objectguid_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, "objectguid_search\n"); - return ldb_next_search_bytree(module, base, scope, tree, attrs, res); -} - static struct ldb_message_element *objectguid_find_attribute(const struct ldb_message *msg, const char *name) { int i; @@ -60,8 +52,9 @@ static struct ldb_message_element *objectguid_find_attribute(const struct ldb_me } /* add_record: add objectGUID attribute */ -static int objectguid_add_record(struct ldb_module *module, const struct ldb_message *msg) +static int objectguid_add(struct ldb_module *module, struct ldb_request *req) { + const struct ldb_message *msg = req->op.add.message; struct ldb_val v; struct ldb_message *msg2; struct ldb_message_element *attribute; @@ -72,11 +65,11 @@ static int objectguid_add_record(struct ldb_module *module, const struct ldb_mes ldb_debug(module->ldb, LDB_DEBUG_TRACE, "objectguid_add_record\n"); if (ldb_dn_is_special(msg->dn)) { /* do not manipulate our control entries */ - return ldb_next_add_record(module, msg); + return ldb_next_request(module, req); } if ((attribute = objectguid_find_attribute(msg, "objectGUID")) != NULL ) { - return ldb_next_add_record(module, msg); + return ldb_next_request(module, req); } msg2 = talloc(module, struct ldb_message); @@ -106,16 +99,31 @@ static int objectguid_add_record(struct ldb_module *module, const struct ldb_mes return ret; } - 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; } +static int objectguid_request(struct ldb_module *module, struct ldb_request *req) +{ + switch (req->operation) { + + case LDB_REQ_ADD: + return objectguid_add(module, req); + + default: + return ldb_next_request(module, req); + + } +} + static const struct ldb_module_ops objectguid_ops = { .name = "objectguid", - .search_bytree = objectguid_search_bytree, - .add_record = objectguid_add_record + .request = objectguid_request }; diff --git a/source4/dsdb/samdb/ldb_modules/proxy.c b/source4/dsdb/samdb/ldb_modules/proxy.c index 4ef5e450aa..643ff5f3d0 100644 --- a/source4/dsdb/samdb/ldb_modules/proxy.c +++ b/source4/dsdb/samdb/ldb_modules/proxy.c @@ -39,6 +39,7 @@ #include "includes.h" #include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" #include "ldb/include/ldb_private.h" #include "lib/cmdline/popt_common.h" @@ -58,8 +59,8 @@ static int load_proxy_info(struct ldb_module *module) { struct proxy_data *proxy = talloc_get_type(module->private_data, struct proxy_data); struct ldb_dn *dn; - struct ldb_message **msg; - int res; + struct ldb_result *res; + int ret; const char *olddn, *newdn, *url, *username, *password, *oldstr, *newstr; struct cli_credentials *creds; @@ -73,20 +74,20 @@ static int load_proxy_info(struct ldb_module *module) if (dn == NULL) { goto failed; } - res = ldb_search(module->ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &msg); + ret = ldb_search(module->ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &res); talloc_free(dn); - if (res != 1) { + if (ret != LDB_SUCCESS || res->count != 1) { ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Can't find @PROXYINFO\n"); goto failed; } - url = ldb_msg_find_string(msg[0], "url", NULL); - olddn = ldb_msg_find_string(msg[0], "olddn", NULL); - newdn = ldb_msg_find_string(msg[0], "newdn", NULL); - username = ldb_msg_find_string(msg[0], "username", NULL); - password = ldb_msg_find_string(msg[0], "password", NULL); - oldstr = ldb_msg_find_string(msg[0], "oldstr", NULL); - newstr = ldb_msg_find_string(msg[0], "newstr", NULL); + url = ldb_msg_find_string(res->msgs[0], "url", NULL); + olddn = ldb_msg_find_string(res->msgs[0], "olddn", NULL); + newdn = ldb_msg_find_string(res->msgs[0], "newdn", NULL); + username = ldb_msg_find_string(res->msgs[0], "username", NULL); + password = ldb_msg_find_string(res->msgs[0], "password", NULL); + oldstr = ldb_msg_find_string(res->msgs[0], "oldstr", NULL); + newstr = ldb_msg_find_string(res->msgs[0], "newstr", NULL); if (url == NULL || olddn == NULL || newdn == NULL || username == NULL || password == NULL) { ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Need url, olddn, newdn, oldstr, newstr, username and password in @PROXYINFO\n"); @@ -135,20 +136,20 @@ static int load_proxy_info(struct ldb_module *module) ldb_set_opaque(proxy->upstream, "credentials", creds); - res = ldb_connect(proxy->upstream, url, 0, NULL); - if (res != 0) { + ret = ldb_connect(proxy->upstream, url, 0, NULL); + if (ret != 0) { ldb_debug(module->ldb, LDB_DEBUG_FATAL, "proxy failed to connect to %s\n", url); goto failed; } ldb_debug(module->ldb, LDB_DEBUG_TRACE, "proxy connected to %s\n", url); - talloc_free(msg); + talloc_free(res); return 0; failed: - talloc_free(msg); + talloc_free(res); talloc_free(proxy->olddn); talloc_free(proxy->newdn); talloc_free(proxy->upstream); @@ -246,15 +247,16 @@ static void proxy_convert_record(struct ldb_module *module, struct ldb_message * } /* search */ -static int proxy_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 proxy_search_bytree(struct ldb_module *module, struct ldb_request *req) { struct proxy_data *proxy = talloc_get_type(module->private_data, struct proxy_data); - struct ldb_dn *newbase; + struct ldb_request newreq; + struct ldb_dn *base; int ret, i; - if (base == NULL || (base->comp_num == 1 && base->components[0].name[0] == '@')) { + if (req->op.search.base == NULL || + (req->op.search.base->comp_num == 1 && + req->op.search.base->components[0].name[0] == '@')) { goto passthru; } @@ -263,56 +265,72 @@ static int proxy_search_bytree(struct ldb_module *module, const struct ldb_dn *b } /* see if the dn is within olddn */ - if (ldb_dn_compare_base(module->ldb, proxy->newdn, base) != 0) { + if (ldb_dn_compare_base(module->ldb, proxy->newdn, req->op.search.base) != 0) { goto passthru; } - tree = proxy_convert_tree(module, tree); + newreq.op.search.tree = proxy_convert_tree(module, req->op.search.tree); /* convert the basedn of this search */ - newbase = ldb_dn_copy(proxy, base); - if (newbase == NULL) { + base = ldb_dn_copy(proxy, req->op.search.base); + if (base == NULL) { goto failed; } - newbase->comp_num -= proxy->newdn->comp_num; - newbase = ldb_dn_compose(proxy, newbase, proxy->olddn); + base->comp_num -= proxy->newdn->comp_num; + base = ldb_dn_compose(proxy, newreq.op.search.base, proxy->olddn); ldb_debug(module->ldb, LDB_DEBUG_FATAL, "proxying: '%s' with dn '%s' \n", - ldb_filter_from_tree(proxy, tree), ldb_dn_linearize(proxy, newbase)); - for (i=0;attrs && attrs[i];i++) { - ldb_debug(module->ldb, LDB_DEBUG_FATAL, "attr: '%s'\n", attrs[i]); + ldb_filter_from_tree(proxy, newreq.op.search.tree), ldb_dn_linearize(proxy, newreq.op.search.base)); + for (i = 0; req->op.search.attrs && req->op.search.attrs[i]; i++) { + ldb_debug(module->ldb, LDB_DEBUG_FATAL, "attr: '%s'\n", req->op.search.attrs[i]); } - - ret = ldb_search_bytree(proxy->upstream, newbase, scope, tree, attrs, res); - if (ret == -1) { + + newreq.op.search.base = base; + newreq.op.search.scope = req->op.search.scope; + newreq.op.search.attrs = req->op.search.attrs; + newreq.op.search.res = req->op.search.res; + ret = ldb_request(proxy->upstream, &newreq); + if (ret != LDB_SUCCESS) { ldb_set_errstring(module, talloc_strdup(module, ldb_errstring(proxy->upstream))); return -1; } - for (i=0;icount; i++) { struct ldb_ldif ldif; printf("# record %d\n", i+1); - proxy_convert_record(module, (*res)[i]); + proxy_convert_record(module, (*newreq.op.search.res)->msgs[i]); ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = (*res)[i]; + ldif.msg = (*newreq.op.search.res)->msgs[i]; } return ret; failed: ldb_debug(module->ldb, LDB_DEBUG_TRACE, "proxy failed for %s\n", - ldb_dn_linearize(proxy, base)); + ldb_dn_linearize(proxy, req->op.search.base)); passthru: - return ldb_next_search_bytree(module, base, scope, tree, attrs, res); + return ldb_next_request(module, req); } +static int proxy_request(struct ldb_module *module, struct ldb_request *req) +{ + switch (req->operation) { + + case LDB_REQ_SEARCH: + return proxy_search_bytree(module, req); + + default: + return ldb_next_request(module, req); + + } +} static const struct ldb_module_ops proxy_ops = { - .name = "proxy", - .search_bytree = proxy_search_bytree + .name = "proxy", + .request = proxy_request }; #ifdef HAVE_DLOPEN_DISABLED diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 5ed84cc10d..bb69b86e1d 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -34,20 +34,13 @@ #include "includes.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" #include "lib/ldb/include/ldb_private.h" #include "system/time.h" #include "librpc/gen_ndr/ndr_security.h" #define SAM_ACCOUNT_NAME_BASE "$000000-000000000000" -static int samldb_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, "samldb_search\n"); - return ldb_next_search_bytree(module, base, scope, tree, attrs, res); -} - /* allocate a new id, attempting to do it atomically return 0 on failure, the id on success @@ -56,7 +49,7 @@ static int samldb_allocate_next_rid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx const struct ldb_dn *dn, uint32_t *id) { const char * const attrs[2] = { "nextRid", NULL }; - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; struct ldb_message msg; int ret; const char *str; @@ -64,11 +57,11 @@ static int samldb_allocate_next_rid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx struct ldb_message_element els[2]; ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, "nextRid=*", attrs, &res); - if (ret != 1) { + if (ret != LDB_SUCCESS || res->count != 1) { if (res) talloc_free(res); return -1; } - str = ldb_msg_find_string(res[0], "nextRid", NULL); + str = ldb_msg_find_string(res->msgs[0], "nextRid", NULL); if (str == NULL) { ldb_debug(ldb, LDB_DEBUG_FATAL, "attribute nextRid not found in %s\n", ldb_dn_linearize(res, dn)); talloc_free(res); @@ -133,7 +126,7 @@ static struct ldb_dn *samldb_search_domain(struct ldb_module *module, TALLOC_CTX { TALLOC_CTX *local_ctx; struct ldb_dn *sdn; - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; int ret = 0; local_ctx = talloc_named(mem_ctx, 0, "samldb_search_domain memory conext"); @@ -144,12 +137,12 @@ static struct ldb_dn *samldb_search_domain(struct ldb_module *module, TALLOC_CTX ret = ldb_search(module->ldb, sdn, LDB_SCOPE_BASE, "objectClass=domain", NULL, &res); talloc_free(res); - if (ret == 1) + if (ret == LDB_SUCCESS && res->count == 1) break; } while ((sdn = ldb_dn_get_parent(local_ctx, sdn))); - if (ret != 1) { + if (ret != LDB_SUCCESS || res->count != 1) { talloc_free(local_ctx); return NULL; } @@ -168,7 +161,7 @@ static struct dom_sid *samldb_get_new_sid(struct ldb_module *module, TALLOC_CTX *mem_ctx, const struct ldb_dn *obj_dn) { const char * const attrs[2] = { "objectSid", NULL }; - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; const struct ldb_dn *dom_dn; uint32_t rid; int ret; @@ -191,13 +184,13 @@ static struct dom_sid *samldb_get_new_sid(struct ldb_module *module, /* find the domain sid */ ret = ldb_search(module->ldb, dom_dn, LDB_SCOPE_BASE, "objectSid=*", attrs, &res); - if (ret != 1) { + if (ret != LDB_SUCCESS || res->count != 1) { ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_get_new_sid: error retrieving domain sid!\n"); talloc_free(res); return NULL; } - dom_sid = samdb_result_dom_sid(res, res[0], "objectSid"); + dom_sid = samdb_result_dom_sid(res, res->msgs[0], "objectSid"); if (dom_sid == NULL) { ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_get_new_sid: error retrieving domain sid!\n"); talloc_free(res); @@ -290,17 +283,18 @@ static BOOL samldb_find_or_add_attribute(struct ldb_module *module, struct ldb_m static int samldb_copy_template(struct ldb_module *module, struct ldb_message *msg, const char *filter) { - struct ldb_message **res, *t; + struct ldb_result *res; + struct ldb_message *t; int ret, i, j; /* pull the template record */ ret = ldb_search(module->ldb, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); - if (ret != 1) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "samldb: ERROR: template '%s' matched %d records\n", filter, ret); + if (ret != LDB_SUCCESS || res->count != 1) { + ldb_debug(module->ldb, LDB_DEBUG_WARNING, "samldb: ERROR: template '%s' matched too many records\n", filter); return -1; } - t = res[0]; + t = res->msgs[0]; for (i = 0; i < t->num_elements; i++) { struct ldb_message_element *el = &t->elements[i]; @@ -515,8 +509,9 @@ static struct ldb_message *samldb_fill_foreignSecurityPrincipal_object(struct ld } /* add_record */ -static int samldb_add_record(struct ldb_module *module, const struct ldb_message *msg) +static int samldb_add(struct ldb_module *module, struct ldb_request *req) { + const struct ldb_message *msg = req->op.add.message; struct ldb_message *msg2 = NULL; int ret; @@ -524,7 +519,7 @@ static int samldb_add_record(struct ldb_module *module, const struct ldb_message if (ldb_dn_is_special(msg->dn)) { /* do not manipulate our control entries */ - return ldb_next_add_record(module, msg); + return ldb_next_request(module, req); } /* is user or computer? add all relevant missing objects */ @@ -541,47 +536,39 @@ static int samldb_add_record(struct ldb_module *module, const struct ldb_message } if (msg2) { - ret = ldb_next_add_record(module, msg2); + req->op.add.message = msg2; + ret = ldb_next_request(module, req); + req->op.add.message = msg; } else { - ret = ldb_next_add_record(module, msg); + ret = ldb_next_request(module, req); } return ret; } -/* modify_record: change modifyTimestamp as well */ -static int samldb_modify_record(struct ldb_module *module, const struct ldb_message *msg) +static int samldb_destructor(void *module_ctx) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "samldb_modify_record\n"); - return ldb_next_modify_record(module, msg); + /* struct ldb_module *ctx = module_ctx; */ + /* put your clean-up functions here */ + return 0; } -static int samldb_delete_record(struct ldb_module *module, const struct ldb_dn *dn) +static int samldb_request(struct ldb_module *module, struct ldb_request *req) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "samldb_delete_record\n"); - return ldb_next_delete_record(module, dn); -} + switch (req->operation) { -static int samldb_rename_record(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn) -{ - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "samldb_rename_record\n"); - return ldb_next_rename_record(module, olddn, newdn); -} + case LDB_REQ_ADD: + return samldb_add(module, req); -static int samldb_destructor(void *module_ctx) -{ - /* struct ldb_module *ctx = module_ctx; */ - /* put your clean-up functions here */ - return 0; + default: + return ldb_next_request(module, req); + + } } static const struct ldb_module_ops samldb_ops = { .name = "samldb", - .search_bytree = samldb_search_bytree, - .add_record = samldb_add_record, - .modify_record = samldb_modify_record, - .delete_record = samldb_delete_record, - .rename_record = samldb_rename_record + .request = samldb_request }; diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c index 5a732b76c0..7f2289bdeb 100644 --- a/source4/kdc/hdb-ldb.c +++ b/source4/kdc/hdb-ldb.c @@ -37,6 +37,7 @@ #include "ads.h" #include "hdb.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" #include "system/iconv.h" #include "librpc/gen_ndr/netlogon.h" @@ -475,7 +476,7 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con struct ldb_message ***pmsg) { krb5_error_code ret; - int count; + int lret; char *filter = NULL; const char * const *princ_attrs = krb5_attrs; @@ -486,7 +487,7 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con char *realm_dn_str; - struct ldb_message **msg = NULL; + struct ldb_result *res = NULL; ret = krb5_unparse_name(context, principal, &princ_str); @@ -538,26 +539,26 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con return ENOMEM; } - count = ldb_search(ldb_ctx, realm_dn, LDB_SCOPE_SUBTREE, filter, - princ_attrs, &msg); + lret = ldb_search(ldb_ctx, realm_dn, LDB_SCOPE_SUBTREE, filter, princ_attrs, &res); realm_dn_str = ldb_dn_linearize(mem_ctx, realm_dn); - if (count < 1) { - krb5_warnx(context, "ldb_search: basedn: '%s' filter: '%s' failed: %d", - realm_dn_str, filter, count); - krb5_set_error_string(context, "ldb_search: basedn: '%s' filter: '%s' failed: %d", - realm_dn_str, filter, count); + if (lret != LDB_SUCCESS || res->count == 0) { + krb5_warnx(context, "ldb_search: basedn: '%s' filter: '%s' failed: %s", + realm_dn_str, filter, ldb_errstring(ldb_ctx)); + krb5_set_error_string(context, "ldb_search: basedn: '%s' filter: '%s' failed: %s", + realm_dn_str, filter, ldb_errstring(ldb_ctx)); return HDB_ERR_NOENTRY; - } else if (count > 1) { - talloc_free(msg); + } else if (res->count > 1) { krb5_warnx(context, "ldb_search: basedn: '%s' filter: '%s' more than 1 entry: %d", - realm_dn_str, filter, count); + realm_dn_str, filter, res->count); krb5_set_error_string(context, "ldb_search: basedn: '%s' filter: '%s' more than 1 entry: %d", - realm_dn_str, filter, count); + realm_dn_str, filter, res->count); + talloc_free(res); return HDB_ERR_NOENTRY; } - *pmsg = talloc_steal(mem_ctx, msg); + *pmsg = talloc_steal(mem_ctx, res->msgs); + talloc_free(res); return 0; } @@ -566,9 +567,9 @@ static krb5_error_code LDB_lookup_realm(krb5_context context, struct ldb_context const char *realm, struct ldb_message ***pmsg) { - int count; + int ret; char *cross_ref_filter; - struct ldb_message **cross_ref_msg; + struct ldb_result *cross_ref_res; cross_ref_filter = talloc_asprintf(mem_ctx, "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))", @@ -578,27 +579,26 @@ static krb5_error_code LDB_lookup_realm(krb5_context context, struct ldb_context return ENOMEM; } - count = ldb_search(ldb_ctx, NULL, LDB_SCOPE_SUBTREE, cross_ref_filter, - realm_ref_attrs, &cross_ref_msg); + ret = ldb_search(ldb_ctx, NULL, LDB_SCOPE_SUBTREE, cross_ref_filter, realm_ref_attrs, &cross_ref_res); - if (count < 1) { - krb5_warnx(context, "ldb_search: filter: '%s' failed: %d", cross_ref_filter, count); - krb5_set_error_string(context, "ldb_search: filter: '%s' failed: %d", cross_ref_filter, count); + if (ret != LDB_SUCCESS || cross_ref_res->count == 0) { + krb5_warnx(context, "ldb_search: filter: '%s' failed: %s", cross_ref_filter, ldb_errstring(ldb_ctx)); + krb5_set_error_string(context, "ldb_search: filter: '%s' failed: %s", cross_ref_filter, ldb_errstring(ldb_ctx)); - talloc_free(cross_ref_msg); + talloc_free(cross_ref_res); return HDB_ERR_NOENTRY; - } else if (count > 1) { - krb5_warnx(context, "ldb_search: filter: '%s' more than 1 entry: %d", cross_ref_filter, count); - krb5_set_error_string(context, "ldb_search: filter: '%s' more than 1 entry: %d", cross_ref_filter, count); + } else if (cross_ref_res->count > 1) { + krb5_warnx(context, "ldb_search: filter: '%s' more than 1 entry: %d", cross_ref_filter, cross_ref_res->count); + krb5_set_error_string(context, "ldb_search: filter: '%s' more than 1 entry: %d", cross_ref_filter, cross_ref_res->count); - talloc_free(cross_ref_msg); + talloc_free(cross_ref_res); return HDB_ERR_NOENTRY; } if (pmsg) { - *pmsg = talloc_steal(mem_ctx, cross_ref_msg); + *pmsg = talloc_steal(mem_ctx, cross_ref_res->msgs); } else { - talloc_free(cross_ref_msg); + talloc_free(cross_ref_res); } return 0; @@ -909,10 +909,11 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_openp; char *realm; struct ldb_dn *realm_dn = NULL; - struct ldb_message **msgs = NULL; + struct ldb_result *res = NULL; struct ldb_message **realm_ref_msgs = NULL; krb5_error_code ret; TALLOC_CTX *mem_ctx; + int lret; if (priv) { talloc_free(priv); @@ -961,17 +962,18 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag krb5_warnx(context, "LDB_firstkey: realm ok\n"); - priv->count = ldb_search(ldb_ctx, realm_dn, + lret = ldb_search(ldb_ctx, realm_dn, LDB_SCOPE_SUBTREE, "(objectClass=user)", - krb5_attrs, &msgs); + krb5_attrs, &res); - priv->msgs = talloc_steal(priv, msgs); - - if (priv->count <= 0) { + if (lret != LDB_SUCCESS) { talloc_free(priv); return HDB_ERR_NOENTRY; } + priv->count = res->count; + priv->msgs = talloc_steal(priv, res->msgs); + db->hdb_openp = priv; ret = LDB_seq(context, db, flags, entry); diff --git a/source4/ldap_server/ldap_rootdse.c b/source4/ldap_server/ldap_rootdse.c index 81a9626f14..d4e6003e5f 100644 --- a/source4/ldap_server/ldap_rootdse.c +++ b/source4/ldap_server/ldap_rootdse.c @@ -22,6 +22,7 @@ #include "ldap_server/ldap_server.h" #include "system/time.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" #define ATTR_BLOB_CONST(val) data_blob_talloc(mem_ctx, val, sizeof(val)-1) @@ -267,12 +268,12 @@ static NTSTATUS rootdse_Search(struct ldapsrv_partition *partition, struct ldaps void *local_ctx; struct ldap_SearchResEntry *ent; struct ldap_Result *done; - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; int result = LDAP_SUCCESS; struct ldapsrv_reply *ent_r, *done_r; struct ldb_context *ldb; const char *errstr = NULL; - int count, j; + int ret, j; const char **attrs = NULL; if (r->scope != LDAP_SEARCH_SCOPE_BASE) { @@ -295,11 +296,10 @@ static NTSTATUS rootdse_Search(struct ldapsrv_partition *partition, struct ldaps attrs[j] = NULL; } - count = ldb_search(ldb, ldb_dn_explode(local_ctx, "cn=rootDSE"), 0, - NULL, attrs, &res); + ret = ldb_search(ldb, ldb_dn_explode(local_ctx, "cn=rootDSE"), 0, NULL, attrs, &res); talloc_steal(local_ctx, res); - if (count == 1) { + if (ret == LDB_SUCCESS && res->count == 1) { ent_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultEntry); NT_STATUS_HAVE_NO_MEMORY(ent_r); @@ -307,11 +307,11 @@ static NTSTATUS rootdse_Search(struct ldapsrv_partition *partition, struct ldaps ent->dn = ""; ent->num_attributes = 0; ent->attributes = NULL; - if (res[0]->num_elements == 0) { + if (res->msgs[0]->num_elements == 0) { goto queue_reply; } - ent->num_attributes = res[0]->num_elements; - ent->attributes = talloc_steal(ent_r, res[0]->elements); + ent->num_attributes = res->msgs[0]->num_elements; + ent->attributes = talloc_steal(ent_r, res->msgs[0]->elements); for (j=0; j < ent->num_attributes; j++) { if (ent->attributes[j].num_values == 1 && @@ -330,22 +330,22 @@ queue_reply: done_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultDone); NT_STATUS_HAVE_NO_MEMORY(done_r); - if (count == 1) { - DEBUG(10,("rootdse_Search: results: [%d]\n",count)); - result = LDAP_SUCCESS; - errstr = NULL; - } else if (count == 0) { + if (ret != LDB_SUCCESS) { + DEBUG(10,("rootdse_Search: error\n")); + result = LDAP_OTHER; + errstr = ldb_errstring(ldb); + } else if (res->count == 0) { DEBUG(10,("rootdse_Search: no results\n")); result = LDAP_NO_SUCH_OBJECT; errstr = ldb_errstring(ldb); - } else if (count > 1) { - DEBUG(10,("rootdse_Search: too many results[%d]\n", count)); + } else if (res->count == 1) { + DEBUG(10,("rootdse_Search: results: [%d]\n", res->count)); + result = LDAP_SUCCESS; + errstr = NULL; + } else if (res->count > 1) { + DEBUG(10,("rootdse_Search: too many results[%d]\n", res->count)); result = LDAP_OTHER; errstr = "internal error"; - } else if (count == -1) { - DEBUG(10,("rootdse_Search: error\n")); - result = LDAP_OTHER; - errstr = ldb_errstring(ldb); } done = &done_r->msg->r.SearchResultDone; diff --git a/source4/ldap_server/ldap_simple_ldb.c b/source4/ldap_server/ldap_simple_ldb.c index b4e4cf8078..481db6052d 100644 --- a/source4/ldap_server/ldap_simple_ldb.c +++ b/source4/ldap_server/ldap_simple_ldb.c @@ -22,6 +22,7 @@ #include "includes.h" #include "ldap_server/ldap_server.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" #include "auth/auth.h" #include "db_wrap.h" @@ -113,12 +114,13 @@ static NTSTATUS sldb_Search(struct ldapsrv_partition *partition, struct ldapsrv_ struct ldapsrv_reply *ent_r, *done_r; int result = LDAP_SUCCESS; struct ldb_context *samdb; - struct ldb_message **res = NULL; - int i, j, y, count = 0; + struct ldb_result *res = NULL; + int i, j, y, ret; int success_limit = 1; enum ldb_scope scope = LDB_SCOPE_DEFAULT; const char **attrs = NULL; const char *errstr = NULL; + struct ldb_request lreq; local_ctx = talloc_named(call, 0, "sldb_Search local memory context"); NT_STATUS_HAVE_NO_MEMORY(local_ctx); @@ -160,71 +162,81 @@ static NTSTATUS sldb_Search(struct ldapsrv_partition *partition, struct ldapsrv_ attrs[i] = NULL; } - DEBUG(5,("ldb_search_bytree dn=%s filter=%s\n", + DEBUG(5,("ldb_request dn=%s filter=%s\n", r->basedn, ldb_filter_from_tree(call, r->tree))); - count = ldb_search_bytree(samdb, basedn, scope, r->tree, attrs, &res); - talloc_steal(samdb, res); + ZERO_STRUCT(lreq); + lreq.operation = LDB_REQ_SEARCH; + lreq.op.search.base = basedn; + lreq.op.search.scope = scope; + lreq.op.search.tree = r->tree; + lreq.op.search.attrs = attrs; + lreq.op.search.res = &res; - for (i=0; i < count; i++) { - ent_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultEntry); - NT_STATUS_HAVE_NO_MEMORY(ent_r); + ret = ldb_request(samdb, &lreq); + talloc_steal(samdb, res); - ent = &ent_r->msg->r.SearchResultEntry; - ent->dn = ldb_dn_linearize(ent_r, res[i]->dn); - ent->num_attributes = 0; - ent->attributes = NULL; - if (res[i]->num_elements == 0) { - goto queue_reply; - } - ent->num_attributes = res[i]->num_elements; - ent->attributes = talloc_array(ent_r, struct ldb_message_element, ent->num_attributes); - NT_STATUS_HAVE_NO_MEMORY(ent->attributes); - for (j=0; j < ent->num_attributes; j++) { - ent->attributes[j].name = talloc_steal(ent->attributes, res[i]->elements[j].name); - ent->attributes[j].num_values = 0; - ent->attributes[j].values = NULL; - if (r->attributesonly && (res[i]->elements[j].num_values == 0)) { - continue; + if (ret == LDB_SUCCESS) { + for (i = 0; i < res->count; i++) { + ent_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultEntry); + NT_STATUS_HAVE_NO_MEMORY(ent_r); + + ent = &ent_r->msg->r.SearchResultEntry; + ent->dn = ldb_dn_linearize(ent_r, res->msgs[i]->dn); + ent->num_attributes = 0; + ent->attributes = NULL; + if (res->msgs[i]->num_elements == 0) { + goto queue_reply; } - ent->attributes[j].num_values = res[i]->elements[j].num_values; - ent->attributes[j].values = talloc_array(ent->attributes, - DATA_BLOB, ent->attributes[j].num_values); - NT_STATUS_HAVE_NO_MEMORY(ent->attributes[j].values); - for (y=0; y < ent->attributes[j].num_values; y++) { - ent->attributes[j].values[y].length = res[i]->elements[j].values[y].length; - ent->attributes[j].values[y].data = talloc_steal(ent->attributes[j].values, - res[i]->elements[j].values[y].data); + ent->num_attributes = res->msgs[i]->num_elements; + ent->attributes = talloc_array(ent_r, struct ldb_message_element, ent->num_attributes); + NT_STATUS_HAVE_NO_MEMORY(ent->attributes); + for (j=0; j < ent->num_attributes; j++) { + ent->attributes[j].name = talloc_steal(ent->attributes, res->msgs[i]->elements[j].name); + ent->attributes[j].num_values = 0; + ent->attributes[j].values = NULL; + if (r->attributesonly && (res->msgs[i]->elements[j].num_values == 0)) { + continue; + } + ent->attributes[j].num_values = res->msgs[i]->elements[j].num_values; + ent->attributes[j].values = talloc_array(ent->attributes, + DATA_BLOB, ent->attributes[j].num_values); + NT_STATUS_HAVE_NO_MEMORY(ent->attributes[j].values); + for (y=0; y < ent->attributes[j].num_values; y++) { + ent->attributes[j].values[y].length = res->msgs[i]->elements[j].values[y].length; + ent->attributes[j].values[y].data = talloc_steal(ent->attributes[j].values, + res->msgs[i]->elements[j].values[y].data); + } } - } queue_reply: - ldapsrv_queue_reply(call, ent_r); + ldapsrv_queue_reply(call, ent_r); + } } reply: done_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultDone); NT_STATUS_HAVE_NO_MEMORY(done_r); - if (result == LDAP_SUCCESS) { - if (count >= success_limit) { - DEBUG(10,("sldb_Search: results: [%d]\n",count)); + if (ret == LDB_SUCCESS) { + if (res->count >= success_limit) { + DEBUG(10,("sldb_Search: results: [%d]\n", res->count)); result = LDAP_SUCCESS; errstr = NULL; - } else if (count == 0) { + } else if (res->count == 0) { DEBUG(10,("sldb_Search: no results\n")); result = LDAP_NO_SUCH_OBJECT; errstr = ldb_errstring(samdb); - } else if (count == -1) { - DEBUG(10,("sldb_Search: error\n")); - result = LDAP_OTHER; - errstr = ldb_errstring(samdb); } + } else { + DEBUG(10,("sldb_Search: error\n")); + result = ret; + errstr = ldb_errstring(samdb); } done = &done_r->msg->r.SearchResultDone; done->dn = NULL; done->resultcode = result; - done->errormessage = (errstr?talloc_strdup(done_r,errstr):NULL); + done->errormessage = (errstr?talloc_strdup(done_r, errstr):NULL); done->referral = NULL; talloc_free(local_ctx); @@ -476,11 +488,11 @@ static NTSTATUS sldb_Compare(struct ldapsrv_partition *partition, struct ldapsrv struct ldapsrv_reply *compare_r; int result = LDAP_SUCCESS; struct ldb_context *samdb; - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; const char *attrs[1]; const char *errstr = NULL; const char *filter = NULL; - int count; + int ret; local_ctx = talloc_named(call, 0, "sldb_Compare local_memory_context"); NT_STATUS_HAVE_NO_MEMORY(local_ctx); @@ -504,24 +516,24 @@ reply: NT_STATUS_HAVE_NO_MEMORY(compare_r); if (result == LDAP_SUCCESS) { - count = ldb_search(samdb, dn, LDB_SCOPE_BASE, filter, attrs, &res); + ret = ldb_search(samdb, dn, LDB_SCOPE_BASE, filter, attrs, &res); talloc_steal(samdb, res); - if (count == 1) { - DEBUG(10,("sldb_Compare: matched\n")); - result = LDAP_COMPARE_TRUE; - errstr = NULL; - } else if (count == 0) { + if (ret != LDB_SUCCESS) { + result = LDAP_OTHER; + errstr = ldb_errstring(samdb); + DEBUG(10,("sldb_Compare: error: %s\n", errstr)); + } else if (res->count == 0) { DEBUG(10,("sldb_Compare: doesn't matched\n")); result = LDAP_COMPARE_FALSE; errstr = NULL; - } else if (count > 1) { + } else if (res->count == 1) { + DEBUG(10,("sldb_Compare: matched\n")); + result = LDAP_COMPARE_TRUE; + errstr = NULL; + } else if (res->count > 1) { result = LDAP_OTHER; errstr = "too many objects match"; - DEBUG(10,("sldb_Compare: %d results: %s\n", count, errstr)); - } else if (count == -1) { - result = LDAP_OTHER; - errstr = ldb_errstring(samdb); - DEBUG(10,("sldb_Compare: error: %s\n", errstr)); + DEBUG(10,("sldb_Compare: %d results: %s\n", res->count, errstr)); } } 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 @@ -171,6 +171,52 @@ int ldb_transaction_cancel(struct ldb_context *ldb) return module->ops->del_transaction(module); } +/* + 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 @@ -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 @@ -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;ir.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 @@ -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;iop.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;rop.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 -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;idn) == 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;icount; 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;icount != 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 header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the 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 header file. */ +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the 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 **/ diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index b487056494..0eb109c2cf 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -227,9 +227,10 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J const struct ldb_dn *account_dn; const char *account_dn_str; const char *remote_ldb_url; - struct ldb_message **msgs, *msg; + struct ldb_result *res; + struct ldb_message *msg; - int rtn; + int ret, rtn; unsigned int kvno; @@ -403,9 +404,9 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J } /* search for the user's record */ - rtn = ldb_search(remote_ldb, account_dn, LDB_SCOPE_BASE, - NULL, attrs, &msgs); - if (rtn != 1) { + ret = ldb_search(remote_ldb, account_dn, LDB_SCOPE_BASE, + NULL, attrs, &res); + if (ret != LDB_SUCCESS || res->count != 1) { r->out.error_string = talloc_asprintf(r, "ldb_search for %s failed - %s\n", account_dn_str, ldb_errstring(remote_ldb)); talloc_free(tmp_ctx); @@ -413,7 +414,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J } /* If we have a kvno recorded in AD, we need it locally as well */ - kvno = ldb_msg_find_uint(msgs[0], "msDS-KeyVersionNumber", 0); + kvno = ldb_msg_find_uint(res->msgs[0], "msDS-KeyVersionNumber", 0); /* Prepare a new message, for the modify */ msg = ldb_msg_new(tmp_ctx); @@ -422,7 +423,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } - msg->dn = msgs[0]->dn; + msg->dn = res->msgs[0]->dn; { int i; diff --git a/source4/nbt_server/wins/winsdb.c b/source4/nbt_server/wins/winsdb.c index 42381a8772..c734c5b51e 100644 --- a/source4/nbt_server/wins/winsdb.c +++ b/source4/nbt_server/wins/winsdb.c @@ -37,7 +37,7 @@ static uint64_t winsdb_allocate_version(struct wins_server *winssrv) int ret; struct ldb_context *ldb = winssrv->wins_db; struct ldb_dn *dn; - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; struct ldb_message *msg = NULL; TALLOC_CTX *tmp_ctx = talloc_new(winssrv); uint64_t maxVersion = 0; @@ -49,16 +49,15 @@ static uint64_t winsdb_allocate_version(struct wins_server *winssrv) if (!dn) goto failed; /* find the record in the WINS database */ - ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, - NULL, NULL, &res); - if (res != NULL) { - talloc_steal(tmp_ctx, res); - } - if (ret < 0) goto failed; - if (ret > 1) goto failed; + ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &res); + + if (ret != LDB_SUCCESS) goto failed; + if (res->count > 1) goto failed; - if (ret == 1) { - maxVersion = ldb_msg_find_uint64(res[0], "maxVersion", 0); + talloc_steal(tmp_ctx, res); + + if (res->count == 1) { + maxVersion = ldb_msg_find_uint64(res->msgs[0], "maxVersion", 0); } maxVersion++; @@ -378,7 +377,7 @@ NTSTATUS winsdb_lookup(struct ldb_context *wins_db, struct winsdb_record **_rec) { NTSTATUS status; - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; int ret; struct winsdb_record *rec; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); @@ -386,18 +385,18 @@ NTSTATUS winsdb_lookup(struct ldb_context *wins_db, /* find the record in the WINS database */ ret = ldb_search(wins_db, winsdb_dn(tmp_ctx, name), LDB_SCOPE_BASE, NULL, NULL, &res); - if (res != NULL) { - talloc_steal(tmp_ctx, res); - } - if (ret == 0) { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto failed; - } else if (ret != 1) { + + if (ret != LDB_SUCCESS || res->count > 1) { status = NT_STATUS_INTERNAL_DB_CORRUPTION; goto failed; + } else if (res->count== 0) { + status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + goto failed; } - status = winsdb_record(res[0], name, tmp_ctx, &rec); + talloc_steal(tmp_ctx, res); + + status = winsdb_record(res->msgs[0], name, tmp_ctx, &rec); if (!NT_STATUS_IS_OK(status)) goto failed; /* see if it has already expired */ diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c index 6936866fcc..c15a7f1d8a 100644 --- a/source4/rpc_server/spoolss/dcesrv_spoolss.c +++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c @@ -538,8 +538,6 @@ static WERROR spoolss_GetPrinterData(struct dcesrv_call_state *dce_call, TALLOC_ DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); handle = talloc_get_type(h->data, struct ntptr_GenericHandle); - if (!handle) - return WERR_BADFID; switch (handle->type) { case NTPTR_HANDLE_SERVER: @@ -611,8 +609,6 @@ static WERROR spoolss_AddForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *me DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); handle = talloc_get_type(h->data, struct ntptr_GenericHandle); - if (!handle) - return WERR_BADFID; switch (handle->type) { case NTPTR_HANDLE_SERVER: @@ -643,8 +639,6 @@ static WERROR spoolss_DeleteForm(struct dcesrv_call_state *dce_call, TALLOC_CTX DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); handle = talloc_get_type(h->data, struct ntptr_GenericHandle); - if (!handle) - return WERR_BADFID; switch (handle->type) { case NTPTR_HANDLE_SERVER: @@ -675,8 +669,6 @@ static WERROR spoolss_GetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *me DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); handle = talloc_get_type(h->data, struct ntptr_GenericHandle); - if (!handle) - return WERR_BADFID; switch (handle->type) { case NTPTR_HANDLE_SERVER: @@ -710,8 +702,6 @@ static WERROR spoolss_SetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *me DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); handle = talloc_get_type(h->data, struct ntptr_GenericHandle); - if (!handle) - return WERR_BADFID; switch (handle->type) { case NTPTR_HANDLE_SERVER: @@ -742,8 +732,6 @@ static WERROR spoolss_EnumForms(struct dcesrv_call_state *dce_call, TALLOC_CTX * DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); handle = talloc_get_type(h->data, struct ntptr_GenericHandle); - if (!handle) - return WERR_BADFID; switch (handle->type) { case NTPTR_HANDLE_SERVER: diff --git a/source4/scripting/ejs/smbcalls_ldb.c b/source4/scripting/ejs/smbcalls_ldb.c index b77736dc36..d3db85db86 100644 --- a/source4/scripting/ejs/smbcalls_ldb.c +++ b/source4/scripting/ejs/smbcalls_ldb.c @@ -25,6 +25,7 @@ #include "scripting/ejs/smbcalls.h" #include "lib/appweb/ejs/ejs.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" /* get the connected db @@ -58,7 +59,7 @@ static int ejs_ldbSearch(MprVarHandle eid, int argc, struct MprVar **argv) TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx()); struct ldb_context *ldb; int ret; - struct ldb_message **res; + struct ldb_result *res; /* validate arguments */ if (argc < 1 || argc > 4) { @@ -104,11 +105,11 @@ static int ejs_ldbSearch(MprVarHandle eid, int argc, struct MprVar **argv) attrs = mprToList(tmp_ctx, argv[3]); } ret = ldb_search(ldb, basedn, scope, expression, attrs, &res); - if (ret == -1) { + if (ret != LDB_SUCCESS) { ejsSetErrorMsg(eid, "ldb.search failed - %s", ldb_errstring(ldb)); mpr_Return(eid, mprCreateUndefinedVar()); } else { - mpr_Return(eid, mprLdbArray(ldb, res, ret, "ldb_message")); + mpr_Return(eid, mprLdbArray(ldb, res->msgs, res->count, "ldb_message")); } talloc_free(tmp_ctx); diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 7ccb52cc20..38d0b72405 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -35,6 +35,7 @@ #include "libcli/composite/composite.h" #include "nbt_server/wins/winsdb.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call) { @@ -185,7 +186,7 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) struct wreplsrv_owner local_owner; struct wreplsrv_owner *owner; const char *filter; - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; int ret; struct wrepl_wins_name *names; struct winsdb_record *rec; @@ -240,28 +241,26 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) owner_in->min_version, owner_in->max_version); NT_STATUS_HAVE_NO_MEMORY(filter); ret = ldb_search(service->wins_db, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); - if (res != NULL) { - talloc_steal(call, res); - } - if (ret < 0) return NT_STATUS_INTERNAL_DB_CORRUPTION; - if (ret == 0) { + if (ret != LDB_SUCCESS) return NT_STATUS_INTERNAL_DB_CORRUPTION; + talloc_steal(call, res); + if (res->count == 0) { DEBUG(2,("WINSREPL:reply [%u] records owner[%s] min[%llu] max[%llu] to partner[%s]\n", - ret, owner_in->address, owner_in->min_version, owner_in->max_version, + res->count, owner_in->address, owner_in->min_version, owner_in->max_version, call->wreplconn->partner->address)); return NT_STATUS_OK; } - names = talloc_array(call, struct wrepl_wins_name, ret); + names = talloc_array(call, struct wrepl_wins_name, res->count); NT_STATUS_HAVE_NO_MEMORY(names); - for (i=0; i < ret; i++) { - status = winsdb_record(res[i], NULL, call, &rec); + for (i = 0; i < res->count; i++) { + status = winsdb_record(res->msgs[i], NULL, call, &rec); NT_STATUS_NOT_OK_RETURN(status); status = wreplsrv_record2wins_name(names, call->wreplconn->our_ip, &names[i], rec); NT_STATUS_NOT_OK_RETURN(status); talloc_free(rec); - talloc_free(res[i]); + talloc_free(res->msgs[i]); } /* sort the names before we send them */ diff --git a/source4/wrepl_server/wrepl_server.c b/source4/wrepl_server/wrepl_server.c index e49b5879dc..8249e6ac31 100644 --- a/source4/wrepl_server/wrepl_server.c +++ b/source4/wrepl_server/wrepl_server.c @@ -31,6 +31,7 @@ #include "wrepl_server/wrepl_server.h" #include "nbt_server/wins/winsdb.h" #include "ldb/include/ldb.h" +#include "ldb/include/ldb_errors.h" /* open winsdb @@ -63,7 +64,7 @@ struct wreplsrv_partner *wreplsrv_find_partner(struct wreplsrv_service *service, */ static NTSTATUS wreplsrv_load_partners(struct wreplsrv_service *service) { - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; int ret; TALLOC_CTX *tmp_ctx = talloc_new(service); int i; @@ -71,29 +72,27 @@ static NTSTATUS wreplsrv_load_partners(struct wreplsrv_service *service) /* find the record in the WINS database */ ret = ldb_search(service->wins_db, ldb_dn_explode(tmp_ctx, "CN=PARTNERS"), LDB_SCOPE_ONELEVEL, "(objectClass=wreplPartner)", NULL, &res); - if (res != NULL) { - talloc_steal(tmp_ctx, res); - } - if (ret < 0) goto failed; - if (ret == 0) goto done; + if (ret != LDB_SUCCESS) goto failed; + talloc_steal(tmp_ctx, res); + if (res->count == 0) goto done; - for (i=0; i < ret; i++) { + for (i=0; i < res->count; i++) { struct wreplsrv_partner *partner; partner = talloc_zero(service, struct wreplsrv_partner); if (partner == NULL) goto failed; - partner->service = service; - partner->address = ldb_msg_find_string(res[i], "address", NULL); + partner->service = service; + partner->address = ldb_msg_find_string(res->msgs[i], "address", NULL); if (!partner->address) goto failed; - partner->name = ldb_msg_find_string(res[i], "name", partner->address); - partner->type = ldb_msg_find_uint(res[i], "type", WINSREPL_PARTNER_BOTH); - partner->pull.interval = ldb_msg_find_uint(res[i], "pullInterval", + partner->name = ldb_msg_find_string(res->msgs[i], "name", partner->address); + partner->type = ldb_msg_find_uint(res->msgs[i], "type", WINSREPL_PARTNER_BOTH); + partner->pull.interval = ldb_msg_find_uint(res->msgs[i], "pullInterval", WINSREPL_DEFAULT_PULL_INTERVAL); - partner->pull.retry_interval = ldb_msg_find_uint(res[i], "pullRetryInterval", + partner->pull.retry_interval = ldb_msg_find_uint(res->msgs[i], "pullRetryInterval", WINSREPL_DEFAULT_PULL_RETRY_INTERVAL); - partner->our_address = ldb_msg_find_string(res[i], "ourAddress", NULL); - partner->push.change_count = ldb_msg_find_uint(res[i], "pushChangeCount", + partner->our_address = ldb_msg_find_string(res->msgs[i], "ourAddress", NULL); + partner->push.change_count = ldb_msg_find_uint(res->msgs[i], "pushChangeCount", WINSREPL_DEFAULT_PUSH_CHANGE_COUNT); talloc_steal(partner, partner->address); @@ -138,7 +137,7 @@ uint64_t wreplsrv_local_max_version(struct wreplsrv_service *service) int ret; struct ldb_context *ldb = service->wins_db; struct ldb_dn *dn; - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; TALLOC_CTX *tmp_ctx = talloc_new(service); uint64_t maxVersion = 0; @@ -148,14 +147,12 @@ uint64_t wreplsrv_local_max_version(struct wreplsrv_service *service) /* find the record in the WINS database */ ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &res); - if (res != NULL) { - talloc_steal(tmp_ctx, res); - } - if (ret < 0) goto failed; - if (ret > 1) goto failed; + if (ret != LDB_SUCCESS) goto failed; + talloc_steal(tmp_ctx, res); + if (res->count > 1) goto failed; - if (ret == 1) { - maxVersion = ldb_msg_find_uint64(res[0], "maxVersion", 0); + if (res->count == 1) { + maxVersion = ldb_msg_find_uint64(res->msgs[0], "maxVersion", 0); } failed: @@ -268,7 +265,7 @@ NTSTATUS wreplsrv_add_table(struct wreplsrv_service *service, */ static NTSTATUS wreplsrv_load_table(struct wreplsrv_service *service) { - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; int ret; NTSTATUS status; TALLOC_CTX *tmp_ctx = talloc_new(service); @@ -284,16 +281,14 @@ static NTSTATUS wreplsrv_load_table(struct wreplsrv_service *service) /* find the record in the WINS database */ ret = ldb_search(service->wins_db, NULL, LDB_SCOPE_SUBTREE, "(objectClass=winsRecord)", attrs, &res); - if (res != NULL) { - talloc_steal(tmp_ctx, res); - } status = NT_STATUS_INTERNAL_DB_CORRUPTION; - if (ret < 0) goto failed; - if (ret == 0) goto done; + if (ret != LDB_SUCCESS) goto failed; + talloc_steal(tmp_ctx, res); + if (res->count == 0) goto done; - for (i=0; i < ret; i++) { - wins_owner = ldb_msg_find_string(res[i], "winsOwner", NULL); - version = ldb_msg_find_uint64(res[i], "versionID", 0); + for (i=0; i < res->count; i++) { + wins_owner = ldb_msg_find_string(res->msgs[i], "winsOwner", NULL); + version = ldb_msg_find_uint64(res->msgs[i], "versionID", 0); if (wins_owner) { status = wreplsrv_add_table(service, @@ -301,7 +296,7 @@ static NTSTATUS wreplsrv_load_table(struct wreplsrv_service *service) wins_owner, version); if (!NT_STATUS_IS_OK(status)) goto failed; } - talloc_free(res[i]); + talloc_free(res->msgs[i]); /* TODO: what's abut the per address owners? */ } -- cgit