LCOV - code coverage report
Current view: top level - lib/ldb/common - ldb_match.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 282 327 86.2 %
Date: 2021-09-23 10:06:22 Functions: 22 23 95.7 %

          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             : 
      38             : /*
      39             :   check if the scope matches in a search result
      40             : */
      41   174615827 : static int ldb_match_scope(struct ldb_context *ldb,
      42             :                            struct ldb_dn *base,
      43             :                            struct ldb_dn *dn,
      44             :                            enum ldb_scope scope)
      45             : {
      46   174615827 :         int ret = 0;
      47             : 
      48   174615827 :         if (base == NULL || dn == NULL) {
      49           0 :                 return 1;
      50             :         }
      51             : 
      52   174615827 :         switch (scope) {
      53          31 :         case LDB_SCOPE_BASE:
      54          31 :                 if (ldb_dn_compare(base, dn) == 0) {
      55          31 :                         ret = 1;
      56             :                 }
      57           0 :                 break;
      58             : 
      59       18532 :         case LDB_SCOPE_ONELEVEL:
      60       18532 :                 if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) {
      61        8250 :                         if (ldb_dn_compare_base(base, dn) == 0) {
      62        4570 :                                 ret = 1;
      63             :                         }
      64             :                 }
      65       17921 :                 break;
      66             :                 
      67   174597264 :         case LDB_SCOPE_SUBTREE:
      68             :         default:
      69   174597264 :                 if (ldb_dn_compare_base(base, dn) == 0) {
      70   105724590 :                         ret = 1;
      71             :                 }
      72   172591175 :                 break;
      73             :         }
      74             : 
      75   172609096 :         return ret;
      76             : }
      77             : 
      78             : 
      79             : /*
      80             :   match if node is present
      81             : */
      82    47822950 : static int ldb_match_present(struct ldb_context *ldb, 
      83             :                              const struct ldb_message *msg,
      84             :                              const struct ldb_parse_tree *tree,
      85             :                              enum ldb_scope scope, bool *matched)
      86             : {
      87             :         const struct ldb_schema_attribute *a;
      88             :         struct ldb_message_element *el;
      89             : 
      90    47822950 :         if (ldb_attr_dn(tree->u.present.attr) == 0) {
      91     8699366 :                 *matched = true;
      92     8247408 :                 return LDB_SUCCESS;
      93             :         }
      94             : 
      95    39123584 :         el = ldb_msg_find_element(msg, tree->u.present.attr);
      96    39123584 :         if (el == NULL) {
      97     9287056 :                 *matched = false;
      98     8826851 :                 return LDB_SUCCESS;
      99             :         }
     100             : 
     101    29836528 :         a = ldb_schema_attribute_by_name(ldb, el->name);
     102    29836528 :         if (!a) {
     103           0 :                 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     104             :         }
     105             : 
     106    29836528 :         if (a->syntax->operator_fn) {
     107             :                 unsigned int i;
     108      351164 :                 for (i = 0; i < el->num_values; i++) {
     109      361316 :                         int ret = a->syntax->operator_fn(ldb, LDB_OP_PRESENT, a, &el->values[i], NULL, matched);
     110      361316 :                         if (ret != LDB_SUCCESS) return ret;
     111      361316 :                         if (*matched) return LDB_SUCCESS;
     112             :                 }
     113           0 :                 *matched = false;
     114           0 :                 return LDB_SUCCESS;
     115             :         }
     116             : 
     117    29475212 :         *matched = true;
     118    28333287 :         return LDB_SUCCESS;
     119             : }
     120             : 
     121     5595299 : static int ldb_match_comparison(struct ldb_context *ldb, 
     122             :                                 const struct ldb_message *msg,
     123             :                                 const struct ldb_parse_tree *tree,
     124             :                                 enum ldb_scope scope,
     125             :                                 enum ldb_parse_op comp_op, bool *matched)
     126             : {
     127             :         unsigned int i;
     128             :         struct ldb_message_element *el;
     129             :         const struct ldb_schema_attribute *a;
     130             : 
     131             :         /* FIXME: APPROX comparison not handled yet */
     132     5595299 :         if (comp_op == LDB_OP_APPROX) {
     133           0 :                 return LDB_ERR_INAPPROPRIATE_MATCHING;
     134             :         }
     135             : 
     136     5595299 :         el = ldb_msg_find_element(msg, tree->u.comparison.attr);
     137     5595299 :         if (el == NULL) {
     138       99465 :                 *matched = false;
     139       99447 :                 return LDB_SUCCESS;
     140             :         }
     141             : 
     142     5495834 :         a = ldb_schema_attribute_by_name(ldb, el->name);
     143     5495834 :         if (!a) {
     144           0 :                 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     145             :         }
     146             : 
     147     8912904 :         for (i = 0; i < el->num_values; i++) {
     148     5495860 :                 if (a->syntax->operator_fn) {
     149             :                         int ret;
     150        1844 :                         ret = a->syntax->operator_fn(ldb, comp_op, a, &el->values[i], &tree->u.comparison.value, matched);
     151        1844 :                         if (ret != LDB_SUCCESS) return ret;
     152        1844 :                         if (*matched) return LDB_SUCCESS;
     153             :                 } else {
     154     5494016 :                         int ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value);
     155             : 
     156     5494016 :                         if (ret == 0) {
     157        1868 :                                 *matched = true;
     158        1868 :                                 return LDB_SUCCESS;
     159             :                         }
     160     5492148 :                         if (ret > 0 && comp_op == LDB_OP_GREATER) {
     161     2074070 :                                 *matched = true;
     162     2074069 :                                 return LDB_SUCCESS;
     163             :                         }
     164     3418078 :                         if (ret < 0 && comp_op == LDB_OP_LESS) {
     165         837 :                                 *matched = true;
     166         814 :                                 return LDB_SUCCESS;
     167             :                         }
     168             :                 }
     169             :         }
     170             : 
     171     3417941 :         *matched = false;
     172     3417568 :         return LDB_SUCCESS;
     173             : }
     174             : 
     175             : /*
     176             :   match a simple leaf node
     177             : */
     178   211770945 : static int ldb_match_equality(struct ldb_context *ldb, 
     179             :                               const struct ldb_message *msg,
     180             :                               const struct ldb_parse_tree *tree,
     181             :                               enum ldb_scope scope,
     182             :                               bool *matched)
     183             : {
     184             :         unsigned int i;
     185             :         struct ldb_message_element *el;
     186             :         const struct ldb_schema_attribute *a;
     187             :         struct ldb_dn *valuedn;
     188             :         int ret;
     189             : 
     190   211770945 :         if (ldb_attr_dn(tree->u.equality.attr) == 0) {
     191      158847 :                 valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value);
     192      158847 :                 if (valuedn == NULL) {
     193           0 :                         return LDB_ERR_INVALID_DN_SYNTAX;
     194             :                 }
     195             : 
     196      158847 :                 ret = ldb_dn_compare(msg->dn, valuedn);
     197             : 
     198      158847 :                 talloc_free(valuedn);
     199             : 
     200      158847 :                 *matched = (ret == 0);
     201      155934 :                 return LDB_SUCCESS;
     202             :         }
     203             : 
     204             :         /* TODO: handle the "*" case derived from an extended search
     205             :            operation without the attibute type defined */
     206   211612098 :         el = ldb_msg_find_element(msg, tree->u.equality.attr);
     207   211612098 :         if (el == NULL) {
     208   100120518 :                 *matched = false;
     209    98140496 :                 return LDB_SUCCESS;
     210             :         }
     211             : 
     212   111491580 :         a = ldb_schema_attribute_by_name(ldb, el->name);
     213   111491580 :         if (a == NULL) {
     214           0 :                 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     215             :         }
     216             : 
     217   212607712 :         for (i=0;i<el->num_values;i++) {
     218   198472988 :                 if (a->syntax->operator_fn) {
     219    33519035 :                         ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a,
     220    18336885 :                                                      &tree->u.equality.value, &el->values[i], matched);
     221    18336885 :                         if (ret != LDB_SUCCESS) return ret;
     222    18336885 :                         if (*matched) return LDB_SUCCESS;
     223             :                 } else {
     224   307054143 :                         if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value,
     225   180136103 :                                                      &el->values[i]) == 0) {
     226    78064751 :                                 *matched = true;
     227    76432815 :                                 return LDB_SUCCESS;
     228             :                         }
     229             :                 }
     230             :         }
     231             : 
     232    16230013 :         *matched = false;
     233    15974900 :         return LDB_SUCCESS;
     234             : }
     235             : 
     236     2431155 : static int ldb_wildcard_compare(struct ldb_context *ldb,
     237             :                                 const struct ldb_parse_tree *tree,
     238             :                                 const struct ldb_val value, bool *matched)
     239             : {
     240             :         const struct ldb_schema_attribute *a;
     241             :         struct ldb_val val;
     242             :         struct ldb_val cnk;
     243             :         struct ldb_val *chunk;
     244     2431155 :         uint8_t *save_p = NULL;
     245     2431155 :         unsigned int c = 0;
     246             : 
     247     2431155 :         if (tree->operation != LDB_OP_SUBSTRING) {
     248           1 :                 *matched = false;
     249           1 :                 return LDB_ERR_INAPPROPRIATE_MATCHING;
     250             :         }
     251             : 
     252     2431154 :         a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr);
     253     2431154 :         if (!a) {
     254           0 :                 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     255             :         }
     256             : 
     257     2431154 :         if (tree->u.substring.chunks == NULL) {
     258           3 :                 *matched = false;
     259           3 :                 return LDB_SUCCESS;
     260             :         }
     261             : 
     262     2431151 :         if (a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) {
     263           0 :                 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     264             :         }
     265             : 
     266     2431151 :         save_p = val.data;
     267     2431151 :         cnk.data = NULL;
     268             : 
     269     2431151 :         if ( ! tree->u.substring.start_with_wildcard ) {
     270             : 
     271     2403184 :                 chunk = tree->u.substring.chunks[c];
     272     2403184 :                 if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch;
     273             : 
     274             :                 /* This deals with wildcard prefix searches on binary attributes (eg objectGUID) */
     275     2403184 :                 if (cnk.length > val.length) {
     276       56535 :                         goto mismatch;
     277             :                 }
     278             :                 /*
     279             :                  * Empty strings are returned as length 0. Ensure
     280             :                  * we can cope with this.
     281             :                  */
     282     2346634 :                 if (cnk.length == 0) {
     283           0 :                         goto mismatch;
     284             :                 }
     285             : 
     286     2346634 :                 if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto mismatch;
     287      441080 :                 val.length -= cnk.length;
     288      441080 :                 val.data += cnk.length;
     289      441080 :                 c++;
     290      441080 :                 talloc_free(cnk.data);
     291      441080 :                 cnk.data = NULL;
     292             :         }
     293             : 
     294      932685 :         while (tree->u.substring.chunks[c]) {
     295             :                 uint8_t *p;
     296             : 
     297       28034 :                 chunk = tree->u.substring.chunks[c];
     298       28034 :                 if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) {
     299           0 :                         goto mismatch;
     300             :                 }
     301             :                 /*
     302             :                  * Empty strings are returned as length 0. Ensure
     303             :                  * we can cope with this.
     304             :                  */
     305       28034 :                 if (cnk.length == 0) {
     306           0 :                         goto mismatch;
     307             :                 }
     308       28034 :                 if (cnk.length > val.length) {
     309       18556 :                         goto mismatch;
     310             :                 }
     311             : 
     312       16736 :                 if ( (tree->u.substring.chunks[c + 1]) == NULL &&
     313       10092 :                      (! tree->u.substring.end_with_wildcard) ) {
     314             :                         /*
     315             :                          * The last bit, after all the asterisks, must match
     316             :                          * exactly the last bit of the string.
     317             :                          */
     318             :                         int cmp;
     319        8861 :                         p = val.data + val.length - cnk.length;
     320       15697 :                         cmp = memcmp(p,
     321        8861 :                                      cnk.data,
     322             :                                      cnk.length);
     323        8861 :                         if (cmp != 0) {
     324        8101 :                                 goto mismatch;
     325             :                         }
     326             :                 } else {
     327             :                         /*
     328             :                          * Values might be binary blobs. Don't use string
     329             :                          * search, but memory search instead.
     330             :                          */
     331        1086 :                         p = memmem((const void *)val.data, val.length,
     332         604 :                                    (const void *)cnk.data, cnk.length);
     333         604 :                         if (p == NULL) {
     334         511 :                                 goto mismatch;
     335             :                         }
     336             :                         /* move val to the end of the match */
     337          62 :                         p += cnk.length;
     338          62 :                         val.length -= (p - val.data);
     339          62 :                         val.data = p;
     340             :                 }
     341         803 :                 c++;
     342         803 :                 TALLOC_FREE(cnk.data);
     343             :         }
     344             : 
     345      441816 :         talloc_free(save_p);
     346      441816 :         *matched = true;
     347      441816 :         return LDB_SUCCESS;
     348             : 
     349     1989335 : mismatch:
     350     1989335 :         *matched = false;
     351     1989335 :         talloc_free(save_p);
     352     1989335 :         talloc_free(cnk.data);
     353     1989335 :         return LDB_SUCCESS;
     354             : }
     355             : 
     356             : /*
     357             :   match a simple leaf node
     358             : */
     359     3088549 : static int ldb_match_substring(struct ldb_context *ldb, 
     360             :                                const struct ldb_message *msg,
     361             :                                const struct ldb_parse_tree *tree,
     362             :                                enum ldb_scope scope, bool *matched)
     363             : {
     364             :         unsigned int i;
     365             :         struct ldb_message_element *el;
     366             : 
     367     3088549 :         el = ldb_msg_find_element(msg, tree->u.substring.attr);
     368     3088549 :         if (el == NULL) {
     369      657585 :                 *matched = false;
     370      657529 :                 return LDB_SUCCESS;
     371             :         }
     372             : 
     373     4420177 :         for (i = 0; i < el->num_values; i++) {
     374             :                 int ret;
     375     2431122 :                 ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched);
     376     2431122 :                 if (ret != LDB_SUCCESS) return ret;
     377     2431122 :                 if (*matched) return LDB_SUCCESS;
     378             :         }
     379             : 
     380     1989174 :         *matched = false;
     381     1989064 :         return LDB_SUCCESS;
     382             : }
     383             : 
     384             : 
     385             : /*
     386             :   bitwise and/or comparator depending on oid
     387             : */
     388     1885709 : static int ldb_comparator_bitmask(const char *oid, const struct ldb_val *v1, const struct ldb_val *v2,
     389             :                                   bool *matched)
     390             : {
     391             :         uint64_t i1, i2;
     392             :         char ibuf[100];
     393     1885709 :         char *endptr = NULL;
     394             : 
     395     1885709 :         if (v1->length >= sizeof(ibuf)-1) {
     396           0 :                 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     397             :         }
     398     1934328 :         memcpy(ibuf, (char *)v1->data, v1->length);
     399     1885709 :         ibuf[v1->length] = 0;
     400     1885709 :         i1 = strtoull(ibuf, &endptr, 0);
     401     1885709 :         if (endptr != NULL) {
     402     1885709 :                 if (endptr == ibuf || *endptr != 0) {
     403           0 :                         return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     404             :                 }
     405             :         }
     406             : 
     407     1885709 :         if (v2->length >= sizeof(ibuf)-1) {
     408           0 :                 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     409             :         }
     410     1885709 :         endptr = NULL;
     411     1934328 :         memcpy(ibuf, (char *)v2->data, v2->length);
     412     1885709 :         ibuf[v2->length] = 0;
     413     1885709 :         i2 = strtoull(ibuf, &endptr, 0);
     414     1885709 :         if (endptr != NULL) {
     415     1885709 :                 if (endptr == ibuf || *endptr != 0) {
     416           0 :                         return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     417             :                 }
     418             :         }
     419     1885709 :         if (strcmp(LDB_OID_COMPARATOR_AND, oid) == 0) {
     420     1884279 :                 *matched = ((i1 & i2) == i2);
     421        1430 :         } else if (strcmp(LDB_OID_COMPARATOR_OR, oid) == 0) {
     422        1430 :                 *matched = ((i1 & i2) != 0);
     423             :         } else {
     424           0 :                 return LDB_ERR_INAPPROPRIATE_MATCHING;
     425             :         }
     426     1837090 :         return LDB_SUCCESS;
     427             : }
     428             : 
     429     1890618 : static int ldb_match_bitmask(struct ldb_context *ldb,
     430             :                              const char *oid,
     431             :                              const struct ldb_message *msg,
     432             :                              const char *attribute_to_match,
     433             :                              const struct ldb_val *value_to_match,
     434             :                              bool *matched)
     435             : {
     436             :         unsigned int i;
     437             :         struct ldb_message_element *el;
     438             : 
     439             :         /* find the message element */
     440     1890618 :         el = ldb_msg_find_element(msg, attribute_to_match);
     441     1890618 :         if (el == NULL) {
     442        4923 :                 *matched = false;
     443        4923 :                 return LDB_SUCCESS;
     444             :         }
     445             : 
     446     2562151 :         for (i=0;i<el->num_values;i++) {
     447             :                 int ret;
     448     1885709 :                 struct ldb_val *v = &el->values[i];
     449             : 
     450     1885709 :                 ret = ldb_comparator_bitmask(oid, v, value_to_match, matched);
     451     1885709 :                 if (ret != LDB_SUCCESS) {
     452           0 :                         return ret;
     453             :                 }
     454     1885709 :                 if (*matched) {
     455     1131695 :                         return LDB_SUCCESS;
     456             :                 }
     457             :         }
     458             : 
     459      725054 :         *matched = false;
     460      725054 :         return LDB_SUCCESS;
     461             : }
     462             : 
     463             : /*
     464             :   always return false
     465             : */
     466       82932 : static int ldb_comparator_false(struct ldb_context *ldb,
     467             :                                 const char *oid,
     468             :                                 const struct ldb_message *msg,
     469             :                                 const char *attribute_to_match,
     470             :                                 const struct ldb_val *value_to_match,
     471             :                                 bool *matched)
     472             : {
     473       82932 :         *matched = false;
     474       82932 :         return LDB_SUCCESS;
     475             : }
     476             : 
     477             : 
     478    12727069 : static const struct ldb_extended_match_rule *ldb_find_extended_match_rule(struct ldb_context *ldb,
     479             :                                                                           const char *oid)
     480             : {
     481             :         struct ldb_extended_match_entry *extended_match_rule;
     482             : 
     483    53667667 :         for (extended_match_rule = ldb->extended_match_rules;
     484    12806227 :              extended_match_rule;
     485    40037202 :              extended_match_rule = extended_match_rule->next) {
     486    49864375 :                 if (strcmp(extended_match_rule->rule->oid, oid) == 0) {
     487     9396061 :                         return extended_match_rule->rule;
     488             :                 }
     489             :         }
     490             : 
     491     3331008 :         return NULL;
     492             : }
     493             : 
     494             : 
     495             : /*
     496             :   extended match, handles things like bitops
     497             : */
     498     9827176 : static int ldb_match_extended(struct ldb_context *ldb, 
     499             :                               const struct ldb_message *msg,
     500             :                               const struct ldb_parse_tree *tree,
     501             :                               enum ldb_scope scope, bool *matched)
     502             : {
     503             :         const struct ldb_extended_match_rule *rule;
     504             : 
     505     9827176 :         if (tree->u.extended.dnAttributes) {
     506             :                 /* FIXME: We really need to find out what this ":dn" part in
     507             :                  * an extended match means and how to handle it. For now print
     508             :                  * only a warning to have s3 winbind and other tools working
     509             :                  * against us. - Matthias */
     510         880 :                 ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb: dnAttributes extended match not supported yet");
     511             :         }
     512     9827176 :         if (tree->u.extended.rule_id == NULL) {
     513           0 :                 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-rule extended matches not supported yet");
     514           0 :                 return LDB_ERR_INAPPROPRIATE_MATCHING;
     515             :         }
     516     9827176 :         if (tree->u.extended.attr == NULL) {
     517           0 :                 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-attribute extended matches not supported yet");
     518           0 :                 return LDB_ERR_INAPPROPRIATE_MATCHING;
     519             :         }
     520             : 
     521    10258288 :         rule = ldb_find_extended_match_rule(ldb, tree->u.extended.rule_id);
     522     9827176 :         if (rule == NULL) {
     523           3 :                 *matched = false;
     524           3 :                 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s",
     525           0 :                           tree->u.extended.rule_id);
     526           3 :                 return LDB_SUCCESS;
     527             :         }
     528             : 
     529     9827173 :         return rule->callback(ldb, rule->oid, msg,
     530     2159501 :                               tree->u.extended.attr,
     531             :                               &tree->u.extended.value, matched);
     532             : }
     533             : 
     534             : /*
     535             :   Check if a particular message will match the given filter
     536             : 
     537             :   set *matched to true if it matches, false otherwise
     538             : 
     539             :   returns LDB_SUCCESS or an error
     540             : 
     541             :   this is a recursive function, and does short-circuit evaluation
     542             :  */
     543   588287850 : int ldb_match_message(struct ldb_context *ldb,
     544             :                       const struct ldb_message *msg,
     545             :                       const struct ldb_parse_tree *tree,
     546             :                       enum ldb_scope scope, bool *matched)
     547             : {
     548             :         unsigned int i;
     549             :         int ret;
     550             : 
     551   588287850 :         *matched = false;
     552             : 
     553   588287850 :         if (scope != LDB_SCOPE_BASE && ldb_dn_is_special(msg->dn)) {
     554             :                 /* don't match special records except on base searches */
     555           0 :                 return LDB_SUCCESS;
     556             :         }
     557             : 
     558   588287850 :         switch (tree->operation) {
     559    99703502 :         case LDB_OP_AND:
     560   288988370 :                 for (i=0;i<tree->u.list.num_elements;i++) {
     561   201449233 :                         ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched);
     562   201449233 :                         if (ret != LDB_SUCCESS) return ret;
     563   201449218 :                         if (!*matched) return LDB_SUCCESS;
     564             :                 }
     565    89590010 :                 *matched = true;
     566    89590010 :                 return LDB_SUCCESS;
     567             : 
     568   108249939 :         case LDB_OP_OR:
     569   147332359 :                 for (i=0;i<tree->u.list.num_elements;i++) {
     570   144732744 :                         ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched);
     571   144732744 :                         if (ret != LDB_SUCCESS) return ret;
     572   144732744 :                         if (*matched) return LDB_SUCCESS;
     573             :                 }
     574     5368078 :                 *matched = false;
     575     5368078 :                 return LDB_SUCCESS;
     576             : 
     577    97410154 :         case LDB_OP_NOT:
     578    97410154 :                 ret = ldb_match_message(ldb, msg, tree->u.isnot.child, scope, matched);
     579    97410154 :                 if (ret != LDB_SUCCESS) return ret;
     580    97410154 :                 *matched = ! *matched;
     581    97410154 :                 return LDB_SUCCESS;
     582             : 
     583   211770945 :         case LDB_OP_EQUALITY:
     584   211770945 :                 return ldb_match_equality(ldb, msg, tree, scope, matched);
     585             : 
     586     3088549 :         case LDB_OP_SUBSTRING:
     587     3088549 :                 return ldb_match_substring(ldb, msg, tree, scope, matched);
     588             : 
     589     5542730 :         case LDB_OP_GREATER:
     590     5542730 :                 return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER, matched);
     591             : 
     592       52569 :         case LDB_OP_LESS:
     593       52569 :                 return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS, matched);
     594             : 
     595    47822950 :         case LDB_OP_PRESENT:
     596    47822950 :                 return ldb_match_present(ldb, msg, tree, scope, matched);
     597             : 
     598           0 :         case LDB_OP_APPROX:
     599           0 :                 return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_APPROX, matched);
     600             : 
     601     9827176 :         case LDB_OP_EXTENDED:
     602     9827176 :                 return ldb_match_extended(ldb, msg, tree, scope, matched);
     603             :         }
     604             : 
     605           0 :         return LDB_ERR_INAPPROPRIATE_MATCHING;
     606             : }
     607             : 
     608             : /*
     609             :   return 0 if the given parse tree matches the given message. Assumes
     610             :   the message is in sorted order
     611             : 
     612             :   return 1 if it matches, and 0 if it doesn't match
     613             : */
     614             : 
     615           0 : int ldb_match_msg(struct ldb_context *ldb,
     616             :                   const struct ldb_message *msg,
     617             :                   const struct ldb_parse_tree *tree,
     618             :                   struct ldb_dn *base,
     619             :                   enum ldb_scope scope)
     620             : {
     621             :         bool matched;
     622             :         int ret;
     623             : 
     624           0 :         if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) {
     625           0 :                 return 0;
     626             :         }
     627             : 
     628           0 :         ret = ldb_match_message(ldb, msg, tree, scope, &matched);
     629           0 :         if (ret != LDB_SUCCESS) {
     630             :                 /* to match the old API, we need to consider this a
     631             :                    failure to match */
     632           0 :                 return 0;
     633             :         }
     634           0 :         return matched?1:0;
     635             : }
     636             : 
     637   174615827 : int ldb_match_msg_error(struct ldb_context *ldb,
     638             :                         const struct ldb_message *msg,
     639             :                         const struct ldb_parse_tree *tree,
     640             :                         struct ldb_dn *base,
     641             :                         enum ldb_scope scope,
     642             :                         bool *matched)
     643             : {
     644   174615827 :         if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) {
     645    68886636 :                 *matched = false;
     646    68886636 :                 return LDB_SUCCESS;
     647             :         }
     648             : 
     649   105729191 :         return ldb_match_message(ldb, msg, tree, scope, matched);
     650             : }
     651             : 
     652      632057 : int ldb_match_msg_objectclass(const struct ldb_message *msg,
     653             :                               const char *objectclass)
     654             : {
     655             :         unsigned int i;
     656      632057 :         struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass");
     657      632057 :         if (!el) {
     658           0 :                 return 0;
     659             :         }
     660     2511898 :         for (i=0; i < el->num_values; i++) {
     661     2528200 :                 if (ldb_attr_cmp((const char *)el->values[i].data, objectclass) == 0) {
     662      615729 :                         return 1;
     663             :                 }
     664             :         }
     665          13 :         return 0;
     666             : }
     667             : 
     668      567547 : _PRIVATE_ int ldb_register_extended_match_rules(struct ldb_context *ldb)
     669             : {
     670             :         struct ldb_extended_match_rule *bitmask_and;
     671             :         struct ldb_extended_match_rule *bitmask_or;
     672             :         struct ldb_extended_match_rule *always_false;
     673             :         int ret;
     674             : 
     675             :         /* Register bitmask-and match */
     676      567547 :         bitmask_and = talloc_zero(ldb, struct ldb_extended_match_rule);
     677      567547 :         if (bitmask_and == NULL) {
     678           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     679             :         }
     680             : 
     681      567547 :         bitmask_and->oid = LDB_OID_COMPARATOR_AND;
     682      567547 :         bitmask_and->callback = ldb_match_bitmask;
     683             : 
     684      567547 :         ret = ldb_register_extended_match_rule(ldb, bitmask_and);
     685      567547 :         if (ret != LDB_SUCCESS) {
     686           0 :                 return ret;
     687             :         }
     688             : 
     689             :         /* Register bitmask-or match */
     690      567547 :         bitmask_or = talloc_zero(ldb, struct ldb_extended_match_rule);
     691      567547 :         if (bitmask_or == NULL) {
     692           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     693             :         }
     694             : 
     695      567547 :         bitmask_or->oid = LDB_OID_COMPARATOR_OR;
     696      567547 :         bitmask_or->callback = ldb_match_bitmask;
     697             : 
     698      567547 :         ret = ldb_register_extended_match_rule(ldb, bitmask_or);
     699      567547 :         if (ret != LDB_SUCCESS) {
     700           0 :                 return ret;
     701             :         }
     702             : 
     703             :         /* Register always-false match */
     704      567547 :         always_false = talloc_zero(ldb, struct ldb_extended_match_rule);
     705      567547 :         if (always_false == NULL) {
     706           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     707             :         }
     708             : 
     709      567547 :         always_false->oid = SAMBA_LDAP_MATCH_ALWAYS_FALSE;
     710      567547 :         always_false->callback = ldb_comparator_false;
     711             : 
     712      567547 :         ret = ldb_register_extended_match_rule(ldb, always_false);
     713      567547 :         if (ret != LDB_SUCCESS) {
     714           0 :                 return ret;
     715             :         }
     716             : 
     717      567547 :         return LDB_SUCCESS;
     718             : }
     719             : 
     720             : /*
     721             :   register a new ldb extended matching rule
     722             : */
     723     3391170 : int ldb_register_extended_match_rule(struct ldb_context *ldb,
     724             :                                      const struct ldb_extended_match_rule *rule)
     725             : {
     726             :         const struct ldb_extended_match_rule *lookup_rule;
     727             :         struct ldb_extended_match_entry *entry;
     728             : 
     729     3451335 :         lookup_rule = ldb_find_extended_match_rule(ldb, rule->oid);
     730     3391170 :         if (lookup_rule) {
     731           0 :                 return LDB_ERR_ENTRY_ALREADY_EXISTS;
     732             :         }
     733             : 
     734     3391170 :         entry = talloc_zero(ldb, struct ldb_extended_match_entry);
     735     3391170 :         if (!entry) {
     736           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     737             :         }
     738     3391170 :         entry->rule = rule;
     739     3391170 :         DLIST_ADD_END(ldb->extended_match_rules, entry);
     740             : 
     741     3331005 :         return LDB_SUCCESS;
     742             : }
     743             : 

Generated by: LCOV version 1.13