diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-06-13 09:10:17 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:18:06 -0500 |
commit | 4b0e5bd75373ffa2d847706a71fd0349dfa15e71 (patch) | |
tree | 5911c1b644daa5778fb437c43fbccd2ab416504a | |
parent | d71e1a7a7fe363d27a0e8256ccfb4cec425c13b5 (diff) | |
download | samba-4b0e5bd75373ffa2d847706a71fd0349dfa15e71.tar.gz samba-4b0e5bd75373ffa2d847706a71fd0349dfa15e71.tar.xz samba-4b0e5bd75373ffa2d847706a71fd0349dfa15e71.zip |
r7527: - added a ldb_search_bytree() interface, which takes a ldb_parse_tree
instead of a search expression. This allows our ldap server to pass
its ASN.1 parsed search expressions straight to ldb, instead of going
via strings.
- updated all the ldb modules code to handle the new interface
- got rid of the separate ldb_parse.h now that the ldb_parse
structures are exposed externally
- moved to C99 structure initialisation in ldb
- switched ldap server to using ldb_search_bytree()
(This used to be commit 96620ab2ee5d440bbbc51c1bc0cad9977770f897)
29 files changed, 264 insertions, 215 deletions
diff --git a/source4/cldap_server/cldap_server.c b/source4/cldap_server/cldap_server.c index a15b93f91c..c6eaf6395a 100644 --- a/source4/cldap_server/cldap_server.c +++ b/source4/cldap_server/cldap_server.c @@ -46,10 +46,11 @@ static void cldapd_request_handler(struct cldap_socket *cldap, if (search->num_attributes == 1 && strcasecmp(search->attributes[0], "netlogon") == 0) { cldapd_netlogon_request(cldap, ldap_msg->messageid, - search->filter, src_address, src_port); + search->tree, src_address, src_port); } else { DEBUG(0,("Unknown CLDAP search for '%s'\n", - ldap_msg->r.SearchRequest.filter)); + ldb_filter_from_tree(ldap_msg, + ldap_msg->r.SearchRequest.tree))); cldap_empty_reply(cldap, ldap_msg->messageid, src_address, src_port); } } diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c index f4f1c226af..4ccec27d01 100644 --- a/source4/cldap_server/netlogon.c +++ b/source4/cldap_server/netlogon.c @@ -177,11 +177,10 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, */ void cldapd_netlogon_request(struct cldap_socket *cldap, uint32_t message_id, - const char *filter, + struct ldb_parse_tree *tree, const char *src_address, int src_port) { struct cldapd_server *cldapd = talloc_get_type(cldap->incoming.private, struct cldapd_server); - struct ldb_parse_tree *tree; int i; const char *domain = NULL; const char *host = NULL; @@ -195,11 +194,6 @@ void cldapd_netlogon_request(struct cldap_socket *cldap, TALLOC_CTX *tmp_ctx = talloc_new(cldap); - DEBUG(5,("cldap filter='%s'\n", filter)); - - tree = ldb_parse_tree(tmp_ctx, filter); - if (tree == NULL) goto failed; - if (tree->operation != LDB_OP_AND) goto failed; /* extract the query elements */ diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index a392f97865..5472bed107 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -51,6 +51,14 @@ static int samldb_search(struct ldb_module *module, const char *base, return ldb_next_search(module, base, scope, expression, attrs, res); } +static int samldb_search_bytree(struct ldb_module *module, const char *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 @@ -599,15 +607,16 @@ static int samldb_destructor(void *module_ctx) } static const struct ldb_module_ops samldb_ops = { - "samldb", - samldb_search, - samldb_add_record, - samldb_modify_record, - samldb_delete_record, - samldb_rename_record, - samldb_lock, - samldb_unlock, - samldb_errstring + .name = "samldb", + .search = samldb_search, + .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, + .named_lock = samldb_lock, + .named_unlock = samldb_unlock, + .errstring = samldb_errstring }; diff --git a/source4/include/structs.h b/source4/include/structs.h index ddc572982d..04fdaaba15 100644 --- a/source4/include/structs.h +++ b/source4/include/structs.h @@ -157,6 +157,7 @@ struct netr_LMSessionKey; struct ldb_val; struct ldb_message; struct ldb_context; +struct ldb_parse_tree; struct dom_sid; struct security_token; diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c index d87ea657d7..1c2ba87018 100644 --- a/source4/ldap_server/ldap_backend.c +++ b/source4/ldap_server/ldap_backend.c @@ -89,7 +89,7 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call) DEBUG(10, ("SearchRequest")); DEBUGADD(10, (" basedn: %s", req->basedn)); - DEBUGADD(10, (" filter: %s\n", req->filter)); + DEBUGADD(10, (" filter: %s\n", ldb_filter_from_tree(call, req->tree))); part = ldapsrv_get_partition(call->conn, req->basedn, req->scope); diff --git a/source4/ldap_server/ldap_hacked_ldb.c b/source4/ldap_server/ldap_hacked_ldb.c index 0829ae7753..154211ba63 100644 --- a/source4/ldap_server/ldap_hacked_ldb.c +++ b/source4/ldap_server/ldap_hacked_ldb.c @@ -99,7 +99,7 @@ static NTSTATUS convert_values(TALLOC_CTX *mem_ctx, if (strcasecmp(attrs->name, "ncname") == 0) { - char *filter = talloc_strdup(mem_ctx, r->filter); + char *filter = ldb_filter_from_tree(mem_ctx, r->tree); struct ldb_message **res = NULL; int count; const char *dom_dn; @@ -333,8 +333,8 @@ static NTSTATUS hacked_Search(struct ldapsrv_partition *partition, struct ldapsr attrs[j] = NULL; } DEBUG(0,("hacked basedn: %s\n", basedn_str)); -DEBUGADD(0,("hacked filter: %s\n", r->filter)); - count = ldb_search(samdb, basedn_str, scope, r->filter, attrs, &res); +DEBUGADD(0,("hacked filter: %s\n", ldb_filter_from_tree(r, r->tree))); + count = ldb_search_bytree(samdb, basedn_str, scope, r->tree, attrs, &res); talloc_steal(samdb, res); if (count < 1) { diff --git a/source4/ldap_server/ldap_simple_ldb.c b/source4/ldap_server/ldap_simple_ldb.c index 905acc10f1..d6b84a37ba 100644 --- a/source4/ldap_server/ldap_simple_ldb.c +++ b/source4/ldap_server/ldap_simple_ldb.c @@ -62,7 +62,7 @@ static NTSTATUS sldb_Search(struct ldapsrv_partition *partition, struct ldapsrv_ VALID_DN_SYNTAX(basedn,0); DEBUG(10, ("sldb_Search: basedn: [%s]\n", basedn->dn)); - DEBUG(10, ("sldb_Search: filter: [%s]\n", r->filter)); + DEBUG(10, ("sldb_Search: filter: [%s]\n", ldb_filter_from_tree(call, r->tree))); switch (r->scope) { case LDAP_SEARCH_SCOPE_BASE: @@ -90,7 +90,7 @@ static NTSTATUS sldb_Search(struct ldapsrv_partition *partition, struct ldapsrv_ attrs[i] = NULL; } - count = ldb_search(samdb, basedn->dn, scope, r->filter, attrs, &res); + count = ldb_search_bytree(samdb, basedn->dn, scope, r->tree, attrs, &res); talloc_steal(samdb, res); for (i=0; i < count; i++) { diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 649b0a0f24..f5c6d551ea 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -101,6 +101,23 @@ int ldb_search(struct ldb_context *ldb, } /* + search the database given a LDAP-like search expression + + 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 char *base, + enum ldb_scope scope, + struct ldb_parse_tree *tree, + const char * const *attrs, struct ldb_message ***res) +{ + return ldb->modules->ops->search_bytree(ldb->modules, base, scope, tree, attrs, res); +} + +/* add a record to the database. Will fail if a record with the given class and key already exists */ diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index 644154d645..7df9901ae9 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -213,10 +213,10 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) */ int ldb_next_search(struct ldb_module *module, - const char *base, - enum ldb_scope scope, - const char *expression, - const char * const *attrs, struct ldb_message ***res) + const char *base, + enum ldb_scope scope, + const char *expression, + const char * const *attrs, struct ldb_message ***res) { if (!module->next) { return -1; @@ -224,6 +224,18 @@ int ldb_next_search(struct ldb_module *module, return module->next->ops->search(module->next, base, scope, expression, attrs, res); } +int ldb_next_search_bytree(struct ldb_module *module, + const char *base, + enum ldb_scope scope, + struct ldb_parse_tree *tree, + const char * const *attrs, struct ldb_message ***res) +{ + if (!module->next) { + return -1; + } + return module->next->ops->search_bytree(module->next, base, scope, tree, attrs, res); +} + int ldb_next_add_record(struct ldb_module *module, const struct ldb_message *message) { if (!module->next) { diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index 7a6dea049a..8d921b989b 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -95,8 +95,7 @@ struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, /* duplicate a ldb_val structure */ -struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, - const struct ldb_val *v) +struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v) { struct ldb_val v2; v2.length = v->length; diff --git a/source4/lib/ldb/common/ldb_parse.c b/source4/lib/ldb/common/ldb_parse.c index e2eb0f8c78..afcda60e8e 100644 --- a/source4/lib/ldb/common/ldb_parse.c +++ b/source4/lib/ldb/common/ldb_parse.c @@ -43,7 +43,6 @@ #include "includes.h" #include "ldb/include/ldb.h" -#include "ldb/include/ldb_parse.h" #include <ctype.h> @@ -64,7 +63,7 @@ a filter is defined by: /* return next token element. Caller frees */ -static char *ldb_parse_lex(TALLOC_CTX *ctx, const char **s, const char *sep) +static char *ldb_parse_lex(void *ctx, const char **s, const char *sep) { const char *p = *s; char *ret; @@ -130,13 +129,13 @@ static const char *match_brace(const char *s) decode a RFC2254 binary string representation of a buffer. Used in LDAP filters. */ -struct ldb_val ldb_binary_decode(TALLOC_CTX *ctx, const char *str) +struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str) { int i, j; struct ldb_val ret; int slen = str?strlen(str):0; - ret.data = talloc_size(ctx, slen+1); + ret.data = talloc_size(mem_ctx, slen+1); ret.length = 0; if (ret.data == NULL) return ret; @@ -165,7 +164,7 @@ struct ldb_val ldb_binary_decode(TALLOC_CTX *ctx, const char *str) encode a blob as a RFC2254 binary string, escaping any non-printable or '\' characters */ -char *ldb_binary_encode(TALLOC_CTX *ctx, struct ldb_val val) +char *ldb_binary_encode(void *mem_ctx, struct ldb_val val) { int i; char *ret; @@ -177,7 +176,7 @@ char *ldb_binary_encode(TALLOC_CTX *ctx, struct ldb_val val) len += 2; } } - ret = talloc_array(ctx, char, len+1); + ret = talloc_array(mem_ctx, char, len+1); if (ret == NULL) return NULL; len = 0; @@ -195,17 +194,17 @@ char *ldb_binary_encode(TALLOC_CTX *ctx, struct ldb_val val) return ret; } -static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *ctx, const char **s); +static struct ldb_parse_tree *ldb_parse_filter(void *mem_ctx, const char **s); /* <simple> ::= <attributetype> <filtertype> <attributevalue> */ -static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *ctx, const char *s) +static struct ldb_parse_tree *ldb_parse_simple(void *mem_ctx, const char *s) { char *eq, *val, *l; struct ldb_parse_tree *ret; - ret = talloc(ctx, struct ldb_parse_tree); + ret = talloc(mem_ctx, struct ldb_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -249,12 +248,12 @@ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *ctx, const char *s) <or> ::= '|' <filterlist> <filterlist> ::= <filter> | <filter> <filterlist> */ -static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *ctx, +static struct ldb_parse_tree *ldb_parse_filterlist(void *mem_ctx, enum ldb_parse_op op, const char *s) { struct ldb_parse_tree *ret, *next; - ret = talloc(ctx, struct ldb_parse_tree); + ret = talloc(mem_ctx, struct ldb_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -300,11 +299,11 @@ static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *ctx, /* <not> ::= '!' <filter> */ -static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *ctx, const char *s) +static struct ldb_parse_tree *ldb_parse_not(void *mem_ctx, const char *s) { struct ldb_parse_tree *ret; - ret = talloc(ctx, struct ldb_parse_tree); + ret = talloc(mem_ctx, struct ldb_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -324,39 +323,39 @@ static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *ctx, const char *s) parse a filtercomp <filtercomp> ::= <and> | <or> | <not> | <simple> */ -static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *ctx, const char *s) +static struct ldb_parse_tree *ldb_parse_filtercomp(void *mem_ctx, const char *s) { while (isspace(*s)) s++; switch (*s) { case '&': - return ldb_parse_filterlist(ctx, LDB_OP_AND, s+1); + return ldb_parse_filterlist(mem_ctx, LDB_OP_AND, s+1); case '|': - return ldb_parse_filterlist(ctx, LDB_OP_OR, s+1); + return ldb_parse_filterlist(mem_ctx, LDB_OP_OR, s+1); case '!': - return ldb_parse_not(ctx, s+1); + return ldb_parse_not(mem_ctx, s+1); case '(': case ')': return NULL; } - return ldb_parse_simple(ctx, s); + return ldb_parse_simple(mem_ctx, s); } /* <filter> ::= '(' <filtercomp> ')' */ -static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *ctx, const char **s) +static struct ldb_parse_tree *ldb_parse_filter(void *mem_ctx, const char **s) { char *l, *s2; const char *p, *p2; struct ldb_parse_tree *ret; - l = ldb_parse_lex(ctx, s, LDB_ALL_SEP); + l = ldb_parse_lex(mem_ctx, s, LDB_ALL_SEP); if (!l) { return NULL; } @@ -373,13 +372,13 @@ static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *ctx, const char **s) } p2 = p + 1; - s2 = talloc_strndup(ctx, *s, p - *s); + s2 = talloc_strndup(mem_ctx, *s, p - *s); if (!s2) { errno = ENOMEM; return NULL; } - ret = ldb_parse_filtercomp(ctx, s2); + ret = ldb_parse_filtercomp(mem_ctx, s2); talloc_free(s2); *s = p2; @@ -393,7 +392,7 @@ static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *ctx, const char **s) expression ::= <simple> | <filter> */ -struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) +struct ldb_parse_tree *ldb_parse_tree(void *mem_ctx, const char *s) { while (isspace(*s)) s++; @@ -408,7 +407,7 @@ struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) /* construct a ldap parse filter given a parse tree */ -char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, struct ldb_parse_tree *tree) +char *ldb_filter_from_tree(void *mem_ctx, struct ldb_parse_tree *tree) { char *s, *s2, *ret; int i; diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 91a826447a..02df0ae810 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -145,6 +145,31 @@ struct ldb_debug_ops { #endif +/* structues for ldb_parse_tree handling code */ +enum ldb_parse_op {LDB_OP_SIMPLE=1, LDB_OP_AND='&', LDB_OP_OR='|', LDB_OP_NOT='!'}; + +struct ldb_parse_tree { + enum ldb_parse_op operation; + union { + struct { + char *attr; + struct ldb_val value; + } simple; + struct { + unsigned int num_elements; + struct ldb_parse_tree **elements; + } list; + struct { + struct ldb_parse_tree *child; + } not; + } u; +}; + +struct ldb_parse_tree *ldb_parse_tree(void *mem_ctx, const char *s); +char *ldb_filter_from_tree(void *mem_ctx, struct ldb_parse_tree *tree); +char *ldb_binary_encode(void *ctx, struct ldb_val val); + + /* connect to a database. The URL can either be one of the following forms ldb://path @@ -172,6 +197,15 @@ int ldb_search(struct ldb_context *ldb, const char * const *attrs, struct ldb_message ***res); /* + like ldb_search() but takes a parse tree +*/ +int ldb_search_bytree(struct ldb_context *ldb, + const char *base, + enum ldb_scope scope, + struct ldb_parse_tree *tree, + const char * const *attrs, struct ldb_message ***res); + +/* add a record to the database. Will fail if a record with the given class and key already exists */ diff --git a/source4/lib/ldb/include/ldb_parse.h b/source4/lib/ldb/include/ldb_parse.h deleted file mode 100644 index c8d89d2165..0000000000 --- a/source4/lib/ldb/include/ldb_parse.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb expression parse header - * - * Description: structure for expression parsing - * - * Author: Andrew Tridgell - */ - -#ifndef _LDB_PARSE_H -#define _LDB_PARSE_H 1 - -enum ldb_parse_op {LDB_OP_SIMPLE=1, LDB_OP_AND='&', LDB_OP_OR='|', LDB_OP_NOT='!'}; - -struct ldb_parse_tree { - enum ldb_parse_op operation; - union { - struct { - char *attr; - struct ldb_val value; - } simple; - struct { - unsigned int num_elements; - struct ldb_parse_tree **elements; - } list; - struct { - struct ldb_parse_tree *child; - } not; - } u; -}; - -struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s); -char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, struct ldb_parse_tree *tree); -char *ldb_binary_encode(TALLOC_CTX *ctx, struct ldb_val val); - -#endif diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index 69bf4a6dc6..414d8c14a1 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -57,6 +57,8 @@ struct ldb_module_ops { const char *name; int (*search)(struct ldb_module *, const char *, enum ldb_scope, const char *, const char * const [], struct ldb_message ***); + int (*search_bytree)(struct ldb_module *, const char *, 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 char *); @@ -88,6 +90,11 @@ int ldb_next_search(struct ldb_module *module, 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 char *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 char *dn); diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index 95b620f571..fceaf02196 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -286,6 +286,27 @@ failed: /* + search for matching records using a ldb_parse_tree +*/ +static int lldb_search_bytree(struct ldb_module *module, const char *base, + enum ldb_scope scope, struct ldb_parse_tree *tree, + const char * const *attrs, struct ldb_message ***res) +{ + struct lldb_private *lldb = module->private_data; + char *expression; + int ret; + + expression = ldb_filter_from_tree(lldb, tree); + if (expression == NULL) { + return -1; + } + ret = lldb_search(module, base, scope, expression, attrs, res); + talloc_free(expression); + return ret; +} + + +/* convert a ldb_message structure to a list of LDAPMod structures ready for ldap_add() or ldap_modify() */ @@ -447,15 +468,16 @@ static const char *lldb_errstring(struct ldb_module *module) static const struct ldb_module_ops lldb_ops = { - "ldap", - lldb_search, - lldb_add, - lldb_modify, - lldb_delete, - lldb_rename, - lldb_lock, - lldb_unlock, - lldb_errstring + .name = "ldap", + .search = lldb_search, + .search_bytree = lldb_search_bytree, + .add_record = lldb_add, + .modify_record = lldb_modify, + .delete_record = lldb_delete, + .rename_record = lldb_rename, + .named_lock = lldb_lock, + .named_unlock = lldb_unlock, + .errstring = lldb_errstring }; diff --git a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c index d9e72c8089..747938116a 100644 --- a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c +++ b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c @@ -36,7 +36,6 @@ #include "includes.h" #include "ldb/include/ldb.h" #include "ldb/include/ldb_private.h" -#include "ldb/include/ldb_parse.h" #include "ldb/include/ldb_explode_dn.h" #include "ldb/ldb_sqlite3/ldb_sqlite3.h" @@ -162,15 +161,16 @@ new_attr(struct ldb_module * module, * Table of operations for the sqlite3 backend */ static const struct ldb_module_ops lsqlite3_ops = { - "sqlite", - lsqlite3_search, - lsqlite3_add, - lsqlite3_modify, - lsqlite3_delete, - lsqlite3_rename, - lsqlite3_lock, - lsqlite3_unlock, - lsqlite3_errstring + .name = "sqlite", + .search = lsqlite3_search, + .search_bytree = lsqlite3_search_bytree, + .add_record = lsqlite3_add, + .modify_record = lsqlite3_modify, + .delete_record = lsqlite3_delete, + .rename_record = lsqlite3_rename, + .named_lock = lsqlite3_lock, + .named_unlock = lsqlite3_unlock, + .errstring = lsqlite3_errstring }; diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index 1cf1b5c531..b6ba413ba5 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -36,7 +36,6 @@ #include "ldb/include/ldb.h" #include "ldb/include/ldb_private.h" #include "ldb/ldb_tdb/ldb_tdb.h" -#include "ldb/include/ldb_parse.h" /* find an element in a list, using the given comparison function and diff --git a/source4/lib/ldb/ldb_tdb/ldb_match.c b/source4/lib/ldb/ldb_tdb/ldb_match.c index 3bb63e2b5b..abaa5e98c6 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_match.c +++ b/source4/lib/ldb/ldb_tdb/ldb_match.c @@ -36,7 +36,6 @@ #include "ldb/include/ldb.h" #include "ldb/include/ldb_private.h" #include "ldb/ldb_tdb/ldb_tdb.h" -#include "ldb/include/ldb_parse.h" #include <fnmatch.h> /* diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index e036ae0966..17eff6f0a6 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -36,7 +36,6 @@ #include "ldb/include/ldb.h" #include "ldb/include/ldb_private.h" #include "ldb/ldb_tdb/ldb_tdb.h" -#include "ldb/include/ldb_parse.h" /* add one element to a message @@ -463,13 +462,11 @@ static int ltdb_search_full(struct ldb_module *module, search the database with a LDAP-like expression. choses a search method */ -int ltdb_search(struct ldb_module *module, const char *base, - enum ldb_scope scope, const char *expression, - const char * const attrs[], struct ldb_message ***res) +int ltdb_search_bytree(struct ldb_module *module, const char *base, + enum ldb_scope scope, struct ldb_parse_tree *tree, + const char * const attrs[], struct ldb_message ***res) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; - struct ldb_parse_tree *tree; int ret; if (ltdb_lock_read(module) != 0) { @@ -485,14 +482,6 @@ int ltdb_search(struct ldb_module *module, const char *base, *res = NULL; - /* form a parse tree for the expression */ - tree = ldb_parse_tree(ldb, expression); - if (!tree) { - ltdb->last_err_string = "expression parse failed"; - ltdb_unlock_read(module); - return -1; - } - if (tree->operation == LDB_OP_SIMPLE && (ldb_attr_cmp(tree->u.simple.attr, "dn") == 0 || ldb_attr_cmp(tree->u.simple.attr, "distinguishedName") == 0) && @@ -506,9 +495,32 @@ int ltdb_search(struct ldb_module *module, const char *base, } } - talloc_free(tree); ltdb_unlock_read(module); return ret; } + +/* + search the database with a LDAP-like expression. + choses a search method +*/ +int ltdb_search(struct ldb_module *module, const char *base, + enum ldb_scope scope, const char *expression, + const char * const attrs[], struct ldb_message ***res) +{ + struct ltdb_private *ltdb = module->private_data; + struct ldb_parse_tree *tree; + int ret; + + tree = ldb_parse_tree(ltdb, expression); + if (tree == NULL) { + ltdb->last_err_string = "expression parse failed"; + return -1; + } + + ret = ltdb_search_bytree(module, base, scope, tree, attrs, res); + talloc_free(tree); + return ret; +} + diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 9c126c1dfd..0366809c33 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -800,15 +800,16 @@ static const char *ltdb_errstring(struct ldb_module *module) static const struct ldb_module_ops ltdb_ops = { - "tdb", - ltdb_search, - ltdb_add, - ltdb_modify, - ltdb_delete, - ltdb_rename, - ltdb_lock, - ltdb_unlock, - ltdb_errstring + .name = "tdb", + .search = ltdb_search, + .search_bytree = ltdb_search_bytree, + .add_record = ltdb_add, + .modify_record = ltdb_modify, + .delete_record = ltdb_delete, + .rename_record = ltdb_rename, + .named_lock = ltdb_lock, + .named_unlock = ltdb_unlock, + .errstring = ltdb_errstring }; diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index eb6c7825d2..891522f300 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -100,6 +100,10 @@ int ltdb_add_attr_results(struct ldb_module *module, struct ldb_message *msg, int ltdb_search(struct ldb_module *module, const char *base, enum ldb_scope scope, const char *expression, const char * const attrs[], struct ldb_message ***res); +int ltdb_search_bytree(struct ldb_module *module, const char *base, + enum ldb_scope scope, struct ldb_parse_tree *tree, + const char * const attrs[], struct ldb_message ***res); + /* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c */ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn); diff --git a/source4/lib/ldb/modules/schema.c b/source4/lib/ldb/modules/schema.c index 29e5194416..e11c8b4e4e 100644 --- a/source4/lib/ldb/modules/schema.c +++ b/source4/lib/ldb/modules/schema.c @@ -306,6 +306,13 @@ static int schema_search(struct ldb_module *module, const char *base, return ldb_next_search(module, base, scope, expression, attrs, res); } +static int schema_search_bytree(struct ldb_module *module, const char *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) { @@ -541,15 +548,16 @@ static int schema_destructor(void *module_ctx) } static const struct ldb_module_ops schema_ops = { - "schema", - schema_search, - schema_add_record, - schema_modify_record, - schema_delete_record, - schema_rename_record, - schema_named_lock, - schema_named_unlock, - schema_errstring, + .name = "schema", + .search = schema_search, + .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, + .named_lock = schema_named_lock, + .named_unlock = schema_named_unlock, + .errstring = schema_errstring, }; #ifdef HAVE_DLOPEN_DISABLED diff --git a/source4/lib/ldb/modules/skel.c b/source4/lib/ldb/modules/skel.c index 505b19a288..1221ac70f1 100644 --- a/source4/lib/ldb/modules/skel.c +++ b/source4/lib/ldb/modules/skel.c @@ -103,6 +103,7 @@ static int skel_destructor(void *module_ctx) static const struct ldb_module_ops skel_ops = { .name = "skel", .search = skel_search, + .search_bytree = skel_search_bytree, .add_record = skel_add_record, .modify_record = skel_modify_record, .delete_record = skel_delete_record, diff --git a/source4/lib/ldb/modules/timestamps.c b/source4/lib/ldb/modules/timestamps.c index 1c01bd14fd..c1db85a284 100644 --- a/source4/lib/ldb/modules/timestamps.c +++ b/source4/lib/ldb/modules/timestamps.c @@ -49,6 +49,14 @@ static int timestamps_search(struct ldb_module *module, const char *base, return ldb_next_search(module, base, scope, expression, attrs, res); } +static int timestamps_search_bytree(struct ldb_module *module, const char *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, "timestamps_search\n"); + return ldb_next_search_bytree(module, base, scope, tree, attrs, res); +} + static int add_time_element(struct ldb_module *module, struct ldb_message *msg, const char *attr_name, const char *time_string, unsigned int flags) { @@ -247,15 +255,16 @@ static int timestamps_destructor(void *module_ctx) } static const struct ldb_module_ops timestamps_ops = { - "timestamps", - timestamps_search, - timestamps_add_record, - timestamps_modify_record, - timestamps_delete_record, - timestamps_rename_record, - timestamps_lock, - timestamps_unlock, - timestamps_errstring + .name = "timestamps", + .search = timestamps_search, + .search_bytree = timestamps_search_bytree, + .add_record = timestamps_add_record, + .modify_record = timestamps_modify_record, + .delete_record = timestamps_delete_record, + .rename_record = timestamps_rename_record, + .named_lock = timestamps_lock, + .named_unlock = timestamps_unlock, + .errstring = timestamps_errstring }; diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 41d5f1a06e..71326caa37 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -328,7 +328,10 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, search->attributesonly = False; search->num_attributes = str_list_length(io->in.attributes); search->attributes = io->in.attributes; - search->filter = io->in.filter; + search->tree = ldb_parse_tree(req, io->in.filter); + if (search->tree == NULL) { + goto failed; + } if (!ldap_encode(&msg, &req->encoded)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 2718dd7e34..0d310b4eed 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -152,7 +152,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_SearchRequest: { struct ldap_SearchRequest *r = &msg->r.SearchRequest; - struct ldb_parse_tree *tree; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->basedn, strlen(r->basedn)); asn1_write_enumerated(&data, r->scope); @@ -161,14 +160,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_Integer(&data, r->timelimit); asn1_write_BOOLEAN(&data, r->attributesonly); - tree = ldb_parse_tree(NULL, r->filter); - - if (tree == NULL) - return False; - - ldap_push_filter(&data, tree); - - talloc_free(tree); + ldap_push_filter(&data, r->tree); asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; i<r->num_attributes; i++) { @@ -176,7 +168,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) strlen(r->attributes[i])); } asn1_pop_tag(&data); - asn1_pop_tag(&data); break; } @@ -413,6 +404,10 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } } + +/* + parse the ASN.1 formatted search string into a ldb_parse_tree +*/ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, struct asn1_data *data) { @@ -540,25 +535,6 @@ failed: } -static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, - const char **filterp) -{ - struct ldb_parse_tree *tree; - - tree = ldap_decode_filter_tree(mem_ctx, data); - if (tree == NULL) { - return False; - } - *filterp = ldb_filter_from_tree(mem_ctx, tree); - talloc_free(tree); - if (*filterp == NULL) { - return False; - } - return True; -} - - - static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, struct ldap_attribute *attrib) { @@ -674,9 +650,10 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_Integer(data, &r->timelimit); asn1_read_BOOLEAN(data, &r->attributesonly); - /* Maybe create a TALLOC_CTX for the filter? This can waste - * quite a bit of memory recursing down. */ - ldap_decode_filter(msg->mem_ctx, data, &r->filter); + r->tree = ldap_decode_filter_tree(msg->mem_ctx, data); + if (r->tree == NULL) { + return False; + } asn1_start_tag(data, ASN1_SEQUENCE(0)); diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 12d30a2610..a44c249e7a 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -23,7 +23,6 @@ #define _SMB_LDAP_H #include "lib/ldb/include/ldb.h" -#include "lib/ldb/include/ldb_parse.h" enum ldap_request_tag { LDAP_TAG_BindRequest = 0, @@ -152,7 +151,7 @@ struct ldap_SearchRequest { uint32_t timelimit; uint32_t sizelimit; BOOL attributesonly; - const char *filter; + struct ldb_parse_tree *tree; int num_attributes; const char **attributes; }; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 1124cc1701..dff31f6411 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -509,9 +509,11 @@ BOOL asn1_read_OctetString(struct asn1_data *data, DATA_BLOB *blob) data->has_error = True; return False; } - *blob = data_blob(NULL, len); + *blob = data_blob(NULL, len+1); asn1_read(data, blob->data, len); asn1_end_tag(data); + blob->length--; + blob->data[len] = 0; if (data->has_error) { data_blob_free(blob); diff --git a/source4/torture/ldap/basic.c b/source4/torture/ldap/basic.c index c0daefa99d..931a1ee2cc 100644 --- a/source4/torture/ldap/basic.c +++ b/source4/torture/ldap/basic.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "lib/ldb/include/ldb.h" #include "libcli/ldap/ldap.h" #include "lib/cmdline/popt_common.h" @@ -96,7 +97,7 @@ static BOOL test_search_rootDSE(struct ldap_connection *conn, char **basedn) msg->r.SearchRequest.timelimit = 0; msg->r.SearchRequest.sizelimit = 0; msg->r.SearchRequest.attributesonly = False; - msg->r.SearchRequest.filter = talloc_strdup(msg->mem_ctx, "(objectclass=*)"); + msg->r.SearchRequest.tree = ldb_parse_tree(msg->mem_ctx, "(objectclass=*)"); msg->r.SearchRequest.num_attributes = 0; msg->r.SearchRequest.attributes = NULL; |