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 231800225 : 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 231800225 : int ret = 0;
48 :
49 231800225 : if (base == NULL || dn == NULL) {
50 0 : return 1;
51 : }
52 :
53 231800225 : 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 343536 : case LDB_SCOPE_ONELEVEL:
61 343536 : if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) {
62 71067 : if (ldb_dn_compare_base(base, dn) == 0) {
63 33565 : ret = 1;
64 : }
65 : }
66 342923 : break;
67 :
68 231456657 : case LDB_SCOPE_SUBTREE:
69 : default:
70 231456657 : if (ldb_dn_compare_base(base, dn) == 0) {
71 137844051 : ret = 1;
72 : }
73 228487937 : break;
74 : }
75 :
76 228830860 : return ret;
77 : }
78 :
79 :
80 : /*
81 : match if node is present
82 : */
83 54642740 : 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 1945445 : const struct ldb_schema_attribute *a;
89 1945445 : struct ldb_message_element *el;
90 :
91 54642740 : if (ldb_attr_dn(tree->u.present.attr) == 0) {
92 5764725 : *matched = true;
93 5764725 : return LDB_SUCCESS;
94 : }
95 :
96 48878015 : el = ldb_msg_find_element(msg, tree->u.present.attr);
97 48878015 : if (el == NULL) {
98 6423965 : *matched = false;
99 6423965 : return LDB_SUCCESS;
100 : }
101 :
102 42454050 : a = ldb_schema_attribute_by_name(ldb, el->name);
103 42454050 : if (!a) {
104 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
105 : }
106 :
107 42454050 : if (a->syntax->operator_fn) {
108 : unsigned int i;
109 460750 : for (i = 0; i < el->num_values; i++) {
110 460750 : int ret = a->syntax->operator_fn(ldb, LDB_OP_PRESENT, a, &el->values[i], NULL, matched);
111 460750 : if (ret != LDB_SUCCESS) return ret;
112 460750 : if (*matched) return LDB_SUCCESS;
113 : }
114 0 : *matched = false;
115 0 : return LDB_SUCCESS;
116 : }
117 :
118 41993300 : *matched = true;
119 41993300 : return LDB_SUCCESS;
120 : }
121 :
122 5964657 : 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 5964657 : if (comp_op == LDB_OP_APPROX) {
134 0 : return LDB_ERR_INAPPROPRIATE_MATCHING;
135 : }
136 :
137 5964657 : el = ldb_msg_find_element(msg, tree->u.comparison.attr);
138 5964657 : if (el == NULL) {
139 123627 : *matched = false;
140 123627 : return LDB_SUCCESS;
141 : }
142 :
143 5841030 : a = ldb_schema_attribute_by_name(ldb, el->name);
144 5841030 : if (!a) {
145 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
146 : }
147 :
148 9074288 : for (i = 0; i < el->num_values; i++) {
149 5841056 : 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 5839212 : int ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value);
156 :
157 5839212 : if (ret == 0) {
158 1946 : *matched = true;
159 1946 : return LDB_SUCCESS;
160 : }
161 5837266 : if (ret > 0 && comp_op == LDB_OP_GREATER) {
162 2603980 : *matched = true;
163 2603980 : return LDB_SUCCESS;
164 : }
165 3233286 : if (ret < 0 && comp_op == LDB_OP_LESS) {
166 754 : *matched = true;
167 754 : return LDB_SUCCESS;
168 : }
169 : }
170 : }
171 :
172 3233232 : *matched = false;
173 3233232 : return LDB_SUCCESS;
174 : }
175 :
176 : /*
177 : match a simple leaf node
178 : */
179 280619744 : 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 6091071 : unsigned int i;
186 6091071 : struct ldb_message_element *el;
187 6091071 : const struct ldb_schema_attribute *a;
188 6091071 : struct ldb_dn *valuedn;
189 6091071 : int ret;
190 :
191 280619744 : if (ldb_attr_dn(tree->u.equality.attr) == 0) {
192 183406 : valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value);
193 183406 : if (valuedn == NULL) {
194 0 : return LDB_ERR_INVALID_DN_SYNTAX;
195 : }
196 :
197 183406 : ret = ldb_dn_compare(msg->dn, valuedn);
198 :
199 183406 : talloc_free(valuedn);
200 :
201 183406 : *matched = (ret == 0);
202 183406 : return LDB_SUCCESS;
203 : }
204 :
205 : /* TODO: handle the "*" case derived from an extended search
206 : operation without the attribute type defined */
207 280436338 : el = ldb_msg_find_element(msg, tree->u.equality.attr);
208 280436338 : if (el == NULL) {
209 130076066 : *matched = false;
210 130076066 : return LDB_SUCCESS;
211 : }
212 :
213 150360272 : a = ldb_schema_attribute_by_name(ldb, el->name);
214 150360272 : if (a == NULL) {
215 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
216 : }
217 :
218 282505515 : for (i=0;i<el->num_values;i++) {
219 260032077 : if (a->syntax->operator_fn) {
220 28234140 : ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a,
221 27723627 : &tree->u.equality.value, &el->values[i], matched);
222 27723627 : if (ret != LDB_SUCCESS) return ret;
223 27723627 : if (*matched) return LDB_SUCCESS;
224 : } else {
225 232308450 : if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value,
226 232308450 : &el->values[i]) == 0) {
227 101422568 : *matched = true;
228 101422568 : return LDB_SUCCESS;
229 : }
230 : }
231 : }
232 :
233 22473438 : *matched = false;
234 22473438 : return LDB_SUCCESS;
235 : }
236 :
237 3201577 : 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 3201577 : uint8_t *save_p = NULL;
246 3201577 : unsigned int c = 0;
247 :
248 3201577 : if (tree->operation != LDB_OP_SUBSTRING) {
249 1 : *matched = false;
250 1 : return LDB_ERR_INAPPROPRIATE_MATCHING;
251 : }
252 :
253 3201576 : a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr);
254 3201576 : if (!a) {
255 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
256 : }
257 :
258 3201576 : 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 3201573 : if (a->syntax->canonicalise_fn != ldb_handler_copy) {
265 2398143 : 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 2398143 : save_p = val.data;
275 : } else {
276 803430 : val = value;
277 : }
278 :
279 3201573 : cnk.data = NULL;
280 :
281 3201573 : if ( ! tree->u.substring.start_with_wildcard ) {
282 2367067 : uint8_t *cnk_to_free = NULL;
283 :
284 2367067 : chunk = tree->u.substring.chunks[c];
285 : /* No need to just copy this value for a binary match */
286 2367067 : if (a->syntax->canonicalise_fn != ldb_handler_copy) {
287 2365644 : if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) {
288 0 : goto mismatch;
289 : }
290 :
291 2365644 : 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 2367067 : if (cnk.length > val.length) {
298 58508 : TALLOC_FREE(cnk_to_free);
299 58508 : goto mismatch;
300 : }
301 : /*
302 : * Empty strings are returned as length 0. Ensure
303 : * we can cope with this.
304 : */
305 2308559 : if (cnk.length == 0) {
306 0 : TALLOC_FREE(cnk_to_free);
307 0 : goto mismatch;
308 : }
309 :
310 2308559 : if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) {
311 1852236 : TALLOC_FREE(cnk_to_free);
312 1852236 : 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 1291610 : while (tree->u.substring.chunks[c]) {
323 76 : uint8_t *p;
324 834573 : uint8_t *cnk_to_free = NULL;
325 :
326 834573 : chunk = tree->u.substring.chunks[c];
327 : /* No need to just copy this value for a binary match */
328 834573 : if (a->syntax->canonicalise_fn != ldb_handler_copy) {
329 32562 : if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) {
330 0 : goto mismatch;
331 : }
332 :
333 32562 : cnk_to_free = cnk.data;
334 : } else {
335 802011 : cnk = *chunk;
336 : }
337 : /*
338 : * Empty strings are returned as length 0. Ensure
339 : * we can cope with this.
340 : */
341 834573 : if (cnk.length == 0) {
342 0 : TALLOC_FREE(cnk_to_free);
343 0 : goto mismatch;
344 : }
345 834573 : if (cnk.length > val.length) {
346 22723 : TALLOC_FREE(cnk_to_free);
347 22723 : goto mismatch;
348 : }
349 :
350 811850 : if ( (tree->u.substring.chunks[c + 1]) == NULL &&
351 812455 : (! 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 9222 : p = val.data + val.length - cnk.length;
358 9222 : cmp = memcmp(p,
359 9222 : cnk.data,
360 : cnk.length);
361 9222 : TALLOC_FREE(cnk_to_free);
362 :
363 9222 : if (cmp != 0) {
364 8503 : goto mismatch;
365 : }
366 : } else {
367 : /*
368 : * Values might be binary blobs. Don't use string
369 : * search, but memory search instead.
370 : */
371 802628 : p = memmem((const void *)val.data, val.length,
372 802628 : (const void *)cnk.data, cnk.length);
373 802628 : if (p == NULL) {
374 802566 : TALLOC_FREE(cnk_to_free);
375 802566 : 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 768 : c++;
384 : }
385 :
386 457037 : talloc_free(save_p);
387 457037 : *matched = true;
388 457037 : return LDB_SUCCESS;
389 :
390 2744536 : mismatch:
391 2744536 : *matched = false;
392 2744536 : talloc_free(save_p);
393 2744536 : return LDB_SUCCESS;
394 : }
395 :
396 : /*
397 : match a simple leaf node
398 : */
399 3791208 : 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 3791208 : el = ldb_msg_find_element(msg, tree->u.substring.attr);
408 3791208 : if (el == NULL) {
409 589822 : *matched = false;
410 589822 : return LDB_SUCCESS;
411 : }
412 :
413 5945919 : for (i = 0; i < el->num_values; i++) {
414 197 : int ret;
415 3201544 : ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched);
416 3201544 : if (ret != LDB_SUCCESS) return ret;
417 3201544 : if (*matched) return LDB_SUCCESS;
418 : }
419 :
420 2744375 : *matched = false;
421 2744375 : return LDB_SUCCESS;
422 : }
423 :
424 :
425 : /*
426 : bitwise and/or comparator depending on oid
427 : */
428 4526121 : 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 4526121 : char *endptr = NULL;
434 :
435 4526121 : if (v1->length >= sizeof(ibuf)-1) {
436 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
437 : }
438 4526121 : memcpy(ibuf, (char *)v1->data, v1->length);
439 4526121 : ibuf[v1->length] = 0;
440 4526121 : i1 = strtoull(ibuf, &endptr, 0);
441 4526121 : if (endptr != NULL) {
442 4526121 : if (endptr == ibuf || *endptr != 0) {
443 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
444 : }
445 : }
446 :
447 4526121 : if (v2->length >= sizeof(ibuf)-1) {
448 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
449 : }
450 4526121 : endptr = NULL;
451 4526121 : memcpy(ibuf, (char *)v2->data, v2->length);
452 4526121 : ibuf[v2->length] = 0;
453 4526121 : i2 = strtoull(ibuf, &endptr, 0);
454 4526121 : if (endptr != NULL) {
455 4526121 : if (endptr == ibuf || *endptr != 0) {
456 0 : return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
457 : }
458 : }
459 4526121 : if (strcmp(LDB_OID_COMPARATOR_AND, oid) == 0) {
460 4524574 : *matched = ((i1 & i2) == i2);
461 1547 : } else if (strcmp(LDB_OID_COMPARATOR_OR, oid) == 0) {
462 1547 : *matched = ((i1 & i2) != 0);
463 : } else {
464 0 : return LDB_ERR_INAPPROPRIATE_MATCHING;
465 : }
466 4390688 : return LDB_SUCCESS;
467 : }
468 :
469 4531282 : 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 4531282 : el = ldb_msg_find_element(msg, attribute_to_match);
481 4531282 : if (el == NULL) {
482 5175 : *matched = false;
483 5175 : return LDB_SUCCESS;
484 : }
485 :
486 6577862 : for (i=0;i<el->num_values;i++) {
487 135433 : int ret;
488 4526121 : struct ldb_val *v = &el->values[i];
489 :
490 4526121 : ret = ldb_comparator_bitmask(oid, v, value_to_match, matched);
491 4526121 : if (ret != LDB_SUCCESS) {
492 0 : return ret;
493 : }
494 4526121 : if (*matched) {
495 2398914 : return LDB_SUCCESS;
496 : }
497 : }
498 :
499 2051741 : *matched = false;
500 2051741 : 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 17124711 : static const struct ldb_extended_match_rule *ldb_find_extended_match_rule(struct ldb_context *ldb,
519 : const char *oid)
520 : {
521 622667 : struct ldb_extended_match_entry *extended_match_rule;
522 :
523 17124711 : for (extended_match_rule = ldb->extended_match_rules;
524 60643351 : extended_match_rule;
525 43518640 : extended_match_rule = extended_match_rule->next) {
526 56097709 : if (strcmp(extended_match_rule->rule->oid, oid) == 0) {
527 12579069 : return extended_match_rule->rule;
528 : }
529 : }
530 :
531 4466349 : return NULL;
532 : }
533 :
534 :
535 : /*
536 : extended match, handles things like bitops
537 : */
538 12579072 : 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 12579072 : 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 12579072 : 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 12579072 : 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 12579072 : rule = ldb_find_extended_match_rule(ldb, tree->u.extended.rule_id);
562 12579072 : 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 12579069 : return rule->callback(ldb, rule->oid, msg,
570 12035695 : tree->u.extended.attr,
571 : &tree->u.extended.value, matched);
572 : }
573 :
574 752494932 : static bool ldb_must_suppress_match(const struct ldb_message *msg,
575 : const struct ldb_parse_tree *tree)
576 : {
577 752494932 : const char *attr = NULL;
578 752494932 : struct ldb_message_element *el = NULL;
579 :
580 752494932 : attr = ldb_parse_tree_get_attr(tree);
581 752494932 : if (attr == NULL) {
582 398014023 : return false;
583 : }
584 :
585 : /* find the message element */
586 345023766 : el = ldb_msg_find_element(msg, attr);
587 345023766 : if (el == NULL) {
588 139994384 : return false;
589 : }
590 :
591 201862164 : 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 765074004 : 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 18038120 : unsigned int i;
609 18038120 : int ret;
610 :
611 765074004 : *matched = false;
612 :
613 765074004 : 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 765074004 : if (tree->operation != LDB_OP_EXTENDED) {
624 752494932 : if (ldb_must_suppress_match(msg, tree)) {
625 5417 : return LDB_SUCCESS;
626 : }
627 : }
628 :
629 765068587 : switch (tree->operation) {
630 136231617 : case LDB_OP_AND:
631 387043772 : for (i=0;i<tree->u.list.num_elements;i++) {
632 271020378 : ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched);
633 271020378 : if (ret != LDB_SUCCESS) return ret;
634 271020363 : if (!*matched) return LDB_SUCCESS;
635 : }
636 116023394 : *matched = true;
637 116023394 : return LDB_SUCCESS;
638 :
639 133961371 : case LDB_OP_OR:
640 178799102 : for (i=0;i<tree->u.list.num_elements;i++) {
641 172731297 : ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched);
642 172731297 : if (ret != LDB_SUCCESS) return ret;
643 172731297 : if (*matched) return LDB_SUCCESS;
644 : }
645 6067805 : *matched = false;
646 6067805 : return LDB_SUCCESS;
647 :
648 130731333 : case LDB_OP_NOT:
649 130731333 : ret = ldb_match_message(ldb, msg, tree->u.isnot.child, scope, matched);
650 130731333 : if (ret != LDB_SUCCESS) return ret;
651 130731333 : *matched = ! *matched;
652 130731333 : return LDB_SUCCESS;
653 :
654 280619744 : case LDB_OP_EQUALITY:
655 280619744 : return ldb_match_equality(ldb, msg, tree, scope, matched);
656 :
657 3791208 : case LDB_OP_SUBSTRING:
658 3791208 : return ldb_match_substring(ldb, msg, tree, scope, matched);
659 :
660 5899754 : case LDB_OP_GREATER:
661 5899754 : return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER, matched);
662 :
663 64903 : case LDB_OP_LESS:
664 64903 : return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS, matched);
665 :
666 54642740 : case LDB_OP_PRESENT:
667 54642740 : 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 12579072 : case LDB_OP_EXTENDED:
673 12579072 : 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 893751 : int ldb_match_msg_objectclass(const struct ldb_message *msg,
724 : const char *objectclass)
725 : {
726 29180 : unsigned int i;
727 893751 : struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass");
728 893751 : if (!el) {
729 0 : return 0;
730 : }
731 3574989 : for (i=0; i < el->num_values; i++) {
732 3574976 : if (ldb_attr_cmp((const char *)el->values[i].data, objectclass) == 0) {
733 864558 : return 1;
734 : }
735 : }
736 13 : return 0;
737 : }
738 :
739 760669 : _PRIVATE_ int ldb_register_extended_match_rules(struct ldb_context *ldb)
740 : {
741 13298 : struct ldb_extended_match_rule *bitmask_and;
742 13298 : struct ldb_extended_match_rule *bitmask_or;
743 13298 : struct ldb_extended_match_rule *always_false;
744 13298 : int ret;
745 :
746 : /* Register bitmask-and match */
747 760669 : bitmask_and = talloc_zero(ldb, struct ldb_extended_match_rule);
748 760669 : if (bitmask_and == NULL) {
749 0 : return LDB_ERR_OPERATIONS_ERROR;
750 : }
751 :
752 760669 : bitmask_and->oid = LDB_OID_COMPARATOR_AND;
753 760669 : bitmask_and->callback = ldb_match_bitmask;
754 :
755 760669 : ret = ldb_register_extended_match_rule(ldb, bitmask_and);
756 760669 : if (ret != LDB_SUCCESS) {
757 0 : return ret;
758 : }
759 :
760 : /* Register bitmask-or match */
761 760669 : bitmask_or = talloc_zero(ldb, struct ldb_extended_match_rule);
762 760669 : if (bitmask_or == NULL) {
763 0 : return LDB_ERR_OPERATIONS_ERROR;
764 : }
765 :
766 760669 : bitmask_or->oid = LDB_OID_COMPARATOR_OR;
767 760669 : bitmask_or->callback = ldb_match_bitmask;
768 :
769 760669 : ret = ldb_register_extended_match_rule(ldb, bitmask_or);
770 760669 : if (ret != LDB_SUCCESS) {
771 0 : return ret;
772 : }
773 :
774 : /* Register always-false match */
775 760669 : always_false = talloc_zero(ldb, struct ldb_extended_match_rule);
776 760669 : if (always_false == NULL) {
777 0 : return LDB_ERR_OPERATIONS_ERROR;
778 : }
779 :
780 760669 : always_false->oid = SAMBA_LDAP_MATCH_ALWAYS_FALSE;
781 760669 : always_false->callback = ldb_comparator_false;
782 :
783 760669 : ret = ldb_register_extended_match_rule(ldb, always_false);
784 760669 : if (ret != LDB_SUCCESS) {
785 0 : return ret;
786 : }
787 :
788 747371 : return LDB_SUCCESS;
789 : }
790 :
791 : /*
792 : register a new ldb extended matching rule
793 : */
794 4545639 : int ldb_register_extended_match_rule(struct ldb_context *ldb,
795 : const struct ldb_extended_match_rule *rule)
796 : {
797 79293 : const struct ldb_extended_match_rule *lookup_rule;
798 79293 : struct ldb_extended_match_entry *entry;
799 :
800 4545639 : lookup_rule = ldb_find_extended_match_rule(ldb, rule->oid);
801 4545639 : if (lookup_rule) {
802 0 : return LDB_ERR_ENTRY_ALREADY_EXISTS;
803 : }
804 :
805 4545639 : entry = talloc_zero(ldb, struct ldb_extended_match_entry);
806 4545639 : if (!entry) {
807 0 : return LDB_ERR_OPERATIONS_ERROR;
808 : }
809 4545639 : entry->rule = rule;
810 4545639 : DLIST_ADD_END(ldb->extended_match_rules, entry);
811 :
812 4466346 : return LDB_SUCCESS;
813 : }
814 :
815 411128 : int ldb_register_redact_callback(struct ldb_context *ldb,
816 : ldb_redact_fn redact_fn,
817 : struct ldb_module *module)
818 : {
819 411128 : if (ldb->redact.callback != NULL) {
820 0 : return LDB_ERR_ENTRY_ALREADY_EXISTS;
821 : }
822 :
823 411128 : ldb->redact.callback = redact_fn;
824 411128 : ldb->redact.module = module;
825 411128 : return LDB_SUCCESS;
826 : }
|