summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-06-13 09:10:17 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:18:06 -0500
commit4b0e5bd75373ffa2d847706a71fd0349dfa15e71 (patch)
tree5911c1b644daa5778fb437c43fbccd2ab416504a
parentd71e1a7a7fe363d27a0e8256ccfb4cec425c13b5 (diff)
downloadsamba-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)
-rw-r--r--source4/cldap_server/cldap_server.c5
-rw-r--r--source4/cldap_server/netlogon.c8
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c27
-rw-r--r--source4/include/structs.h1
-rw-r--r--source4/ldap_server/ldap_backend.c2
-rw-r--r--source4/ldap_server/ldap_hacked_ldb.c6
-rw-r--r--source4/ldap_server/ldap_simple_ldb.c4
-rw-r--r--source4/lib/ldb/common/ldb.c17
-rw-r--r--source4/lib/ldb/common/ldb_modules.c20
-rw-r--r--source4/lib/ldb/common/ldb_msg.c3
-rw-r--r--source4/lib/ldb/common/ldb_parse.c47
-rw-r--r--source4/lib/ldb/include/ldb.h34
-rw-r--r--source4/lib/ldb/include/ldb_parse.h61
-rw-r--r--source4/lib/ldb/include/ldb_private.h7
-rw-r--r--source4/lib/ldb/ldb_ldap/ldb_ldap.c40
-rw-r--r--source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c20
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_index.c1
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_match.c1
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_search.c42
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c19
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.h4
-rw-r--r--source4/lib/ldb/modules/schema.c26
-rw-r--r--source4/lib/ldb/modules/skel.c1
-rw-r--r--source4/lib/ldb/modules/timestamps.c27
-rw-r--r--source4/libcli/cldap/cldap.c5
-rw-r--r--source4/libcli/ldap/ldap.c41
-rw-r--r--source4/libcli/ldap/ldap.h3
-rw-r--r--source4/libcli/util/asn1.c4
-rw-r--r--source4/torture/ldap/basic.c3
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;