summaryrefslogtreecommitdiff
path: root/source3/lib/ldb_compat.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2011-07-05 10:14:12 +1000
committerAndrew Bartlett <abartlet@samba.org>2011-10-07 17:45:20 +1100
commit36b2227eca55e769813eecc97366ba18a2832fb3 (patch)
treee7ad966a443a67762814a256d1ef3446471b8d27 /source3/lib/ldb_compat.c
parented41edddde6b81b759d4b4c8d9e59ee541a37c0a (diff)
downloadsamba-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/lib/ldb_compat.c')
-rw-r--r--source3/lib/ldb_compat.c639
1 files changed, 0 insertions, 639 deletions
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);
-}
-
-