Line data Source code
1 : /*
2 : ldb database library
3 :
4 : Copyright (C) Andrew Tridgell 2004-2005
5 : Copyright (C) Simo Sorce 2005
6 :
7 : ** NOTE! The following LGPL license applies to the ldb
8 : ** library. This does NOT imply that all of Samba is released
9 : ** under the LGPL
10 :
11 : This library is free software; you can redistribute it and/or
12 : modify it under the terms of the GNU Lesser General Public
13 : License as published by the Free Software Foundation; either
14 : version 3 of the License, or (at your option) any later version.
15 :
16 : This library is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 : Lesser General Public License for more details.
20 :
21 : You should have received a copy of the GNU Lesser General Public
22 : License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 : */
24 :
25 : /*
26 : * Name: ldb
27 : *
28 : * Component: ldb expression matching
29 : *
30 : * Description: ldb expression matching
31 : *
32 : * Author: Andrew Tridgell
33 : */
34 :
35 : #include "ldb_private.h"
36 : #include "dlinklist.h"
37 : #include "ldb_handlers.h"
38 :
39 : /*
40 : check if the scope matches in a search result
41 : */
42 232376395 : int ldb_match_scope(struct ldb_context *ldb,
43 : struct ldb_dn *base,
44 : struct ldb_dn *dn,
45 : enum ldb_scope scope)
46 : {
47 232376395 : int ret = 0;
48 :
49 232376395 : if (base == NULL || dn == NULL) {
50 0 : return 1;
51 : }
52 :
53 232376395 : switch (scope) {
54 32 : case LDB_SCOPE_BASE:
55 32 : if (ldb_dn_compare(base, dn) == 0) {
56 32 : ret = 1;
57 : }
58 0 : break;
59 :
60 343428 : case LDB_SCOPE_ONELEVEL:
61 343428 : if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) {
62 71055 : if (ldb_dn_compare_base(base, dn) == 0) {
63 33553 : ret = 1;
64 : }
65 : }
66 342815 : break;
67 :
68 232032935 : case LDB_SCOPE_SUBTREE:
69 : default:
70 232032935 : if (ldb_dn_compare_base(base, dn) == 0) {
71 138247507 : ret = 1;
72 : }
73 229069436 : break;
74 : }
75 :
76 229412251 : return ret;
77 : }
78 :
79 :
80 : /*
81 : match if node is present
82 : */
83 54715461 : static int ldb_match_present(struct ldb_context *ldb,
84 : const struct ldb_message *msg,
85 : const struct ldb_parse_tree *tree,
86 : enum ldb_scope scope, bool *matched)
87 : {
88 1947096 : const struct ldb_schema_attribute *a;
89 1947096 : struct ldb_message_element *el;
90 :
91 54715461 : if (ldb_attr_dn(tree->u.present.attr) == 0) {
92 5658426 : *matched = true;
93 5658426 : return LDB_SUCCESS;
94 : }
95 :
96 49057035 : el = ldb_msg_find_element(msg, tree->u.present.attr);
97 49057035 : if (el == NULL) {
98 6309363 : *matched = false;
99 6309363 : return LDB_SUCCESS;
100 : }
101 :
102 42747672 : a = ldb_schema_attribute_by_name(ldb, el->name);
103 42747672 : if (!a) {
104 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
105 : }
106 :
107 42747672 : if (a->syntax->operator_fn) {
108 : unsigned int i;
109 450549 : for (i = 0; i < el->num_values; i++) {
110 450549 : int ret = a->syntax->operator_fn(ldb, LDB_OP_PRESENT, a, &el->values[i], NULL, matched);
111 450549 : if (ret != LDB_SUCCESS) return ret;
112 450549 : if (*matched) return LDB_SUCCESS;
113 : }
114 0 : *matched = false;
115 0 : return LDB_SUCCESS;
116 : }
117 :
118 42297123 : *matched = true;
119 42297123 : return LDB_SUCCESS;
120 : }
121 :
122 5618225 : static int ldb_match_comparison(struct ldb_context *ldb,
123 : const struct ldb_message *msg,
124 : const struct ldb_parse_tree *tree,
125 : enum ldb_scope scope,
126 : enum ldb_parse_op comp_op, bool *matched)
127 : {
128 912 : unsigned int i;
129 912 : struct ldb_message_element *el;
130 912 : const struct ldb_schema_attribute *a;
131 :
132 : /* FIXME: APPROX comparison not handled yet */
133 5618225 : if (comp_op == LDB_OP_APPROX) {
134 0 : return LDB_ERR_INAPPROPRIATE_MATCHING;
135 : }
136 :
137 5618225 : el = ldb_msg_find_element(msg, tree->u.comparison.attr);
138 5618225 : if (el == NULL) {
139 123627 : *matched = false;
140 123627 : return LDB_SUCCESS;
141 : }
142 :
143 5494598 : a = ldb_schema_attribute_by_name(ldb, el->name);
144 5494598 : if (!a) {
145 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
146 : }
147 :
148 8385097 : for (i = 0; i < el->num_values; i++) {
149 5494624 : if (a->syntax->operator_fn) {
150 842 : int ret;
151 1844 : ret = a->syntax->operator_fn(ldb, comp_op, a, &el->values[i], &tree->u.comparison.value, matched);
152 1844 : if (ret != LDB_SUCCESS) return ret;
153 1844 : if (*matched) return LDB_SUCCESS;
154 : } else {
155 5492780 : int ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value);
156 :
157 5492780 : if (ret == 0) {
158 1947 : *matched = true;
159 1947 : return LDB_SUCCESS;
160 : }
161 5490833 : if (ret > 0 && comp_op == LDB_OP_GREATER) {
162 2600305 : *matched = true;
163 2600305 : return LDB_SUCCESS;
164 : }
165 2890528 : if (ret < 0 && comp_op == LDB_OP_LESS) {
166 755 : *matched = true;
167 755 : return LDB_SUCCESS;
168 : }
169 : }
170 : }
171 :
172 2890473 : *matched = false;
173 2890473 : return LDB_SUCCESS;
174 : }
175 :
176 : /*
177 : match a simple leaf node
178 : */
179 280751517 : static int ldb_match_equality(struct ldb_context *ldb,
180 : const struct ldb_message *msg,
181 : const struct ldb_parse_tree *tree,
182 : enum ldb_scope scope,
183 : bool *matched)
184 : {
185 6096700 : unsigned int i;
186 6096700 : struct ldb_message_element *el;
187 6096700 : const struct ldb_schema_attribute *a;
188 6096700 : struct ldb_dn *valuedn;
189 6096700 : int ret;
190 :
191 280751517 : if (ldb_attr_dn(tree->u.equality.attr) == 0) {
192 183036 : valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value);
193 183036 : if (valuedn == NULL) {
194 0 : return LDB_ERR_INVALID_DN_SYNTAX;
195 : }
196 :
197 183036 : ret = ldb_dn_compare(msg->dn, valuedn);
198 :
199 183036 : talloc_free(valuedn);
200 :
201 183036 : *matched = (ret == 0);
202 183036 : return LDB_SUCCESS;
203 : }
204 :
205 : /* TODO: handle the "*" case derived from an extended search
206 : operation without the attribute type defined */
207 280568481 : el = ldb_msg_find_element(msg, tree->u.equality.attr);
208 280568481 : if (el == NULL) {
209 129596723 : *matched = false;
210 129596723 : return LDB_SUCCESS;
211 : }
212 :
213 150971758 : a = ldb_schema_attribute_by_name(ldb, el->name);
214 150971758 : if (a == NULL) {
215 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
216 : }
217 :
218 282711365 : for (i=0;i<el->num_values;i++) {
219 260310866 : if (a->syntax->operator_fn) {
220 29209588 : ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a,
221 28694230 : &tree->u.equality.value, &el->values[i], matched);
222 28694230 : if (ret != LDB_SUCCESS) return ret;
223 28694230 : if (*matched) return LDB_SUCCESS;
224 : } else {
225 231616636 : if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value,
226 231616636 : &el->values[i]) == 0) {
227 101102746 : *matched = true;
228 101102746 : return LDB_SUCCESS;
229 : }
230 : }
231 : }
232 :
233 22400499 : *matched = false;
234 22400499 : return LDB_SUCCESS;
235 : }
236 :
237 3226842 : static int ldb_wildcard_compare(struct ldb_context *ldb,
238 : const struct ldb_parse_tree *tree,
239 : const struct ldb_val value, bool *matched)
240 : {
241 197 : const struct ldb_schema_attribute *a;
242 197 : struct ldb_val val;
243 197 : struct ldb_val cnk;
244 197 : struct ldb_val *chunk;
245 3226842 : uint8_t *save_p = NULL;
246 3226842 : unsigned int c = 0;
247 :
248 3226842 : if (tree->operation != LDB_OP_SUBSTRING) {
249 1 : *matched = false;
250 1 : return LDB_ERR_INAPPROPRIATE_MATCHING;
251 : }
252 :
253 3226841 : a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr);
254 3226841 : if (!a) {
255 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
256 : }
257 :
258 3226841 : if (tree->u.substring.chunks == NULL) {
259 3 : *matched = false;
260 3 : return LDB_SUCCESS;
261 : }
262 :
263 : /* No need to just copy this value for a binary match */
264 3226838 : if (a->syntax->canonicalise_fn != ldb_handler_copy) {
265 2397408 : if (a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) {
266 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
267 : }
268 :
269 : /*
270 : * Only set save_p if we allocate (call
271 : * a->syntax->canonicalise_fn()), as we
272 : * talloc_free(save_p) below to clean up
273 : */
274 2397408 : save_p = val.data;
275 : } else {
276 829430 : val = value;
277 : }
278 :
279 3226838 : cnk.data = NULL;
280 :
281 3226838 : if ( ! tree->u.substring.start_with_wildcard ) {
282 2367082 : uint8_t *cnk_to_free = NULL;
283 :
284 2367082 : chunk = tree->u.substring.chunks[c];
285 : /* No need to just copy this value for a binary match */
286 2367082 : if (a->syntax->canonicalise_fn != ldb_handler_copy) {
287 2365659 : if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) {
288 0 : goto mismatch;
289 : }
290 :
291 2365659 : cnk_to_free = cnk.data;
292 : } else {
293 1423 : cnk = *chunk;
294 : }
295 :
296 : /* This deals with wildcard prefix searches on binary attributes (eg objectGUID) */
297 2367082 : if (cnk.length > val.length) {
298 58466 : TALLOC_FREE(cnk_to_free);
299 58466 : goto mismatch;
300 : }
301 : /*
302 : * Empty strings are returned as length 0. Ensure
303 : * we can cope with this.
304 : */
305 2308616 : if (cnk.length == 0) {
306 0 : TALLOC_FREE(cnk_to_free);
307 0 : goto mismatch;
308 : }
309 :
310 2308616 : if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) {
311 1852293 : TALLOC_FREE(cnk_to_free);
312 1852293 : goto mismatch;
313 : }
314 :
315 456323 : val.length -= cnk.length;
316 456323 : val.data += cnk.length;
317 456323 : c++;
318 456323 : TALLOC_FREE(cnk_to_free);
319 456323 : cnk.data = NULL;
320 : }
321 :
322 1316840 : while (tree->u.substring.chunks[c]) {
323 76 : uint8_t *p;
324 859823 : uint8_t *cnk_to_free = NULL;
325 :
326 859823 : chunk = tree->u.substring.chunks[c];
327 : /* No need to just copy this value for a binary match */
328 859823 : if (a->syntax->canonicalise_fn != ldb_handler_copy) {
329 31812 : if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) {
330 0 : goto mismatch;
331 : }
332 :
333 31812 : cnk_to_free = cnk.data;
334 : } else {
335 828011 : cnk = *chunk;
336 : }
337 : /*
338 : * Empty strings are returned as length 0. Ensure
339 : * we can cope with this.
340 : */
341 859823 : if (cnk.length == 0) {
342 0 : TALLOC_FREE(cnk_to_free);
343 0 : goto mismatch;
344 : }
345 859823 : if (cnk.length > val.length) {
346 22099 : TALLOC_FREE(cnk_to_free);
347 22099 : goto mismatch;
348 : }
349 :
350 837724 : if ( (tree->u.substring.chunks[c + 1]) == NULL &&
351 838309 : (! tree->u.substring.end_with_wildcard) ) {
352 : /*
353 : * The last bit, after all the asterisks, must match
354 : * exactly the last bit of the string.
355 : */
356 23 : int cmp;
357 9096 : p = val.data + val.length - cnk.length;
358 9096 : cmp = memcmp(p,
359 9096 : cnk.data,
360 : cnk.length);
361 9096 : TALLOC_FREE(cnk_to_free);
362 :
363 9096 : if (cmp != 0) {
364 8397 : goto mismatch;
365 : }
366 : } else {
367 : /*
368 : * Values might be binary blobs. Don't use string
369 : * search, but memory search instead.
370 : */
371 828628 : p = memmem((const void *)val.data, val.length,
372 828628 : (const void *)cnk.data, cnk.length);
373 828628 : if (p == NULL) {
374 828566 : TALLOC_FREE(cnk_to_free);
375 828566 : goto mismatch;
376 : }
377 : /* move val to the end of the match */
378 62 : p += cnk.length;
379 62 : val.length -= (p - val.data);
380 62 : val.data = p;
381 62 : TALLOC_FREE(cnk_to_free);
382 : }
383 748 : c++;
384 : }
385 :
386 457017 : talloc_free(save_p);
387 457017 : *matched = true;
388 457017 : return LDB_SUCCESS;
389 :
390 2769821 : mismatch:
391 2769821 : *matched = false;
392 2769821 : talloc_free(save_p);
393 2769821 : return LDB_SUCCESS;
394 : }
395 :
396 : /*
397 : match a simple leaf node
398 : */
399 3826476 : static int ldb_match_substring(struct ldb_context *ldb,
400 : const struct ldb_message *msg,
401 : const struct ldb_parse_tree *tree,
402 : enum ldb_scope scope, bool *matched)
403 : {
404 175 : unsigned int i;
405 175 : struct ldb_message_element *el;
406 :
407 3826476 : el = ldb_msg_find_element(msg, tree->u.substring.attr);
408 3826476 : if (el == NULL) {
409 599825 : *matched = false;
410 599825 : return LDB_SUCCESS;
411 : }
412 :
413 5996469 : for (i = 0; i < el->num_values; i++) {
414 197 : int ret;
415 3226809 : ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched);
416 3226809 : if (ret != LDB_SUCCESS) return ret;
417 3226809 : if (*matched) return LDB_SUCCESS;
418 : }
419 :
420 2769660 : *matched = false;
421 2769660 : return LDB_SUCCESS;
422 : }
423 :
424 :
425 : /*
426 : bitwise and/or comparator depending on oid
427 : */
428 4499141 : static int ldb_comparator_bitmask(const char *oid, const struct ldb_val *v1, const struct ldb_val *v2,
429 : bool *matched)
430 : {
431 135433 : uint64_t i1, i2;
432 135433 : char ibuf[100];
433 4499141 : char *endptr = NULL;
434 :
435 4499141 : if (v1->length >= sizeof(ibuf)-1) {
436 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
437 : }
438 4499141 : memcpy(ibuf, (char *)v1->data, v1->length);
439 4499141 : ibuf[v1->length] = 0;
440 4499141 : i1 = strtoull(ibuf, &endptr, 0);
441 4499141 : if (endptr != NULL) {
442 4499141 : if (endptr == ibuf || *endptr != 0) {
443 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
444 : }
445 : }
446 :
447 4499141 : if (v2->length >= sizeof(ibuf)-1) {
448 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
449 : }
450 4499141 : endptr = NULL;
451 4499141 : memcpy(ibuf, (char *)v2->data, v2->length);
452 4499141 : ibuf[v2->length] = 0;
453 4499141 : i2 = strtoull(ibuf, &endptr, 0);
454 4499141 : if (endptr != NULL) {
455 4499141 : if (endptr == ibuf || *endptr != 0) {
456 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
457 : }
458 : }
459 4499141 : if (strcmp(LDB_OID_COMPARATOR_AND, oid) == 0) {
460 4497457 : *matched = ((i1 & i2) == i2);
461 1684 : } else if (strcmp(LDB_OID_COMPARATOR_OR, oid) == 0) {
462 1684 : *matched = ((i1 & i2) != 0);
463 : } else {
464 0 : return LDB_ERR_INAPPROPRIATE_MATCHING;
465 : }
466 4363708 : return LDB_SUCCESS;
467 : }
468 :
469 4504302 : static int ldb_match_bitmask(struct ldb_context *ldb,
470 : const char *oid,
471 : const struct ldb_message *msg,
472 : const char *attribute_to_match,
473 : const struct ldb_val *value_to_match,
474 : bool *matched)
475 : {
476 135480 : unsigned int i;
477 135480 : struct ldb_message_element *el;
478 :
479 : /* find the message element */
480 4504302 : el = ldb_msg_find_element(msg, attribute_to_match);
481 4504302 : if (el == NULL) {
482 5175 : *matched = false;
483 5175 : return LDB_SUCCESS;
484 : }
485 :
486 6543206 : for (i=0;i<el->num_values;i++) {
487 135433 : int ret;
488 4499141 : struct ldb_val *v = &el->values[i];
489 :
490 4499141 : ret = ldb_comparator_bitmask(oid, v, value_to_match, matched);
491 4499141 : if (ret != LDB_SUCCESS) {
492 0 : return ret;
493 : }
494 4499141 : if (*matched) {
495 2379610 : return LDB_SUCCESS;
496 : }
497 : }
498 :
499 2044065 : *matched = false;
500 2044065 : return LDB_SUCCESS;
501 : }
502 :
503 : /*
504 : always return false
505 : */
506 3373 : static int ldb_comparator_false(struct ldb_context *ldb,
507 : const char *oid,
508 : const struct ldb_message *msg,
509 : const char *attribute_to_match,
510 : const struct ldb_val *value_to_match,
511 : bool *matched)
512 : {
513 3373 : *matched = false;
514 3373 : return LDB_SUCCESS;
515 : }
516 :
517 :
518 17028002 : static const struct ldb_extended_match_rule *ldb_find_extended_match_rule(struct ldb_context *ldb,
519 : const char *oid)
520 : {
521 622450 : struct ldb_extended_match_entry *extended_match_rule;
522 :
523 17028002 : for (extended_match_rule = ldb->extended_match_rules;
524 60372628 : extended_match_rule;
525 43344626 : extended_match_rule = extended_match_rule->next) {
526 55896826 : if (strcmp(extended_match_rule->rule->oid, oid) == 0) {
527 12552200 : return extended_match_rule->rule;
528 : }
529 : }
530 :
531 4396731 : return NULL;
532 : }
533 :
534 :
535 : /*
536 : extended match, handles things like bitops
537 : */
538 12552203 : static int ldb_match_extended(struct ldb_context *ldb,
539 : const struct ldb_message *msg,
540 : const struct ldb_parse_tree *tree,
541 : enum ldb_scope scope, bool *matched)
542 : {
543 543379 : const struct ldb_extended_match_rule *rule;
544 :
545 12552203 : if (tree->u.extended.dnAttributes) {
546 : /* FIXME: We really need to find out what this ":dn" part in
547 : * an extended match means and how to handle it. For now print
548 : * only a warning to have s3 winbind and other tools working
549 : * against us. - Matthias */
550 912 : ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb: dnAttributes extended match not supported yet");
551 : }
552 12552203 : if (tree->u.extended.rule_id == NULL) {
553 0 : ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-rule extended matches not supported yet");
554 0 : return LDB_ERR_INAPPROPRIATE_MATCHING;
555 : }
556 12552203 : if (tree->u.extended.attr == NULL) {
557 0 : ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-attribute extended matches not supported yet");
558 0 : return LDB_ERR_INAPPROPRIATE_MATCHING;
559 : }
560 :
561 12552203 : rule = ldb_find_extended_match_rule(ldb, tree->u.extended.rule_id);
562 12552203 : if (rule == NULL) {
563 3 : *matched = false;
564 3 : ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s",
565 3 : tree->u.extended.rule_id);
566 3 : return LDB_SUCCESS;
567 : }
568 :
569 12552200 : return rule->callback(ldb, rule->oid, msg,
570 12008821 : tree->u.extended.attr,
571 : &tree->u.extended.value, matched);
572 : }
573 :
574 751200440 : static bool ldb_must_suppress_match(const struct ldb_message *msg,
575 : const struct ldb_parse_tree *tree)
576 : {
577 751200440 : const char *attr = NULL;
578 751200440 : struct ldb_message_element *el = NULL;
579 :
580 751200440 : attr = ldb_parse_tree_get_attr(tree);
581 751200440 : if (attr == NULL) {
582 396818925 : return false;
583 : }
584 :
585 : /* find the message element */
586 344917096 : el = ldb_msg_find_element(msg, attr);
587 344917096 : if (el == NULL) {
588 139293495 : return false;
589 : }
590 :
591 202446105 : return ldb_msg_element_is_inaccessible(el);
592 : }
593 :
594 : /*
595 : Check if a particular message will match the given filter
596 :
597 : set *matched to true if it matches, false otherwise
598 :
599 : returns LDB_SUCCESS or an error
600 :
601 : this is a recursive function, and does short-circuit evaluation
602 : */
603 763752643 : int ldb_match_message(struct ldb_context *ldb,
604 : const struct ldb_message *msg,
605 : const struct ldb_parse_tree *tree,
606 : enum ldb_scope scope, bool *matched)
607 : {
608 18052681 : unsigned int i;
609 18052681 : int ret;
610 :
611 763752643 : *matched = false;
612 :
613 763752643 : if (scope != LDB_SCOPE_BASE && ldb_dn_is_special(msg->dn)) {
614 : /* don't match special records except on base searches */
615 0 : return LDB_SUCCESS;
616 : }
617 :
618 : /*
619 : * Suppress matches on confidential attributes (handled
620 : * manually in extended matches as these can do custom things
621 : * like read other parts of the DB or other attributes).
622 : */
623 763752643 : if (tree->operation != LDB_OP_EXTENDED) {
624 751200440 : if (ldb_must_suppress_match(msg, tree)) {
625 5417 : return LDB_SUCCESS;
626 : }
627 : }
628 :
629 763747226 : switch (tree->operation) {
630 135664283 : case LDB_OP_AND:
631 385461100 : for (i=0;i<tree->u.list.num_elements;i++) {
632 269918208 : ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched);
633 269918208 : if (ret != LDB_SUCCESS) return ret;
634 269918193 : if (!*matched) return LDB_SUCCESS;
635 : }
636 115542892 : *matched = true;
637 115542892 : return LDB_SUCCESS;
638 :
639 133831053 : case LDB_OP_OR:
640 178527892 : for (i=0;i<tree->u.list.num_elements;i++) {
641 172466043 : ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched);
642 172466043 : if (ret != LDB_SUCCESS) return ret;
643 172466043 : if (*matched) return LDB_SUCCESS;
644 : }
645 6061849 : *matched = false;
646 6061849 : return LDB_SUCCESS;
647 :
648 130235665 : case LDB_OP_NOT:
649 130235665 : ret = ldb_match_message(ldb, msg, tree->u.isnot.child, scope, matched);
650 130235665 : if (ret != LDB_SUCCESS) return ret;
651 130235665 : *matched = ! *matched;
652 130235665 : return LDB_SUCCESS;
653 :
654 280751517 : case LDB_OP_EQUALITY:
655 280751517 : return ldb_match_equality(ldb, msg, tree, scope, matched);
656 :
657 3826476 : case LDB_OP_SUBSTRING:
658 3826476 : return ldb_match_substring(ldb, msg, tree, scope, matched);
659 :
660 5553330 : case LDB_OP_GREATER:
661 5553330 : return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER, matched);
662 :
663 64895 : case LDB_OP_LESS:
664 64895 : return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS, matched);
665 :
666 54715461 : case LDB_OP_PRESENT:
667 54715461 : return ldb_match_present(ldb, msg, tree, scope, matched);
668 :
669 0 : case LDB_OP_APPROX:
670 0 : return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_APPROX, matched);
671 :
672 12552203 : case LDB_OP_EXTENDED:
673 12552203 : return ldb_match_extended(ldb, msg, tree, scope, matched);
674 : }
675 :
676 0 : return LDB_ERR_INAPPROPRIATE_MATCHING;
677 : }
678 :
679 : /*
680 : return 0 if the given parse tree matches the given message. Assumes
681 : the message is in sorted order
682 :
683 : return 1 if it matches, and 0 if it doesn't match
684 : */
685 :
686 0 : int ldb_match_msg(struct ldb_context *ldb,
687 : const struct ldb_message *msg,
688 : const struct ldb_parse_tree *tree,
689 : struct ldb_dn *base,
690 : enum ldb_scope scope)
691 : {
692 0 : bool matched;
693 0 : int ret;
694 :
695 0 : if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) {
696 0 : return 0;
697 : }
698 :
699 0 : ret = ldb_match_message(ldb, msg, tree, scope, &matched);
700 0 : if (ret != LDB_SUCCESS) {
701 : /* to match the old API, we need to consider this a
702 : failure to match */
703 0 : return 0;
704 : }
705 0 : return matched?1:0;
706 : }
707 :
708 254 : int ldb_match_msg_error(struct ldb_context *ldb,
709 : const struct ldb_message *msg,
710 : const struct ldb_parse_tree *tree,
711 : struct ldb_dn *base,
712 : enum ldb_scope scope,
713 : bool *matched)
714 : {
715 254 : if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) {
716 0 : *matched = false;
717 0 : return LDB_SUCCESS;
718 : }
719 :
720 254 : return ldb_match_message(ldb, msg, tree, scope, matched);
721 : }
722 :
723 890564 : int ldb_match_msg_objectclass(const struct ldb_message *msg,
724 : const char *objectclass)
725 : {
726 29180 : unsigned int i;
727 890564 : struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass");
728 890564 : if (!el) {
729 0 : return 0;
730 : }
731 3562241 : for (i=0; i < el->num_values; i++) {
732 3562228 : if (ldb_attr_cmp((const char *)el->values[i].data, objectclass) == 0) {
733 861371 : return 1;
734 : }
735 : }
736 13 : return 0;
737 : }
738 :
739 749029 : _PRIVATE_ int ldb_register_extended_match_rules(struct ldb_context *ldb)
740 : {
741 13261 : struct ldb_extended_match_rule *bitmask_and;
742 13261 : struct ldb_extended_match_rule *bitmask_or;
743 13261 : struct ldb_extended_match_rule *always_false;
744 13261 : int ret;
745 :
746 : /* Register bitmask-and match */
747 749029 : bitmask_and = talloc_zero(ldb, struct ldb_extended_match_rule);
748 749029 : if (bitmask_and == NULL) {
749 0 : return LDB_ERR_OPERATIONS_ERROR;
750 : }
751 :
752 749029 : bitmask_and->oid = LDB_OID_COMPARATOR_AND;
753 749029 : bitmask_and->callback = ldb_match_bitmask;
754 :
755 749029 : ret = ldb_register_extended_match_rule(ldb, bitmask_and);
756 749029 : if (ret != LDB_SUCCESS) {
757 0 : return ret;
758 : }
759 :
760 : /* Register bitmask-or match */
761 749029 : bitmask_or = talloc_zero(ldb, struct ldb_extended_match_rule);
762 749029 : if (bitmask_or == NULL) {
763 0 : return LDB_ERR_OPERATIONS_ERROR;
764 : }
765 :
766 749029 : bitmask_or->oid = LDB_OID_COMPARATOR_OR;
767 749029 : bitmask_or->callback = ldb_match_bitmask;
768 :
769 749029 : ret = ldb_register_extended_match_rule(ldb, bitmask_or);
770 749029 : if (ret != LDB_SUCCESS) {
771 0 : return ret;
772 : }
773 :
774 : /* Register always-false match */
775 749029 : always_false = talloc_zero(ldb, struct ldb_extended_match_rule);
776 749029 : if (always_false == NULL) {
777 0 : return LDB_ERR_OPERATIONS_ERROR;
778 : }
779 :
780 749029 : always_false->oid = SAMBA_LDAP_MATCH_ALWAYS_FALSE;
781 749029 : always_false->callback = ldb_comparator_false;
782 :
783 749029 : ret = ldb_register_extended_match_rule(ldb, always_false);
784 749029 : if (ret != LDB_SUCCESS) {
785 0 : return ret;
786 : }
787 :
788 735768 : return LDB_SUCCESS;
789 : }
790 :
791 : /*
792 : register a new ldb extended matching rule
793 : */
794 4475799 : int ldb_register_extended_match_rule(struct ldb_context *ldb,
795 : const struct ldb_extended_match_rule *rule)
796 : {
797 79071 : const struct ldb_extended_match_rule *lookup_rule;
798 79071 : struct ldb_extended_match_entry *entry;
799 :
800 4475799 : lookup_rule = ldb_find_extended_match_rule(ldb, rule->oid);
801 4475799 : if (lookup_rule) {
802 0 : return LDB_ERR_ENTRY_ALREADY_EXISTS;
803 : }
804 :
805 4475799 : entry = talloc_zero(ldb, struct ldb_extended_match_entry);
806 4475799 : if (!entry) {
807 0 : return LDB_ERR_OPERATIONS_ERROR;
808 : }
809 4475799 : entry->rule = rule;
810 4475799 : DLIST_ADD_END(ldb->extended_match_rules, entry);
811 :
812 4396728 : return LDB_SUCCESS;
813 : }
814 :
815 400961 : int ldb_register_redact_callback(struct ldb_context *ldb,
816 : ldb_redact_fn redact_fn,
817 : struct ldb_module *module)
818 : {
819 400961 : if (ldb->redact.callback != NULL) {
820 0 : return LDB_ERR_ENTRY_ALREADY_EXISTS;
821 : }
822 :
823 400961 : ldb->redact.callback = redact_fn;
824 400961 : ldb->redact.module = module;
825 400961 : return LDB_SUCCESS;
826 : }
|