diff options
author | Andrew Bartlett <abartlet@samba.org> | 2011-07-05 10:14:12 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2011-10-07 17:45:20 +1100 |
commit | 36b2227eca55e769813eecc97366ba18a2832fb3 (patch) | |
tree | e7ad966a443a67762814a256d1ef3446471b8d27 /source3 | |
parent | ed41edddde6b81b759d4b4c8d9e59ee541a37c0a (diff) | |
download | samba-36b2227eca55e769813eecc97366ba18a2832fb3.tar.gz samba-36b2227eca55e769813eecc97366ba18a2832fb3.tar.bz2 samba-36b2227eca55e769813eecc97366ba18a2832fb3.zip |
ldb: use ldb directly rather than via a copy
This avoids needing to manually sync the two files, which due to the
top level build must be API compatible at all times anyway.
The most important recent change was:
commit e3b76bd6205acfc1a89fbcab5d9588b32cb47b88
Author: Andrew Tridgell <tridge@samba.org>
Date: Thu Jul 28 15:51:31 2011 +1000
ldb: fixed a search expression parse bug
However, as we always control the search expression in the callers to
this code, no backport to other releases is required.
Andrew Bartlett
Diffstat (limited to 'source3')
-rw-r--r-- | source3/Makefile.in | 3 | ||||
-rw-r--r-- | source3/include/autoconf/ldb_version.h | 4 | ||||
-rw-r--r-- | source3/lib/ldb_compat.c | 639 | ||||
-rw-r--r-- | source3/lib/ldb_compat.h | 87 | ||||
-rwxr-xr-x | source3/wscript_build | 4 |
5 files changed, 6 insertions, 731 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 1bb987e04d..1264611f72 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -177,6 +177,7 @@ FLAGS = -I. \ $(ISA) \ -I$(srcdir)/lib \ -I.. \ + -I./../lib/ldb/include \ -D_SAMBA_BUILD_=3 PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \ @@ -567,7 +568,7 @@ LIBSAMBA_OBJ = $(LIBSMB_OBJ0) \ $(LIBSMB_ERR_OBJ) LIBCLI_LDAP_MESSAGE_OBJ = ../libcli/ldap/ldap_message.o -LIBCLI_LDAP_NDR_OBJ = ../libcli/ldap/ldap_ndr.o lib/ldb_compat.o +LIBCLI_LDAP_NDR_OBJ = ../libcli/ldap/ldap_ndr.o ../lib/ldb/common/ldb_parse.o LIBTSOCKET_OBJ = ../lib/tsocket/tsocket.o \ ../lib/tsocket/tsocket_helpers.o \ diff --git a/source3/include/autoconf/ldb_version.h b/source3/include/autoconf/ldb_version.h new file mode 100644 index 0000000000..e1c1afc51b --- /dev/null +++ b/source3/include/autoconf/ldb_version.h @@ -0,0 +1,4 @@ + +/* This define and header file is needed so we can include ldb.h + * without building ldb properly */ +#define LDB_VERSION "dummy ldb version for ldb.h without ldb" diff --git a/source3/lib/ldb_compat.c b/source3/lib/ldb_compat.c deleted file mode 100644 index 36a29e6833..0000000000 --- a/source3/lib/ldb_compat.c +++ /dev/null @@ -1,639 +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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "lib/ldb_compat.h" - -static struct ldb_parse_tree *ldb_parse_filter(void *mem_ctx, const char **s); - -static int ldb_parse_hex2char(const char *x) -{ - if (isxdigit(x[0]) && isxdigit(x[1])) { - const char h1 = x[0], h2 = x[1]; - int c = 0; - - if (h1 >= 'a') c = h1 - (int)'a' + 10; - else if (h1 >= 'A') c = h1 - (int)'A' + 10; - else if (h1 >= '0') c = h1 - (int)'0'; - c = c << 4; - if (h2 >= 'a') c += h2 - (int)'a' + 10; - else if (h2 >= 'A') c += h2 - (int)'A' + 10; - else if (h2 >= '0') c += h2 - (int)'0'; - - return c; - } - - return -1; -} - - - -/* - decode a RFC2254 binary string representation of a buffer. - Used in LDAP filters. -*/ -static struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str) -{ - size_t i, j; - struct ldb_val ret; - size_t slen = str?strlen(str):0; - - ret.data = (uint8_t *)talloc_size(mem_ctx, slen+1); - ret.length = 0; - if (ret.data == NULL) return ret; - - for (i=j=0;i<slen;i++) { - if (str[i] == '\\') { - int c; - - c = ldb_parse_hex2char(&str[i+1]); - if (c == -1) { - talloc_free(ret.data); - memset(&ret, 0, sizeof(ret)); - return ret; - } - ((uint8_t *)ret.data)[j++] = c; - i += 2; - } else { - ((uint8_t *)ret.data)[j++] = str[i]; - } - } - ret.length = j; - ((uint8_t *)ret.data)[j] = 0; - - return ret; -} - - - - -/* - encode a blob as a RFC2254 binary string, escaping any - non-printable or '\' characters -*/ -char *ldb_binary_encode(void *mem_ctx, struct ldb_val val) -{ - size_t i; - char *ret; - size_t len = val.length; - unsigned char *buf = val.data; - - for (i=0;i<val.length;i++) { - if (!isprint(buf[i]) || strchr(" *()\\&|!\"", buf[i])) { - len += 2; - } - } - ret = talloc_array(mem_ctx, char, len+1); - if (ret == NULL) return NULL; - - len = 0; - for (i=0;i<val.length;i++) { - if (!isprint(buf[i]) || strchr(" *()\\&|!\"", buf[i])) { - snprintf(ret+len, 4, "\\%02X", buf[i]); - len += 3; - } else { - ret[len++] = buf[i]; - } - } - - ret[len] = 0; - - return ret; -} - - - -static enum ldb_parse_op ldb_parse_filtertype(void *mem_ctx, char **type, char **value, const char **s) -{ - enum ldb_parse_op filter = 0; - char *name, *val, *k; - const char *p = *s; - const char *t, *t1; - - /* retrieve attributetype name */ - t = p; - - if (*p == '@') { /* for internal attributes the first char can be @ */ - p++; - } - - while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-') || (*p == '.')) { - /* attribute names can only be alphanums */ - p++; - } - - if (*p == ':') { /* but extended searches have : and . chars too */ - p = strstr(p, ":="); - if (p == NULL) { /* malformed attribute name */ - return 0; - } - } - - t1 = p; - - while (isspace((unsigned char)*p)) p++; - - if (!strchr("=<>~:", *p)) { - return 0; - } - - /* save name */ - name = (char *)talloc_memdup(mem_ctx, t, t1 - t + 1); - if (name == NULL) return 0; - name[t1 - t] = '\0'; - - /* retrieve filtertype */ - - if (*p == '=') { - filter = LDB_OP_EQUALITY; - } else if (*(p + 1) == '=') { - switch (*p) { - case '<': - filter = LDB_OP_LESS; - p++; - break; - case '>': - filter = LDB_OP_GREATER; - p++; - break; - case '~': - filter = LDB_OP_APPROX; - p++; - break; - case ':': - filter = LDB_OP_EXTENDED; - p++; - break; - } - } - if (!filter) { - talloc_free(name); - return filter; - } - p++; - - while (isspace((unsigned char)*p)) p++; - - /* retrieve value */ - t = p; - - while (*p && ((*p != ')') || ((*p == ')') && (*(p - 1) == '\\')))) p++; - - val = (char *)talloc_memdup(mem_ctx, t, p - t + 1); - if (val == NULL) { - talloc_free(name); - return 0; - } - val[p - t] = '\0'; - - k = &(val[p - t]); - - /* remove trailing spaces from value */ - while ((k > val) && (isspace((unsigned char)*(k - 1)))) k--; - *k = '\0'; - - *type = name; - *value = val; - *s = p; - return filter; -} - -/* find the first matching wildcard */ -static char *ldb_parse_find_wildcard(char *value) -{ - while (*value) { - value = strpbrk(value, "\\*"); - if (value == NULL) return NULL; - - if (value[0] == '\\') { - if (value[1] == '\0') return NULL; - value += 2; - continue; - } - - if (value[0] == '*') return value; - } - - return NULL; -} - -/* return a NULL terminated list of binary strings representing the value - chunks separated by wildcards that makes the value portion of the filter -*/ -static struct ldb_val **ldb_wildcard_decode(void *mem_ctx, const char *string) -{ - struct ldb_val **ret = NULL; - unsigned int val = 0; - char *wc, *str; - - wc = talloc_strdup(mem_ctx, string); - if (wc == NULL) return NULL; - - while (wc && *wc) { - str = wc; - wc = ldb_parse_find_wildcard(str); - if (wc && *wc) { - if (wc == str) { - wc++; - continue; - } - *wc = 0; - wc++; - } - - ret = talloc_realloc(mem_ctx, ret, struct ldb_val *, val + 2); - if (ret == NULL) return NULL; - - ret[val] = talloc(mem_ctx, struct ldb_val); - if (ret[val] == NULL) return NULL; - - *(ret[val]) = ldb_binary_decode(mem_ctx, str); - if ((ret[val])->data == NULL) return NULL; - - val++; - } - - if (ret != NULL) { - ret[val] = NULL; - } - - return ret; -} - -/* - parse an extended match - - possible forms: - (attr:oid:=value) - (attr:dn:oid:=value) - (attr:dn:=value) - (:dn:oid:=value) - - the ':dn' part sets the dnAttributes boolean if present - the oid sets the rule_id string - -*/ -static struct ldb_parse_tree *ldb_parse_extended(struct ldb_parse_tree *ret, - char *attr, char *value) -{ - char *p1, *p2; - - ret->operation = LDB_OP_EXTENDED; - ret->u.extended.value = ldb_binary_decode(ret, value); - if (ret->u.extended.value.data == NULL) goto failed; - - p1 = strchr(attr, ':'); - if (p1 == NULL) goto failed; - p2 = strchr(p1+1, ':'); - - *p1 = 0; - if (p2) *p2 = 0; - - ret->u.extended.attr = attr; - if (strcmp(p1+1, "dn") == 0) { - ret->u.extended.dnAttributes = 1; - if (p2) { - ret->u.extended.rule_id = talloc_strdup(ret, p2+1); - if (ret->u.extended.rule_id == NULL) goto failed; - } else { - ret->u.extended.rule_id = NULL; - } - } else { - ret->u.extended.dnAttributes = 0; - ret->u.extended.rule_id = talloc_strdup(ret, p1+1); - if (ret->u.extended.rule_id == NULL) goto failed; - } - - return ret; - -failed: - talloc_free(ret); - return NULL; -} - - -/* - <simple> ::= <attributetype> <filtertype> <attributevalue> -*/ -static struct ldb_parse_tree *ldb_parse_simple(void *mem_ctx, const char **s) -{ - char *attr, *value; - struct ldb_parse_tree *ret; - enum ldb_parse_op filtertype; - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - filtertype = ldb_parse_filtertype(ret, &attr, &value, s); - if (!filtertype) { - talloc_free(ret); - return NULL; - } - - switch (filtertype) { - - case LDB_OP_PRESENT: - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = attr; - break; - - case LDB_OP_EQUALITY: - - if (strcmp(value, "*") == 0) { - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = attr; - break; - } - - if (ldb_parse_find_wildcard(value) != NULL) { - ret->operation = LDB_OP_SUBSTRING; - ret->u.substring.attr = attr; - ret->u.substring.start_with_wildcard = 0; - ret->u.substring.end_with_wildcard = 0; - ret->u.substring.chunks = ldb_wildcard_decode(ret, value); - if (ret->u.substring.chunks == NULL){ - talloc_free(ret); - return NULL; - } - if (value[0] == '*') - ret->u.substring.start_with_wildcard = 1; - if (value[strlen(value) - 1] == '*') - ret->u.substring.end_with_wildcard = 1; - talloc_free(value); - - break; - } - - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = attr; - ret->u.equality.value = ldb_binary_decode(ret, value); - if (ret->u.equality.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_GREATER: - ret->operation = LDB_OP_GREATER; - ret->u.comparison.attr = attr; - ret->u.comparison.value = ldb_binary_decode(ret, value); - if (ret->u.comparison.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_LESS: - ret->operation = LDB_OP_LESS; - ret->u.comparison.attr = attr; - ret->u.comparison.value = ldb_binary_decode(ret, value); - if (ret->u.comparison.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_APPROX: - ret->operation = LDB_OP_APPROX; - ret->u.comparison.attr = attr; - ret->u.comparison.value = ldb_binary_decode(ret, value); - if (ret->u.comparison.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_EXTENDED: - - ret = ldb_parse_extended(ret, attr, value); - break; - - default: - talloc_free(ret); - return NULL; - } - - return ret; -} - -/* - parse a filterlist - <and> ::= '&' <filterlist> - <or> ::= '|' <filterlist> - <filterlist> ::= <filter> | <filter> <filterlist> -*/ -static struct ldb_parse_tree *ldb_parse_filterlist(void *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret, *next; - enum ldb_parse_op op; - const char *p = *s; - - switch (*p) { - case '&': - op = LDB_OP_AND; - break; - case '|': - op = LDB_OP_OR; - break; - default: - return NULL; - } - p++; - - while (isspace((unsigned char)*p)) p++; - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = op; - ret->u.list.num_elements = 1; - ret->u.list.elements = talloc(ret, struct ldb_parse_tree *); - if (!ret->u.list.elements) { - errno = ENOMEM; - talloc_free(ret); - return NULL; - } - - ret->u.list.elements[0] = ldb_parse_filter(ret->u.list.elements, &p); - if (!ret->u.list.elements[0]) { - talloc_free(ret); - return NULL; - } - - while (isspace((unsigned char)*p)) p++; - - while (*p && (next = ldb_parse_filter(ret->u.list.elements, &p))) { - struct ldb_parse_tree **e; - e = talloc_realloc(ret, ret->u.list.elements, - struct ldb_parse_tree *, - ret->u.list.num_elements + 1); - if (!e) { - errno = ENOMEM; - talloc_free(ret); - return NULL; - } - ret->u.list.elements = e; - ret->u.list.elements[ret->u.list.num_elements] = next; - ret->u.list.num_elements++; - while (isspace((unsigned char)*p)) p++; - } - - *s = p; - - return ret; -} - -/* - <not> ::= '!' <filter> -*/ -static struct ldb_parse_tree *ldb_parse_not(void *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret; - const char *p = *s; - - if (*p != '!') { - return NULL; - } - p++; - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = LDB_OP_NOT; - ret->u.isnot.child = ldb_parse_filter(ret, &p); - if (!ret->u.isnot.child) { - talloc_free(ret); - return NULL; - } - - *s = p; - - return ret; -} - - - -/* - parse a filtercomp - <filtercomp> ::= <and> | <or> | <not> | <simple> -*/ -static struct ldb_parse_tree *ldb_parse_filtercomp(void *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret; - const char *p = *s; - - while (isspace((unsigned char)*p)) p++; - - switch (*p) { - case '&': - ret = ldb_parse_filterlist(mem_ctx, &p); - break; - - case '|': - ret = ldb_parse_filterlist(mem_ctx, &p); - break; - - case '!': - ret = ldb_parse_not(mem_ctx, &p); - break; - - case '(': - case ')': - return NULL; - - default: - ret = ldb_parse_simple(mem_ctx, &p); - - } - - *s = p; - return ret; -} - - - -/* - <filter> ::= '(' <filtercomp> ')' -*/ -static struct ldb_parse_tree *ldb_parse_filter(void *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret; - const char *p = *s; - - if (*p != '(') { - return NULL; - } - p++; - - ret = ldb_parse_filtercomp(mem_ctx, &p); - - if (*p != ')') { - return NULL; - } - p++; - - while (isspace((unsigned char)*p)) { - p++; - } - - *s = p; - - return ret; -} - - - -/* - main parser entry point. Takes a search string and returns a parse tree - - expression ::= <simple> | <filter> -*/ -struct ldb_parse_tree *ldb_parse_tree(void *mem_ctx, const char *s) -{ - if (s == NULL || *s == 0) { - s = "(|(objectClass=*)(distinguishedName=*))"; - } - - while (isspace((unsigned char)*s)) s++; - - if (*s == '(') { - return ldb_parse_filter(mem_ctx, &s); - } - - return ldb_parse_simple(mem_ctx, &s); -} - - diff --git a/source3/lib/ldb_compat.h b/source3/lib/ldb_compat.h deleted file mode 100644 index f05104a5c6..0000000000 --- a/source3/lib/ldb_compat.h +++ /dev/null @@ -1,87 +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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef __LDB_COMPAT_H__ -#define __LDB_COMPAT_H__ - -char *ldb_binary_encode(void *mem_ctx, struct ldb_val val); -struct ldb_parse_tree *ldb_parse_tree(void *mem_ctx, const char *s); - -/* - structures for ldb_parse_tree handling code -*/ -enum ldb_parse_op { LDB_OP_AND=1, LDB_OP_OR=2, LDB_OP_NOT=3, - LDB_OP_EQUALITY=4, LDB_OP_SUBSTRING=5, - LDB_OP_GREATER=6, LDB_OP_LESS=7, LDB_OP_PRESENT=8, - LDB_OP_APPROX=9, LDB_OP_EXTENDED=10 }; - -struct ldb_parse_tree { - enum ldb_parse_op operation; - union { - struct { - struct ldb_parse_tree *child; - } isnot; - struct { - const char *attr; - struct ldb_val value; - } equality; - struct { - const char *attr; - int start_with_wildcard; - int end_with_wildcard; - struct ldb_val **chunks; - } substring; - struct { - const char *attr; - } present; - struct { - const char *attr; - struct ldb_val value; - } comparison; - struct { - const char *attr; - int dnAttributes; - char *rule_id; - struct ldb_val value; - } extended; - struct { - unsigned int num_elements; - struct ldb_parse_tree **elements; - } list; - } u; -}; - -struct ldb_message_element { - unsigned int flags; - const char *name; - unsigned int num_values; - struct ldb_val *values; -}; - -struct ldb_control { - const char *oid; - int critical; - void *data; -}; - -#endif diff --git a/source3/wscript_build b/source3/wscript_build index 41ff19159a..c132e365e8 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -6,10 +6,6 @@ import samba_version, samba3 # enable building of public headers in the build tree bld.env.build_public_headers = 'include/public' -# these are includes which appear in public headers, but with #ifdef conditional -# compilation, so they are safe -bld.env.public_headers_skip = ['lib/ldb_compat.h'] - # s3 public headers refer to non-public headers bld.env.public_headers_allow_broken = True |