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 231876186 : 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 231876186 : int ret = 0;
48 :
49 231876186 : if (base == NULL || dn == NULL) {
50 0 : return 1;
51 : }
52 :
53 231876186 : 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 343752 : case LDB_SCOPE_ONELEVEL:
61 343752 : if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) {
62 71091 : if (ldb_dn_compare_base(base, dn) == 0) {
63 33589 : ret = 1;
64 : }
65 : }
66 343139 : break;
67 :
68 231532402 : case LDB_SCOPE_SUBTREE:
69 : default:
70 231532402 : if (ldb_dn_compare_base(base, dn) == 0) {
71 138062586 : ret = 1;
72 : }
73 228556340 : break;
74 : }
75 :
76 228899479 : return ret;
77 : }
78 :
79 :
80 : /*
81 : match if node is present
82 : */
83 55056228 : 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 1963287 : const struct ldb_schema_attribute *a;
89 1963287 : struct ldb_message_element *el;
90 :
91 55056228 : if (ldb_attr_dn(tree->u.present.attr) == 0) {
92 5822296 : *matched = true;
93 5822296 : return LDB_SUCCESS;
94 : }
95 :
96 49233932 : el = ldb_msg_find_element(msg, tree->u.present.attr);
97 49233932 : if (el == NULL) {
98 6485207 : *matched = false;
99 6485207 : return LDB_SUCCESS;
100 : }
101 :
102 42748725 : a = ldb_schema_attribute_by_name(ldb, el->name);
103 42748725 : if (!a) {
104 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
105 : }
106 :
107 42748725 : if (a->syntax->operator_fn) {
108 : unsigned int i;
109 464703 : for (i = 0; i < el->num_values; i++) {
110 464703 : int ret = a->syntax->operator_fn(ldb, LDB_OP_PRESENT, a, &el->values[i], NULL, matched);
111 464703 : if (ret != LDB_SUCCESS) return ret;
112 464703 : if (*matched) return LDB_SUCCESS;
113 : }
114 0 : *matched = false;
115 0 : return LDB_SUCCESS;
116 : }
117 :
118 42284022 : *matched = true;
119 42284022 : return LDB_SUCCESS;
120 : }
121 :
122 6139381 : 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 6139381 : if (comp_op == LDB_OP_APPROX) {
134 0 : return LDB_ERR_INAPPROPRIATE_MATCHING;
135 : }
136 :
137 6139381 : el = ldb_msg_find_element(msg, tree->u.comparison.attr);
138 6139381 : if (el == NULL) {
139 123627 : *matched = false;
140 123627 : return LDB_SUCCESS;
141 : }
142 :
143 6015754 : a = ldb_schema_attribute_by_name(ldb, el->name);
144 6015754 : if (!a) {
145 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
146 : }
147 :
148 9343176 : for (i = 0; i < el->num_values; i++) {
149 6015780 : 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 6013936 : int ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value);
156 :
157 6013936 : if (ret == 0) {
158 1938 : *matched = true;
159 1938 : return LDB_SUCCESS;
160 : }
161 6011998 : if (ret > 0 && comp_op == LDB_OP_GREATER) {
162 2684549 : *matched = true;
163 2684549 : return LDB_SUCCESS;
164 : }
165 3327449 : if (ret < 0 && comp_op == LDB_OP_LESS) {
166 753 : *matched = true;
167 753 : return LDB_SUCCESS;
168 : }
169 : }
170 : }
171 :
172 3327396 : *matched = false;
173 3327396 : return LDB_SUCCESS;
174 : }
175 :
176 : /*
177 : match a simple leaf node
178 : */
179 280840842 : 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 6109584 : unsigned int i;
186 6109584 : struct ldb_message_element *el;
187 6109584 : const struct ldb_schema_attribute *a;
188 6109584 : struct ldb_dn *valuedn;
189 6109584 : int ret;
190 :
191 280840842 : if (ldb_attr_dn(tree->u.equality.attr) == 0) {
192 183863 : valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value);
193 183863 : if (valuedn == NULL) {
194 0 : return LDB_ERR_INVALID_DN_SYNTAX;
195 : }
196 :
197 183863 : ret = ldb_dn_compare(msg->dn, valuedn);
198 :
199 183863 : talloc_free(valuedn);
200 :
201 183863 : *matched = (ret == 0);
202 183863 : return LDB_SUCCESS;
203 : }
204 :
205 : /* TODO: handle the "*" case derived from an extended search
206 : operation without the attribute type defined */
207 280656979 : el = ldb_msg_find_element(msg, tree->u.equality.attr);
208 280656979 : if (el == NULL) {
209 130144685 : *matched = false;
210 130144685 : return LDB_SUCCESS;
211 : }
212 :
213 150512294 : a = ldb_schema_attribute_by_name(ldb, el->name);
214 150512294 : if (a == NULL) {
215 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
216 : }
217 :
218 282603640 : for (i=0;i<el->num_values;i++) {
219 260101810 : if (a->syntax->operator_fn) {
220 28433708 : ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a,
221 27908190 : &tree->u.equality.value, &el->values[i], matched);
222 27908190 : if (ret != LDB_SUCCESS) return ret;
223 27908190 : if (*matched) return LDB_SUCCESS;
224 : } else {
225 232193620 : if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value,
226 232193620 : &el->values[i]) == 0) {
227 101385462 : *matched = true;
228 101385462 : return LDB_SUCCESS;
229 : }
230 : }
231 : }
232 :
233 22501830 : *matched = false;
234 22501830 : return LDB_SUCCESS;
235 : }
236 :
237 3173079 : 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 3173079 : uint8_t *save_p = NULL;
246 3173079 : unsigned int c = 0;
247 :
248 3173079 : if (tree->operation != LDB_OP_SUBSTRING) {
249 1 : *matched = false;
250 1 : return LDB_ERR_INAPPROPRIATE_MATCHING;
251 : }
252 :
253 3173078 : a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr);
254 3173078 : if (!a) {
255 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
256 : }
257 :
258 3173078 : 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 3173075 : if (a->syntax->canonicalise_fn != ldb_handler_copy) {
265 2399645 : 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 2399645 : save_p = val.data;
275 : } else {
276 773430 : val = value;
277 : }
278 :
279 3173075 : cnk.data = NULL;
280 :
281 3173075 : if ( ! tree->u.substring.start_with_wildcard ) {
282 2367069 : uint8_t *cnk_to_free = NULL;
283 :
284 2367069 : chunk = tree->u.substring.chunks[c];
285 : /* No need to just copy this value for a binary match */
286 2367069 : if (a->syntax->canonicalise_fn != ldb_handler_copy) {
287 2365646 : if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) {
288 0 : goto mismatch;
289 : }
290 :
291 2365646 : 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 2367069 : if (cnk.length > val.length) {
298 58461 : TALLOC_FREE(cnk_to_free);
299 58461 : goto mismatch;
300 : }
301 : /*
302 : * Empty strings are returned as length 0. Ensure
303 : * we can cope with this.
304 : */
305 2308608 : if (cnk.length == 0) {
306 0 : TALLOC_FREE(cnk_to_free);
307 0 : goto mismatch;
308 : }
309 :
310 2308608 : if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) {
311 1852285 : TALLOC_FREE(cnk_to_free);
312 1852285 : 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 1263150 : while (tree->u.substring.chunks[c]) {
323 76 : uint8_t *p;
324 806073 : uint8_t *cnk_to_free = NULL;
325 :
326 806073 : chunk = tree->u.substring.chunks[c];
327 : /* No need to just copy this value for a binary match */
328 806073 : if (a->syntax->canonicalise_fn != ldb_handler_copy) {
329 34062 : if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) {
330 0 : goto mismatch;
331 : }
332 :
333 34062 : cnk_to_free = cnk.data;
334 : } else {
335 772011 : cnk = *chunk;
336 : }
337 : /*
338 : * Empty strings are returned as length 0. Ensure
339 : * we can cope with this.
340 : */
341 806073 : if (cnk.length == 0) {
342 0 : TALLOC_FREE(cnk_to_free);
343 0 : goto mismatch;
344 : }
345 806073 : if (cnk.length > val.length) {
346 23971 : TALLOC_FREE(cnk_to_free);
347 23971 : goto mismatch;
348 : }
349 :
350 782102 : if ( (tree->u.substring.chunks[c + 1]) == NULL &&
351 782747 : (! 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 9474 : p = val.data + val.length - cnk.length;
358 9474 : cmp = memcmp(p,
359 9474 : cnk.data,
360 : cnk.length);
361 9474 : TALLOC_FREE(cnk_to_free);
362 :
363 9474 : if (cmp != 0) {
364 8715 : goto mismatch;
365 : }
366 : } else {
367 : /*
368 : * Values might be binary blobs. Don't use string
369 : * search, but memory search instead.
370 : */
371 772628 : p = memmem((const void *)val.data, val.length,
372 772628 : (const void *)cnk.data, cnk.length);
373 772628 : if (p == NULL) {
374 772566 : TALLOC_FREE(cnk_to_free);
375 772566 : 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 808 : c++;
384 : }
385 :
386 457077 : talloc_free(save_p);
387 457077 : *matched = true;
388 457077 : return LDB_SUCCESS;
389 :
390 2715998 : mismatch:
391 2715998 : *matched = false;
392 2715998 : talloc_free(save_p);
393 2715998 : return LDB_SUCCESS;
394 : }
395 :
396 : /*
397 : match a simple leaf node
398 : */
399 3766670 : 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 3766670 : el = ldb_msg_find_element(msg, tree->u.substring.attr);
408 3766670 : if (el == NULL) {
409 593782 : *matched = false;
410 593782 : return LDB_SUCCESS;
411 : }
412 :
413 5888883 : for (i = 0; i < el->num_values; i++) {
414 197 : int ret;
415 3173046 : ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched);
416 3173046 : if (ret != LDB_SUCCESS) return ret;
417 3173046 : if (*matched) return LDB_SUCCESS;
418 : }
419 :
420 2715837 : *matched = false;
421 2715837 : return LDB_SUCCESS;
422 : }
423 :
424 :
425 : /*
426 : bitwise and/or comparator depending on oid
427 : */
428 4556325 : 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 4556325 : char *endptr = NULL;
434 :
435 4556325 : if (v1->length >= sizeof(ibuf)-1) {
436 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
437 : }
438 4556325 : memcpy(ibuf, (char *)v1->data, v1->length);
439 4556325 : ibuf[v1->length] = 0;
440 4556325 : i1 = strtoull(ibuf, &endptr, 0);
441 4556325 : if (endptr != NULL) {
442 4556325 : if (endptr == ibuf || *endptr != 0) {
443 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
444 : }
445 : }
446 :
447 4556325 : if (v2->length >= sizeof(ibuf)-1) {
448 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
449 : }
450 4556325 : endptr = NULL;
451 4556325 : memcpy(ibuf, (char *)v2->data, v2->length);
452 4556325 : ibuf[v2->length] = 0;
453 4556325 : i2 = strtoull(ibuf, &endptr, 0);
454 4556325 : if (endptr != NULL) {
455 4556325 : if (endptr == ibuf || *endptr != 0) {
456 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
457 : }
458 : }
459 4556325 : if (strcmp(LDB_OID_COMPARATOR_AND, oid) == 0) {
460 4554752 : *matched = ((i1 & i2) == i2);
461 1573 : } else if (strcmp(LDB_OID_COMPARATOR_OR, oid) == 0) {
462 1573 : *matched = ((i1 & i2) != 0);
463 : } else {
464 0 : return LDB_ERR_INAPPROPRIATE_MATCHING;
465 : }
466 4420892 : return LDB_SUCCESS;
467 : }
468 :
469 4561486 : 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 4561486 : el = ldb_msg_find_element(msg, attribute_to_match);
481 4561486 : if (el == NULL) {
482 5175 : *matched = false;
483 5175 : return LDB_SUCCESS;
484 : }
485 :
486 6622079 : for (i=0;i<el->num_values;i++) {
487 135433 : int ret;
488 4556325 : struct ldb_val *v = &el->values[i];
489 :
490 4556325 : ret = ldb_comparator_bitmask(oid, v, value_to_match, matched);
491 4556325 : if (ret != LDB_SUCCESS) {
492 0 : return ret;
493 : }
494 4556325 : if (*matched) {
495 2415105 : return LDB_SUCCESS;
496 : }
497 : }
498 :
499 2065754 : *matched = false;
500 2065754 : 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 17192036 : static const struct ldb_extended_match_rule *ldb_find_extended_match_rule(struct ldb_context *ldb,
519 : const char *oid)
520 : {
521 622643 : struct ldb_extended_match_entry *extended_match_rule;
522 :
523 17192036 : for (extended_match_rule = ldb->extended_match_rules;
524 60803328 : extended_match_rule;
525 43611292 : extended_match_rule = extended_match_rule->next) {
526 56220444 : if (strcmp(extended_match_rule->rule->oid, oid) == 0) {
527 12609152 : return extended_match_rule->rule;
528 : }
529 : }
530 :
531 4503615 : return NULL;
532 : }
533 :
534 :
535 : /*
536 : extended match, handles things like bitops
537 : */
538 12609155 : 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 543374 : const struct ldb_extended_match_rule *rule;
544 :
545 12609155 : 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 12609155 : 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 12609155 : 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 12609155 : rule = ldb_find_extended_match_rule(ldb, tree->u.extended.rule_id);
562 12609155 : 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 12609152 : return rule->callback(ldb, rule->oid, msg,
570 12065778 : tree->u.extended.attr,
571 : &tree->u.extended.value, matched);
572 : }
573 :
574 753801169 : static bool ldb_must_suppress_match(const struct ldb_message *msg,
575 : const struct ldb_parse_tree *tree)
576 : {
577 753801169 : const char *attr = NULL;
578 753801169 : struct ldb_message_element *el = NULL;
579 :
580 753801169 : attr = ldb_parse_tree_get_attr(tree);
581 753801169 : if (attr == NULL) {
582 398514218 : return false;
583 : }
584 :
585 : /* find the message element */
586 345808538 : el = ldb_msg_find_element(msg, attr);
587 345808538 : if (el == NULL) {
588 140170162 : return false;
589 : }
590 :
591 202455087 : 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 766410324 : 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 18095745 : unsigned int i;
609 18095745 : int ret;
610 :
611 766410324 : *matched = false;
612 :
613 766410324 : 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 766410324 : if (tree->operation != LDB_OP_EXTENDED) {
624 753801169 : if (ldb_must_suppress_match(msg, tree)) {
625 5417 : return LDB_SUCCESS;
626 : }
627 : }
628 :
629 766404907 : switch (tree->operation) {
630 136395871 : case LDB_OP_AND:
631 387365163 : for (i=0;i<tree->u.list.num_elements;i++) {
632 271317302 : ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched);
633 271317302 : if (ret != LDB_SUCCESS) return ret;
634 271317287 : if (!*matched) return LDB_SUCCESS;
635 : }
636 116047861 : *matched = true;
637 116047861 : return LDB_SUCCESS;
638 :
639 134206361 : case LDB_OP_OR:
640 179099401 : for (i=0;i<tree->u.list.num_elements;i++) {
641 173019635 : ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched);
642 173019635 : if (ret != LDB_SUCCESS) return ret;
643 173019635 : if (*matched) return LDB_SUCCESS;
644 : }
645 6079766 : *matched = false;
646 6079766 : return LDB_SUCCESS;
647 :
648 130824343 : case LDB_OP_NOT:
649 130824343 : ret = ldb_match_message(ldb, msg, tree->u.isnot.child, scope, matched);
650 130824343 : if (ret != LDB_SUCCESS) return ret;
651 130824343 : *matched = ! *matched;
652 130824343 : return LDB_SUCCESS;
653 :
654 280840842 : case LDB_OP_EQUALITY:
655 280840842 : return ldb_match_equality(ldb, msg, tree, scope, matched);
656 :
657 3766670 : case LDB_OP_SUBSTRING:
658 3766670 : return ldb_match_substring(ldb, msg, tree, scope, matched);
659 :
660 6074483 : case LDB_OP_GREATER:
661 6074483 : return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER, matched);
662 :
663 64898 : case LDB_OP_LESS:
664 64898 : return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS, matched);
665 :
666 55056228 : case LDB_OP_PRESENT:
667 55056228 : 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 12609155 : case LDB_OP_EXTENDED:
673 12609155 : 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 898789 : int ldb_match_msg_objectclass(const struct ldb_message *msg,
724 : const char *objectclass)
725 : {
726 29180 : unsigned int i;
727 898789 : struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass");
728 898789 : if (!el) {
729 0 : return 0;
730 : }
731 3595141 : for (i=0; i < el->num_values; i++) {
732 3595128 : if (ldb_attr_cmp((const char *)el->values[i].data, objectclass) == 0) {
733 869596 : return 1;
734 : }
735 : }
736 13 : return 0;
737 : }
738 :
739 766876 : _PRIVATE_ int ldb_register_extended_match_rules(struct ldb_context *ldb)
740 : {
741 13294 : struct ldb_extended_match_rule *bitmask_and;
742 13294 : struct ldb_extended_match_rule *bitmask_or;
743 13294 : struct ldb_extended_match_rule *always_false;
744 13294 : int ret;
745 :
746 : /* Register bitmask-and match */
747 766876 : bitmask_and = talloc_zero(ldb, struct ldb_extended_match_rule);
748 766876 : if (bitmask_and == NULL) {
749 0 : return LDB_ERR_OPERATIONS_ERROR;
750 : }
751 :
752 766876 : bitmask_and->oid = LDB_OID_COMPARATOR_AND;
753 766876 : bitmask_and->callback = ldb_match_bitmask;
754 :
755 766876 : ret = ldb_register_extended_match_rule(ldb, bitmask_and);
756 766876 : if (ret != LDB_SUCCESS) {
757 0 : return ret;
758 : }
759 :
760 : /* Register bitmask-or match */
761 766876 : bitmask_or = talloc_zero(ldb, struct ldb_extended_match_rule);
762 766876 : if (bitmask_or == NULL) {
763 0 : return LDB_ERR_OPERATIONS_ERROR;
764 : }
765 :
766 766876 : bitmask_or->oid = LDB_OID_COMPARATOR_OR;
767 766876 : bitmask_or->callback = ldb_match_bitmask;
768 :
769 766876 : ret = ldb_register_extended_match_rule(ldb, bitmask_or);
770 766876 : if (ret != LDB_SUCCESS) {
771 0 : return ret;
772 : }
773 :
774 : /* Register always-false match */
775 766876 : always_false = talloc_zero(ldb, struct ldb_extended_match_rule);
776 766876 : if (always_false == NULL) {
777 0 : return LDB_ERR_OPERATIONS_ERROR;
778 : }
779 :
780 766876 : always_false->oid = SAMBA_LDAP_MATCH_ALWAYS_FALSE;
781 766876 : always_false->callback = ldb_comparator_false;
782 :
783 766876 : ret = ldb_register_extended_match_rule(ldb, always_false);
784 766876 : if (ret != LDB_SUCCESS) {
785 0 : return ret;
786 : }
787 :
788 753582 : return LDB_SUCCESS;
789 : }
790 :
791 : /*
792 : register a new ldb extended matching rule
793 : */
794 4582881 : int ldb_register_extended_match_rule(struct ldb_context *ldb,
795 : const struct ldb_extended_match_rule *rule)
796 : {
797 79269 : const struct ldb_extended_match_rule *lookup_rule;
798 79269 : struct ldb_extended_match_entry *entry;
799 :
800 4582881 : lookup_rule = ldb_find_extended_match_rule(ldb, rule->oid);
801 4582881 : if (lookup_rule) {
802 0 : return LDB_ERR_ENTRY_ALREADY_EXISTS;
803 : }
804 :
805 4582881 : entry = talloc_zero(ldb, struct ldb_extended_match_entry);
806 4582881 : if (!entry) {
807 0 : return LDB_ERR_OPERATIONS_ERROR;
808 : }
809 4582881 : entry->rule = rule;
810 4582881 : DLIST_ADD_END(ldb->extended_match_rules, entry);
811 :
812 4503612 : return LDB_SUCCESS;
813 : }
814 :
815 414914 : int ldb_register_redact_callback(struct ldb_context *ldb,
816 : ldb_redact_fn redact_fn,
817 : struct ldb_module *module)
818 : {
819 414914 : if (ldb->redact.callback != NULL) {
820 0 : return LDB_ERR_ENTRY_ALREADY_EXISTS;
821 : }
822 :
823 414914 : ldb->redact.callback = redact_fn;
824 414914 : ldb->redact.module = module;
825 414914 : return LDB_SUCCESS;
826 : }
|