LCOV - code coverage report
Current view: top level - lib/ldb/common - attrib_handlers.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 133 181 73.5 %
Date: 2024-05-31 13:13:24 Functions: 15 17 88.2 %

          Line data    Source code
       1             : /*
       2             :    ldb database library
       3             : 
       4             :    Copyright (C) Andrew Tridgell  2005
       5             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2009
       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             :   attribute handlers for well known attribute types, selected by syntax OID
      26             :   see rfc2252
      27             : */
      28             : 
      29             : #include "ldb_private.h"
      30             : #include "system/locale.h"
      31             : #include "ldb_handlers.h"
      32             : 
      33             : /*
      34             :   default handler that just copies a ldb_val.
      35             : */
      36   127268060 : int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx,
      37             :                      const struct ldb_val *in, struct ldb_val *out)
      38             : {
      39   127268060 :         *out = ldb_val_dup(mem_ctx, in);
      40   127268060 :         if (in->length > 0 && out->data == NULL) {
      41           0 :                 ldb_oom(ldb);
      42           0 :                 return -1;
      43             :         }
      44   122399475 :         return 0;
      45             : }
      46             : 
      47             : /*
      48             :   a case folding copy handler, removing leading and trailing spaces and
      49             :   multiple internal spaces
      50             : 
      51             :   We exploit the fact that utf8 never uses the space octet except for
      52             :   the space itself
      53             : */
      54   763590411 : int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx,
      55             :                             const struct ldb_val *in, struct ldb_val *out)
      56             : {
      57    13118729 :         char *s, *t, *start;
      58    13118729 :         bool in_space;
      59             : 
      60   763590411 :         if (!in || !out || !(in->data)) {
      61           0 :                 return -1;
      62             :         }
      63             : 
      64   763590411 :         out->data = (uint8_t *)ldb_casefold(ldb, mem_ctx, (const char *)(in->data), in->length);
      65   763590411 :         if (out->data == NULL) {
      66           0 :                 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_handler_fold: unable to casefold string [%.*s]", (int)in->length, (const char *)in->data);
      67           0 :                 return -1;
      68             :         }
      69             : 
      70   750471682 :         start = (char *)(out->data);
      71   750471682 :         in_space = true;
      72   750471682 :         t = start;
      73 11352718048 :         for (s = start; *s != '\0'; s++) {
      74 10589127637 :                 if (*s == ' ') {
      75   109159756 :                         if (in_space) {
      76             :                                 /*
      77             :                                  * We already have one (or this is the start)
      78             :                                  * and we don't want to add more
      79             :                                  */
      80        2230 :                                 continue;
      81             :                         }
      82   108359593 :                         in_space = true;
      83             :                 } else {
      84 10360507880 :                         in_space = false;
      85             :                 }
      86 10589125407 :                 *t = *s;
      87 10589125407 :                 t++;
      88             :         }
      89             : 
      90   763590411 :         if (in_space && t != start) {
      91             :                 /* the loop will have left a single trailing space */
      92          13 :                 t--;
      93             :         }
      94   763590411 :         *t = '\0';
      95             : 
      96   763590411 :         out->length = t - start;
      97   763590411 :         return 0;
      98             : }
      99             : 
     100             : /* length limited conversion of a ldb_val to an int64_t */
     101    31573150 : static int val_to_int64(const struct ldb_val *in, int64_t *v)
     102             : {
     103     2561074 :         char *end;
     104     2561074 :         char buf[64];
     105             : 
     106             :         /* make sure we don't read past the end of the data */
     107    31573150 :         if (in->length > sizeof(buf)-1) {
     108           0 :                 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     109             :         }
     110    31573150 :         strncpy(buf, (char *)in->data, in->length);
     111    31573150 :         buf[in->length] = 0;
     112             : 
     113    31573150 :         *v = (int64_t) strtoll(buf, &end, 0);
     114    31573150 :         if (*end != 0) {
     115          35 :                 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     116             :         }
     117    29012043 :         return LDB_SUCCESS;
     118             : }
     119             : 
     120             : 
     121             : /*
     122             :   canonicalise a ldap Integer
     123             :   rfc2252 specifies it should be in decimal form
     124             : */
     125      279621 : static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx,
     126             :                                     const struct ldb_val *in, struct ldb_val *out)
     127             : {
     128       25877 :         int64_t i;
     129       25877 :         int ret;
     130             : 
     131      279621 :         ret = val_to_int64(in, &i);
     132      279621 :         if (ret != LDB_SUCCESS) {
     133           3 :                 return ret;
     134             :         }
     135      279618 :         out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i);
     136      279618 :         if (out->data == NULL) {
     137           0 :                 ldb_oom(ldb);
     138           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     139             :         }
     140      279618 :         out->length = strlen((char *)out->data);
     141      279618 :         return 0;
     142             : }
     143             : 
     144             : /*
     145             :  * Lexicographically ordered format for a ldap Integer
     146             :  *
     147             :  * [ INT64_MIN ... -3, -2, -1 | 0 | +1, +2, +3 ... INT64_MAX ]
     148             :  *             n                o              p
     149             :  *
     150             :  * For human readability sake, we continue to format the key as a string
     151             :  * (like the canonicalize) rather than store as a fixed binary representation.
     152             :  *
     153             :  * In order to sort the integers in the correct string order, there are three
     154             :  * techniques we use:
     155             :  *
     156             :  * 1. Zero padding
     157             :  * 2. Negative integer inversion
     158             :  * 3. 1-byte prefixes: 'n' < 'o' < 'p'
     159             :  *
     160             :  * 1. To have a fixed-width representation so that 10 sorts after 2 rather than
     161             :  * after 1, we zero pad, like this 4-byte width example:
     162             :  *
     163             :  *     0001, 0002, 0010
     164             :  *
     165             :  * INT64_MAX = 2^63 - 1 = 9223372036854775807 (19 characters long)
     166             :  *
     167             :  * Meaning we need to pad to 19 characters.
     168             :  *
     169             :  * 2. This works for positive integers, but negative integers will still be
     170             :  * sorted backwards, for example:
     171             :  *
     172             :  *     -9223372036854775808 ..., -0000000000000000002, -0000000000000000001
     173             :  *          INT64_MIN                    -2                    -1
     174             :  *
     175             :  *   gets sorted based on string as:
     176             :  *
     177             :  *     -0000000000000000001, -0000000000000000002, ... -9223372036854775808
     178             :  *
     179             :  * In order to fix this, we invert the negative integer range, so that they
     180             :  * get sorted the same way as positive numbers. INT64_MIN becomes the lowest
     181             :  * possible non-negative number (zero), and -1 becomes the highest (INT64_MAX).
     182             :  *
     183             :  * The actual conversion applied to negative number 'x' is:
     184             :  *   INT64_MAX - abs(x) + 1
     185             :  * (The +1 is needed because abs(INT64_MIN) is one greater than INT64_MAX)
     186             :  *
     187             :  * 3. Finally, we now have two different numbers that map to the same key, e.g.
     188             :  * INT64_MIN maps to -0000000000000000000 and zero maps to 0000000000000000000.
     189             :  * In order to avoid confusion, we give every number a prefix representing its
     190             :  * sign: 'n' for negative numbers, 'o' for zero, and 'p' for positive. (Note
     191             :  * that '+' and '-' weren't used because they sort the wrong way).
     192             :  *
     193             :  * The result is a range of key values that look like this:
     194             :  *
     195             :  *     n0000000000000000000, ... n9223372036854775807,
     196             :  *          INT64_MIN                    -1
     197             :  *
     198             :  *     o0000000000000000000,
     199             :  *            ZERO
     200             :  *
     201             :  *     p0000000000000000001, ... p9223372036854775807
     202             :  *            +1                       INT64_MAX
     203             :  */
     204     5585973 : static int ldb_index_format_Integer(struct ldb_context *ldb,
     205             :                                     void *mem_ctx,
     206             :                                     const struct ldb_val *in,
     207             :                                     struct ldb_val *out)
     208             : {
     209      399425 :         int64_t i;
     210      399425 :         int ret;
     211      399425 :         char prefix;
     212      399425 :         size_t len;
     213             : 
     214     5585973 :         ret = val_to_int64(in, &i);
     215     5585973 :         if (ret != LDB_SUCCESS) {
     216           0 :                 return ret;
     217             :         }
     218             : 
     219     5585973 :         if (i < 0) {
     220             :                 /*
     221             :                  * i is negative, so this is subtraction rather than
     222             :                  * wrap-around.
     223             :                  */
     224         184 :                 prefix = 'n';
     225         184 :                 i = INT64_MAX + i + 1;
     226     5585789 :         } else if (i > 0) {
     227     5186548 :                 prefix = 'p';
     228             :         } else {
     229          24 :                 prefix = 'o';
     230             :         }
     231             : 
     232     5585973 :         out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%c%019lld", prefix, (long long)i);
     233     5585973 :         if (out->data == NULL) {
     234           0 :                 ldb_oom(ldb);
     235           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     236             :         }
     237             : 
     238     5585973 :         len = talloc_array_length(out->data) - 1;
     239     5585973 :         if (len != 20) {
     240           0 :                 ldb_debug(ldb, LDB_DEBUG_ERROR,
     241             :                           __location__ ": expected index format str %s to"
     242             :                           " have length 20 but got %zu",
     243           0 :                           (char*)out->data, len);
     244           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     245             :         }
     246             : 
     247     5585973 :         out->length = 20;
     248     5585973 :         return 0;
     249             : }
     250             : 
     251             : /*
     252             :   compare two Integers
     253             : */
     254    12853778 : static int ldb_comparison_Integer(struct ldb_context *ldb, void *mem_ctx,
     255             :                                   const struct ldb_val *v1, const struct ldb_val *v2)
     256             : {
     257    12853778 :         int64_t i1=0, i2=0;
     258    12853778 :         val_to_int64(v1, &i1);
     259    12853778 :         val_to_int64(v2, &i2);
     260    12853778 :         if (i1 == i2) return 0;
     261    12852006 :         return i1 > i2? 1 : -1;
     262             : }
     263             : 
     264             : /*
     265             :   canonicalise a ldap Boolean
     266             :   rfc2252 specifies it should be either "TRUE" or "FALSE"
     267             : */
     268     2809394 : static int ldb_canonicalise_Boolean(struct ldb_context *ldb, void *mem_ctx,
     269             :                              const struct ldb_val *in, struct ldb_val *out)
     270             : {
     271     2809394 :         if (in->length >= 4 && strncasecmp((char *)in->data, "TRUE", in->length) == 0) {
     272     2521559 :                 out->data = (uint8_t *)talloc_strdup(mem_ctx, "TRUE");
     273     2521559 :                 out->length = 4;
     274      287835 :         } else if (in->length >= 5 && strncasecmp((char *)in->data, "FALSE", in->length) == 0) {
     275      287835 :                 out->data = (uint8_t *)talloc_strdup(mem_ctx, "FALSE");
     276      287835 :                 out->length = 5;
     277             :         } else {
     278           0 :                 return -1;
     279             :         }
     280     2446563 :         return 0;
     281             : }
     282             : 
     283             : /*
     284             :  * compare two Booleans.
     285             :  *
     286             :  * According to RFC4517 4.2.2, "the booleanMatch rule is an equality matching
     287             :  * rule", meaning it isn't used for ordering.
     288             :  *
     289             :  * However, it seems conceivable that Samba could be coerced into sorting on a
     290             :  * field with Boolean syntax, so we might as well have consistent behaviour in
     291             :  * that case.
     292             :  *
     293             :  * The most probably values are {"FALSE", 5} and {"TRUE", 4}. To save time we
     294             :  * compare first by length, which makes FALSE > TRUE. This is somewhat
     295             :  * contrary to convention, but is how Samba has worked forever.
     296             :  *
     297             :  * If somehow we are comparing incompletely normalised values where the length
     298             :  * is the same (for example {"false", 5} and {"TRUE\0", 5}), the length is the
     299             :  * same, and we fall back to a strncasecmp. In this case, since "FALSE" is
     300             :  * alphabetically lower, we swap the order, so that "TRUE\0" again comes
     301             :  * before "FALSE".
     302             :  *
     303             :  * ldb_canonicalise_Boolean (just above) gives us a clue as to what we might
     304             :  * expect to cope with by way of invalid values.
     305             :  */
     306     5602275 : static int ldb_comparison_Boolean(struct ldb_context *ldb, void *mem_ctx,
     307             :                            const struct ldb_val *v1, const struct ldb_val *v2)
     308             : {
     309     5602275 :         if (v1->length != v2->length) {
     310          89 :                 return NUMERIC_CMP(v2->length, v1->length);
     311             :         }
     312             :         /* reversed, see long comment above */
     313     5602186 :         return strncasecmp((char *)v2->data, (char *)v1->data, v1->length);
     314             : }
     315             : 
     316             : 
     317             : /*
     318             :   compare two binary blobs
     319             : */
     320    27914097 : int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx,
     321             :                           const struct ldb_val *v1, const struct ldb_val *v2)
     322             : {
     323    27914097 :         if (v1->length != v2->length) {
     324       28933 :                 return NUMERIC_CMP(v1->length, v2->length);
     325             :         }
     326    27885164 :         return memcmp(v1->data, v2->data, v1->length);
     327             : }
     328             : 
     329             : /*
     330             :  * ldb_comparison_fold is a schema syntax comparison_fn for utf-8 strings that
     331             :  * collapse multiple spaces into one (e.g. "Directory String" syntax).
     332             :  *
     333             :  * The default comparison function only performs ASCII case-folding, and only
     334             :  * collapses multiple spaces, not tabs and other whitespace (contrary to
     335             :  * RFC4518). To change the comparison function (as Samba does), use
     336             :  * ldb_set_utf8_functions().
     337             :  */
     338   232028616 : int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx,
     339             :                         const struct ldb_val *v1, const struct ldb_val *v2)
     340             : {
     341   232028616 :         return ldb->utf8_fns.casecmp(ldb->utf8_fns.context, v1, v2);
     342             : }
     343             : 
     344             : 
     345             : /*
     346             :   canonicalise a attribute in DN format
     347             : */
     348           6 : static int ldb_canonicalise_dn(struct ldb_context *ldb, void *mem_ctx,
     349             :                                const struct ldb_val *in, struct ldb_val *out)
     350             : {
     351           6 :         struct ldb_dn *dn;
     352           6 :         int ret = -1;
     353             : 
     354           6 :         out->length = 0;
     355           6 :         out->data = NULL;
     356             : 
     357           6 :         dn = ldb_dn_from_ldb_val(mem_ctx, ldb, in);
     358           6 :         if ( ! ldb_dn_validate(dn)) {
     359           0 :                 return LDB_ERR_INVALID_DN_SYNTAX;
     360             :         }
     361             : 
     362           6 :         out->data = (uint8_t *)ldb_dn_alloc_casefold(mem_ctx, dn);
     363           6 :         if (out->data == NULL) {
     364           0 :                 goto done;
     365             :         }
     366           6 :         out->length = strlen((char *)out->data);
     367             : 
     368           6 :         ret = 0;
     369             : 
     370           6 : done:
     371           6 :         talloc_free(dn);
     372             : 
     373           6 :         return ret;
     374             : }
     375             : 
     376             : /*
     377             :   compare two dns
     378             : */
     379           0 : static int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx,
     380             :                              const struct ldb_val *v1, const struct ldb_val *v2)
     381             : {
     382           0 :         struct ldb_dn *dn1 = NULL, *dn2 = NULL;
     383           0 :         int ret;
     384             : 
     385           0 :         dn1 = ldb_dn_from_ldb_val(mem_ctx, ldb, v1);
     386           0 :         if ( ! ldb_dn_validate(dn1)) return -1;
     387             : 
     388           0 :         dn2 = ldb_dn_from_ldb_val(mem_ctx, ldb, v2);
     389           0 :         if ( ! ldb_dn_validate(dn2)) {
     390           0 :                 talloc_free(dn1);
     391           0 :                 return -1;
     392             :         }
     393             : 
     394           0 :         ret = ldb_dn_compare(dn1, dn2);
     395             : 
     396           0 :         talloc_free(dn1);
     397           0 :         talloc_free(dn2);
     398           0 :         return ret;
     399             : }
     400             : 
     401             : /*
     402             :   compare two utc time values. 1 second resolution
     403             : */
     404      601020 : static int ldb_comparison_utctime(struct ldb_context *ldb, void *mem_ctx,
     405             :                                   const struct ldb_val *v1, const struct ldb_val *v2)
     406             : {
     407      601020 :         time_t t1=0, t2=0;
     408      601020 :         ldb_val_to_time(v1, &t1);
     409      601020 :         ldb_val_to_time(v2, &t2);
     410      601020 :         if (t1 == t2) return 0;
     411      313907 :         return t1 > t2? 1 : -1;
     412             : }
     413             : 
     414             : /*
     415             :   canonicalise a utc time
     416             : */
     417           0 : static int ldb_canonicalise_utctime(struct ldb_context *ldb, void *mem_ctx,
     418             :                                     const struct ldb_val *in, struct ldb_val *out)
     419             : {
     420           0 :         time_t t;
     421           0 :         int ret;
     422           0 :         ret = ldb_val_to_time(in, &t);
     423           0 :         if (ret != LDB_SUCCESS) {
     424           0 :                 return ret;
     425             :         }
     426           0 :         out->data = (uint8_t *)ldb_timestring_utc(mem_ctx, t);
     427           0 :         if (out->data == NULL) {
     428           0 :                 ldb_oom(ldb);
     429           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     430             :         }
     431           0 :         out->length = strlen((char *)out->data);
     432           0 :         return 0;
     433             : }
     434             : 
     435             : /*
     436             :   canonicalise a generalized time
     437             : */
     438       10948 : static int ldb_canonicalise_generalizedtime(struct ldb_context *ldb, void *mem_ctx,
     439             :                                         const struct ldb_val *in, struct ldb_val *out)
     440             : {
     441           0 :         time_t t;
     442           0 :         int ret;
     443       10948 :         ret = ldb_val_to_time(in, &t);
     444       10948 :         if (ret != LDB_SUCCESS) {
     445           0 :                 return ret;
     446             :         }
     447       10948 :         out->data = (uint8_t *)ldb_timestring(mem_ctx, t);
     448       10948 :         if (out->data == NULL) {
     449           0 :                 ldb_oom(ldb);
     450           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     451             :         }
     452       10948 :         out->length = strlen((char *)out->data);
     453       10948 :         return 0;
     454             : }
     455             : 
     456             : /*
     457             :   table of standard attribute handlers
     458             : */
     459             : static const struct ldb_schema_syntax ldb_standard_syntaxes[] = {
     460             :         {
     461             :                 .name            = LDB_SYNTAX_INTEGER,
     462             :                 .ldif_read_fn    = ldb_handler_copy,
     463             :                 .ldif_write_fn   = ldb_handler_copy,
     464             :                 .canonicalise_fn = ldb_canonicalise_Integer,
     465             :                 .comparison_fn   = ldb_comparison_Integer
     466             :         },
     467             :         {
     468             :                 .name            = LDB_SYNTAX_ORDERED_INTEGER,
     469             :                 .ldif_read_fn    = ldb_handler_copy,
     470             :                 .ldif_write_fn   = ldb_handler_copy,
     471             :                 .canonicalise_fn = ldb_canonicalise_Integer,
     472             :                 .index_format_fn = ldb_index_format_Integer,
     473             :                 .comparison_fn   = ldb_comparison_Integer
     474             :         },
     475             :         {
     476             :                 .name            = LDB_SYNTAX_OCTET_STRING,
     477             :                 .ldif_read_fn    = ldb_handler_copy,
     478             :                 .ldif_write_fn   = ldb_handler_copy,
     479             :                 .canonicalise_fn = ldb_handler_copy,
     480             :                 .comparison_fn   = ldb_comparison_binary
     481             :         },
     482             :         {
     483             :                 .name            = LDB_SYNTAX_DIRECTORY_STRING,
     484             :                 .ldif_read_fn    = ldb_handler_copy,
     485             :                 .ldif_write_fn   = ldb_handler_copy,
     486             :                 .canonicalise_fn = ldb_handler_fold,
     487             :                 .comparison_fn   = ldb_comparison_fold
     488             :         },
     489             :         {
     490             :                 .name            = LDB_SYNTAX_DN,
     491             :                 .ldif_read_fn    = ldb_handler_copy,
     492             :                 .ldif_write_fn   = ldb_handler_copy,
     493             :                 .canonicalise_fn = ldb_canonicalise_dn,
     494             :                 .comparison_fn   = ldb_comparison_dn
     495             :         },
     496             :         {
     497             :                 .name            = LDB_SYNTAX_OBJECTCLASS,
     498             :                 .ldif_read_fn    = ldb_handler_copy,
     499             :                 .ldif_write_fn   = ldb_handler_copy,
     500             :                 .canonicalise_fn = ldb_handler_fold,
     501             :                 .comparison_fn   = ldb_comparison_fold
     502             :         },
     503             :         {
     504             :                 .name            = LDB_SYNTAX_UTC_TIME,
     505             :                 .ldif_read_fn    = ldb_handler_copy,
     506             :                 .ldif_write_fn   = ldb_handler_copy,
     507             :                 .canonicalise_fn = ldb_canonicalise_utctime,
     508             :                 .comparison_fn   = ldb_comparison_utctime
     509             :         },
     510             :         {
     511             :                 .name            = LDB_SYNTAX_GENERALIZED_TIME,
     512             :                 .ldif_read_fn    = ldb_handler_copy,
     513             :                 .ldif_write_fn   = ldb_handler_copy,
     514             :                 .canonicalise_fn = ldb_canonicalise_generalizedtime,
     515             :                 .comparison_fn   = ldb_comparison_utctime
     516             :         },
     517             :         {
     518             :                 .name            = LDB_SYNTAX_BOOLEAN,
     519             :                 .ldif_read_fn    = ldb_handler_copy,
     520             :                 .ldif_write_fn   = ldb_handler_copy,
     521             :                 .canonicalise_fn = ldb_canonicalise_Boolean,
     522             :                 .comparison_fn   = ldb_comparison_Boolean
     523             :         },
     524             : };
     525             : 
     526             : 
     527             : /*
     528             :   return the attribute handlers for a given syntax name
     529             : */
     530   163712355 : const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *ldb,
     531             :                                                             const char *syntax)
     532             : {
     533     5378679 :         unsigned int i;
     534   163712355 :         unsigned num_handlers = sizeof(ldb_standard_syntaxes)/sizeof(ldb_standard_syntaxes[0]);
     535             :         /* TODO: should be replaced with a binary search */
     536   639339820 :         for (i=0;i<num_handlers;i++) {
     537   639339820 :                 if (strcmp(ldb_standard_syntaxes[i].name, syntax) == 0) {
     538   163712355 :                         return &ldb_standard_syntaxes[i];
     539             :                 }
     540             :         }
     541           0 :         return NULL;
     542             : }
     543             : 
     544       78160 : int ldb_any_comparison(struct ldb_context *ldb, void *mem_ctx,
     545             :                        ldb_attr_handler_t canonicalise_fn,
     546             :                        const struct ldb_val *v1,
     547             :                        const struct ldb_val *v2)
     548             : {
     549        1833 :         int ret, ret1, ret2;
     550        1833 :         struct ldb_val v1_canon, v2_canon;
     551       78160 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     552             : 
     553             :         /* I could try and bail if tmp_ctx was NULL, but what return
     554             :          * value would I use?
     555             :          *
     556             :          * It seems easier to continue on the NULL context
     557             :          */
     558       78160 :         ret1 = canonicalise_fn(ldb, tmp_ctx, v1, &v1_canon);
     559       78160 :         ret2 = canonicalise_fn(ldb, tmp_ctx, v2, &v2_canon);
     560             : 
     561       78160 :         if (ret1 == LDB_SUCCESS && ret2 == LDB_SUCCESS) {
     562       78136 :                 ret = ldb_comparison_binary(ldb, mem_ctx, &v1_canon, &v2_canon);
     563             :         } else {
     564          24 :                 ret = ldb_comparison_binary(ldb, mem_ctx, v1, v2);
     565             :         }
     566       78160 :         talloc_free(tmp_ctx);
     567       78160 :         return ret;
     568             : }

Generated by: LCOV version 1.14