4 Copyright (C) Andrew Tridgell 2004
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 3 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, see <http://www.gnu.org/licenses/>.
27 * Component: ldb expression parsing
29 * Description: parse LDAP-like search expressions
31 * Author: Andrew Tridgell
36 - add RFC2254 binary string handling
37 - possibly add ~=, <= and >= handling
38 - expand the test suite
39 - add better parse error handling
43 #include "ldb_private.h"
44 #include "system/locale.h"
47 * Maximum depth of the filter parse tree, the value chosen is small enough to
48 * avoid triggering ASAN stack overflow checks. But large enough to be useful.
50 * On Windows clients the maximum number of levels of recursion allowed is 100.
51 * In the LDAP server, Windows restricts clients to 512 nested
54 #define LDB_MAX_PARSE_TREE_DEPTH 128
56 static int ldb_parse_hex2char(const char *x)
58 if (isxdigit(x[0]) && isxdigit(x[1])) {
59 const char h1 = x[0], h2 = x[1];
62 if (h1 >= 'a') c = h1 - (int)'a' + 10;
63 else if (h1 >= 'A') c = h1 - (int)'A' + 10;
64 else if (h1 >= '0') c = h1 - (int)'0';
66 if (h2 >= 'a') c += h2 - (int)'a' + 10;
67 else if (h2 >= 'A') c += h2 - (int)'A' + 10;
68 else if (h2 >= '0') c += h2 - (int)'0';
77 a filter is defined by:
78 <filter> ::= '(' <filtercomp> ')'
79 <filtercomp> ::= <and> | <or> | <not> | <simple>
80 <and> ::= '&' <filterlist>
81 <or> ::= '|' <filterlist>
82 <not> ::= '!' <filter>
83 <filterlist> ::= <filter> | <filter> <filterlist>
84 <simple> ::= <attributetype> <filtertype> <attributevalue>
85 <filtertype> ::= '=' | '~=' | '<=' | '>='
89 decode a RFC2254 binary string representation of a buffer.
92 struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str)
96 size_t slen = str?strlen(str):0;
98 ret.data = (uint8_t *)talloc_size(mem_ctx, slen+1);
100 if (ret.data == NULL) return ret;
102 for (i=j=0;i<slen;i++) {
103 if (str[i] == '\\') {
106 c = ldb_parse_hex2char(&str[i+1]);
108 talloc_free(ret.data);
109 memset(&ret, 0, sizeof(ret));
112 ((uint8_t *)ret.data)[j++] = c;
115 ((uint8_t *)ret.data)[j++] = str[i];
119 ((uint8_t *)ret.data)[j] = 0;
124 static bool need_encode(unsigned char cval)
126 if (cval < 0x20 || cval > 0x7E || strchr(" *()\\&|!\"", cval)) {
133 encode a blob as a RFC2254 binary string, escaping any
134 non-printable or '\' characters
136 char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val)
140 size_t len = val.length;
141 unsigned char *buf = val.data;
143 for (i=0;i<val.length;i++) {
144 if (need_encode(buf[i])) {
148 ret = talloc_array(mem_ctx, char, len+1);
149 if (ret == NULL) return NULL;
152 for (i=0;i<val.length;i++) {
153 if (need_encode(buf[i])) {
154 snprintf(ret+len, 4, "\\%02X", buf[i]);
167 encode a string as a RFC2254 binary string, escaping any
168 non-printable or '\' characters. This routine is suitable for use
169 in escaping user data in ldap filters.
171 char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string)
174 if (string == NULL) {
177 val.data = discard_const_p(uint8_t, string);
178 val.length = strlen(string);
179 return ldb_binary_encode(mem_ctx, val);
182 /* find the first matching wildcard */
183 static char *ldb_parse_find_wildcard(char *value)
186 value = strpbrk(value, "\\*");
187 if (value == NULL) return NULL;
189 if (value[0] == '\\') {
190 if (value[1] == '\0') return NULL;
195 if (value[0] == '*') return value;
201 /* return a NULL terminated list of binary strings representing the value
202 chunks separated by wildcards that makes the value portion of the filter
204 static struct ldb_val **ldb_wildcard_decode(TALLOC_CTX *mem_ctx, const char *string)
206 struct ldb_val **ret = NULL;
207 unsigned int val = 0;
210 wc = talloc_strdup(mem_ctx, string);
211 if (wc == NULL) return NULL;
215 wc = ldb_parse_find_wildcard(str);
225 ret = talloc_realloc(mem_ctx, ret, struct ldb_val *, val + 2);
226 if (ret == NULL) return NULL;
228 ret[val] = talloc(mem_ctx, struct ldb_val);
229 if (ret[val] == NULL) return NULL;
231 *(ret[val]) = ldb_binary_decode(mem_ctx, str);
232 if ((ret[val])->data == NULL) return NULL;
244 static struct ldb_parse_tree *ldb_parse_filter(
252 parse an extended match
260 the ':dn' part sets the dnAttributes boolean if present
261 the oid sets the rule_id string
264 static struct ldb_parse_tree *ldb_parse_extended(struct ldb_parse_tree *ret,
265 char *attr, char *value)
269 ret->operation = LDB_OP_EXTENDED;
270 ret->u.extended.value = ldb_binary_decode(ret, value);
271 if (ret->u.extended.value.data == NULL) goto failed;
273 p1 = strchr(attr, ':');
274 if (p1 == NULL) goto failed;
275 p2 = strchr(p1+1, ':');
280 ret->u.extended.attr = attr;
281 if (strcmp(p1+1, "dn") == 0) {
282 ret->u.extended.dnAttributes = 1;
284 ret->u.extended.rule_id = talloc_strdup(ret, p2+1);
285 if (ret->u.extended.rule_id == NULL) goto failed;
287 ret->u.extended.rule_id = NULL;
290 ret->u.extended.dnAttributes = 0;
291 ret->u.extended.rule_id = talloc_strdup(ret, p1+1);
292 if (ret->u.extended.rule_id == NULL) goto failed;
302 static enum ldb_parse_op ldb_parse_filtertype(TALLOC_CTX *mem_ctx, char **type, char **value, const char **s)
304 enum ldb_parse_op filter = 0;
305 char *name, *val, *k;
309 /* retrieve attributetype name */
312 if (*p == '@') { /* for internal attributes the first char can be @ */
316 while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-') || (*p == '.')) {
317 /* attribute names can only be alphanums */
321 if (*p == ':') { /* but extended searches have : and . chars too */
323 if (p == NULL) { /* malformed attribute name */
330 while (isspace((unsigned char)*p)) p++;
332 if (!strchr("=<>~:", *p)) {
337 name = (char *)talloc_memdup(mem_ctx, t, t1 - t + 1);
338 if (name == NULL) return 0;
341 /* retrieve filtertype */
344 filter = LDB_OP_EQUALITY;
345 } else if (*p != '\0' && *(p + 1) == '=') {
348 filter = LDB_OP_LESS;
352 filter = LDB_OP_GREATER;
356 filter = LDB_OP_APPROX;
360 filter = LDB_OP_EXTENDED;
371 while (isspace((unsigned char)*p)) p++;
376 while (*p && ((*p != ')') || ((*p == ')') && (*(p - 1) == '\\')))) p++;
378 val = (char *)talloc_memdup(mem_ctx, t, p - t + 1);
387 /* remove trailing spaces from value */
388 while ((k > val) && (isspace((unsigned char)*(k - 1)))) k--;
398 <simple> ::= <attributetype> <filtertype> <attributevalue>
400 static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char **s)
403 struct ldb_parse_tree *ret;
404 enum ldb_parse_op filtertype;
406 ret = talloc_zero(mem_ctx, struct ldb_parse_tree);
412 filtertype = ldb_parse_filtertype(ret, &attr, &value, s);
418 switch (filtertype) {
421 ret->operation = LDB_OP_PRESENT;
422 ret->u.present.attr = attr;
425 case LDB_OP_EQUALITY:
427 if (strcmp(value, "*") == 0) {
428 ret->operation = LDB_OP_PRESENT;
429 ret->u.present.attr = attr;
433 if (ldb_parse_find_wildcard(value) != NULL) {
434 ret->operation = LDB_OP_SUBSTRING;
435 ret->u.substring.attr = attr;
436 ret->u.substring.start_with_wildcard = 0;
437 ret->u.substring.end_with_wildcard = 0;
438 ret->u.substring.chunks = ldb_wildcard_decode(ret, value);
439 if (ret->u.substring.chunks == NULL){
444 ret->u.substring.start_with_wildcard = 1;
445 if (value[strlen(value) - 1] == '*')
446 ret->u.substring.end_with_wildcard = 1;
452 ret->operation = LDB_OP_EQUALITY;
453 ret->u.equality.attr = attr;
454 ret->u.equality.value = ldb_binary_decode(ret, value);
455 if (ret->u.equality.value.data == NULL) {
463 ret->operation = LDB_OP_GREATER;
464 ret->u.comparison.attr = attr;
465 ret->u.comparison.value = ldb_binary_decode(ret, value);
466 if (ret->u.comparison.value.data == NULL) {
474 ret->operation = LDB_OP_LESS;
475 ret->u.comparison.attr = attr;
476 ret->u.comparison.value = ldb_binary_decode(ret, value);
477 if (ret->u.comparison.value.data == NULL) {
485 ret->operation = LDB_OP_APPROX;
486 ret->u.comparison.attr = attr;
487 ret->u.comparison.value = ldb_binary_decode(ret, value);
488 if (ret->u.comparison.value.data == NULL) {
495 case LDB_OP_EXTENDED:
497 ret = ldb_parse_extended(ret, attr, value);
511 <and> ::= '&' <filterlist>
512 <or> ::= '|' <filterlist>
513 <filterlist> ::= <filter> | <filter> <filterlist>
515 static struct ldb_parse_tree *ldb_parse_filterlist(
521 struct ldb_parse_tree *ret, *next;
522 enum ldb_parse_op op;
537 while (isspace((unsigned char)*p)) p++;
539 ret = talloc(mem_ctx, struct ldb_parse_tree);
546 ret->u.list.num_elements = 1;
547 ret->u.list.elements = talloc(ret, struct ldb_parse_tree *);
548 if (!ret->u.list.elements) {
554 ret->u.list.elements[0] =
555 ldb_parse_filter(ret->u.list.elements, &p, depth, max_depth);
556 if (!ret->u.list.elements[0]) {
561 while (isspace((unsigned char)*p)) p++;
564 struct ldb_parse_tree **e;
569 next = ldb_parse_filter(
570 ret->u.list.elements, &p, depth, max_depth);
572 /* an invalid filter element */
576 e = talloc_realloc(ret, ret->u.list.elements,
577 struct ldb_parse_tree *,
578 ret->u.list.num_elements + 1);
584 ret->u.list.elements = e;
585 ret->u.list.elements[ret->u.list.num_elements] = next;
586 ret->u.list.num_elements++;
587 while (isspace((unsigned char)*p)) p++;
597 <not> ::= '!' <filter>
599 static struct ldb_parse_tree *ldb_parse_not(
605 struct ldb_parse_tree *ret;
613 ret = talloc(mem_ctx, struct ldb_parse_tree);
619 ret->operation = LDB_OP_NOT;
620 ret->u.isnot.child = ldb_parse_filter(ret, &p, depth, max_depth);
621 if (!ret->u.isnot.child) {
633 <filtercomp> ::= <and> | <or> | <not> | <simple>
635 static struct ldb_parse_tree *ldb_parse_filtercomp(
641 struct ldb_parse_tree *ret;
644 while (isspace((unsigned char)*p)) p++;
648 ret = ldb_parse_filterlist(mem_ctx, &p, depth, max_depth);
652 ret = ldb_parse_filterlist(mem_ctx, &p, depth, max_depth);
656 ret = ldb_parse_not(mem_ctx, &p, depth, max_depth);
664 ret = ldb_parse_simple(mem_ctx, &p);
673 <filter> ::= '(' <filtercomp> ')'
675 static struct ldb_parse_tree *ldb_parse_filter(
681 struct ldb_parse_tree *ret;
685 * Check the depth of the parse tree, and reject the input if
686 * max_depth exceeded. This avoids stack overflow
689 if (depth > max_depth) {
699 ret = ldb_parse_filtercomp(mem_ctx, &p, depth, max_depth);
706 while (isspace((unsigned char)*p)) {
717 main parser entry point. Takes a search string and returns a parse tree
719 expression ::= <simple> | <filter>
721 struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s)
725 while (s && isspace((unsigned char)*s)) s++;
727 if (s == NULL || *s == 0) {
728 s = "(|(objectClass=*)(distinguishedName=*))";
732 return ldb_parse_filter(
733 mem_ctx, &s, depth, LDB_MAX_PARSE_TREE_DEPTH);
736 return ldb_parse_simple(mem_ctx, &s);
741 construct a ldap parse filter given a parse tree
743 char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree)
752 switch (tree->operation) {
755 ret = talloc_asprintf(mem_ctx, "(%c", tree->operation==LDB_OP_AND?'&':'|');
756 if (ret == NULL) return NULL;
757 for (i=0;i<tree->u.list.num_elements;i++) {
758 s = ldb_filter_from_tree(mem_ctx, tree->u.list.elements[i]);
763 s2 = talloc_asprintf_append(ret, "%s", s);
771 s = talloc_asprintf_append(ret, ")");
778 s = ldb_filter_from_tree(mem_ctx, tree->u.isnot.child);
779 if (s == NULL) return NULL;
781 ret = talloc_asprintf(mem_ctx, "(!%s)", s);
784 case LDB_OP_EQUALITY:
785 s = ldb_binary_encode(mem_ctx, tree->u.equality.value);
786 if (s == NULL) return NULL;
787 ret = talloc_asprintf(mem_ctx, "(%s=%s)",
788 tree->u.equality.attr, s);
791 case LDB_OP_SUBSTRING:
792 ret = talloc_asprintf(mem_ctx, "(%s=%s", tree->u.substring.attr,
793 tree->u.substring.start_with_wildcard?"*":"");
794 if (ret == NULL) return NULL;
795 for (i = 0; tree->u.substring.chunks && tree->u.substring.chunks[i]; i++) {
796 s2 = ldb_binary_encode(mem_ctx, *(tree->u.substring.chunks[i]));
801 if (tree->u.substring.chunks[i+1] ||
802 tree->u.substring.end_with_wildcard) {
803 s = talloc_asprintf_append(ret, "%s*", s2);
805 s = talloc_asprintf_append(ret, "%s", s2);
813 s = talloc_asprintf_append(ret, ")");
821 s = ldb_binary_encode(mem_ctx, tree->u.equality.value);
822 if (s == NULL) return NULL;
823 ret = talloc_asprintf(mem_ctx, "(%s>=%s)",
824 tree->u.equality.attr, s);
828 s = ldb_binary_encode(mem_ctx, tree->u.equality.value);
829 if (s == NULL) return NULL;
830 ret = talloc_asprintf(mem_ctx, "(%s<=%s)",
831 tree->u.equality.attr, s);
835 ret = talloc_asprintf(mem_ctx, "(%s=*)", tree->u.present.attr);
838 s = ldb_binary_encode(mem_ctx, tree->u.equality.value);
839 if (s == NULL) return NULL;
840 ret = talloc_asprintf(mem_ctx, "(%s~=%s)",
841 tree->u.equality.attr, s);
844 case LDB_OP_EXTENDED:
845 s = ldb_binary_encode(mem_ctx, tree->u.extended.value);
846 if (s == NULL) return NULL;
847 ret = talloc_asprintf(mem_ctx, "(%s%s%s%s:=%s)",
848 tree->u.extended.attr?tree->u.extended.attr:"",
849 tree->u.extended.dnAttributes?":dn":"",
850 tree->u.extended.rule_id?":":"",
851 tree->u.extended.rule_id?tree->u.extended.rule_id:"",
862 walk a parse tree, calling the provided callback on each node
864 int ldb_parse_tree_walk(struct ldb_parse_tree *tree,
865 int (*callback)(struct ldb_parse_tree *tree, void *),
866 void *private_context)
871 ret = callback(tree, private_context);
872 if (ret != LDB_SUCCESS) {
876 switch (tree->operation) {
879 for (i=0;i<tree->u.list.num_elements;i++) {
880 ret = ldb_parse_tree_walk(tree->u.list.elements[i], callback, private_context);
881 if (ret != LDB_SUCCESS) {
887 ret = ldb_parse_tree_walk(tree->u.isnot.child, callback, private_context);
888 if (ret != LDB_SUCCESS) {
892 case LDB_OP_EQUALITY:
896 case LDB_OP_SUBSTRING:
898 case LDB_OP_EXTENDED:
904 struct parse_tree_attr_replace_ctx {
910 callback for ldb_parse_tree_attr_replace()
912 static int parse_tree_attr_replace(struct ldb_parse_tree *tree, void *private_context)
914 struct parse_tree_attr_replace_ctx *ctx = private_context;
915 switch (tree->operation) {
916 case LDB_OP_EQUALITY:
920 if (ldb_attr_cmp(tree->u.equality.attr, ctx->attr) == 0) {
921 tree->u.equality.attr = ctx->replace;
924 case LDB_OP_SUBSTRING:
925 if (ldb_attr_cmp(tree->u.substring.attr, ctx->attr) == 0) {
926 tree->u.substring.attr = ctx->replace;
930 if (ldb_attr_cmp(tree->u.present.attr, ctx->attr) == 0) {
931 tree->u.present.attr = ctx->replace;
934 case LDB_OP_EXTENDED:
935 if (tree->u.extended.attr &&
936 ldb_attr_cmp(tree->u.extended.attr, ctx->attr) == 0) {
937 tree->u.extended.attr = ctx->replace;
947 replace any occurrences of an attribute name in the parse tree with a
950 void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree,
954 struct parse_tree_attr_replace_ctx ctx;
957 ctx.replace = replace;
959 ldb_parse_tree_walk(tree, parse_tree_attr_replace, &ctx);
963 shallow copy a tree - copying only the elements array so that the caller
964 can safely add new elements without changing the message
966 struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx,
967 const struct ldb_parse_tree *ot)
970 struct ldb_parse_tree *nt;
972 nt = talloc(mem_ctx, struct ldb_parse_tree);
979 switch (ot->operation) {
982 nt->u.list.elements = talloc_array(nt, struct ldb_parse_tree *,
983 ot->u.list.num_elements);
984 if (!nt->u.list.elements) {
989 for (i=0;i<ot->u.list.num_elements;i++) {
990 nt->u.list.elements[i] =
991 ldb_parse_tree_copy_shallow(nt->u.list.elements,
992 ot->u.list.elements[i]);
993 if (!nt->u.list.elements[i]) {
1000 nt->u.isnot.child = ldb_parse_tree_copy_shallow(nt,
1002 if (!nt->u.isnot.child) {
1007 case LDB_OP_EQUALITY:
1008 case LDB_OP_GREATER:
1011 case LDB_OP_SUBSTRING:
1012 case LDB_OP_PRESENT:
1013 case LDB_OP_EXTENDED: