LCOV - code coverage report
Current view: top level - lib/ldb/common - ldb_dn.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 939 1138 82.5 %
Date: 2024-04-13 12:30:31 Functions: 51 51 100.0 %

          Line data    Source code
       1             : /*
       2             :    ldb database library
       3             : 
       4             :    Copyright (C) Simo Sorce 2005
       5             : 
       6             :      ** NOTE! The following LGPL license applies to the ldb
       7             :      ** library. This does NOT imply that all of Samba is released
       8             :      ** under the LGPL
       9             : 
      10             :    This library is free software; you can redistribute it and/or
      11             :    modify it under the terms of the GNU Lesser General Public
      12             :    License as published by the Free Software Foundation; either
      13             :    version 3 of the License, or (at your option) any later version.
      14             : 
      15             :    This library is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      18             :    Lesser General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU Lesser General Public
      21             :    License along with this library; if not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : /*
      25             :  *  Name: ldb
      26             :  *
      27             :  *  Component: ldb dn creation and manipulation utility functions
      28             :  *
      29             :  *  Description: - explode a dn into it's own basic elements
      30             :  *                 and put them in a structure (only if necessary)
      31             :  *               - manipulate ldb_dn structures
      32             :  *
      33             :  *  Author: Simo Sorce
      34             :  */
      35             : 
      36             : #include "ldb_private.h"
      37             : #include <ctype.h>
      38             : 
      39             : #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
      40             : 
      41             : #define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0)
      42             : 
      43             : /**
      44             :    internal ldb exploded dn structures
      45             : */
      46             : struct ldb_dn_component {
      47             : 
      48             :         char *name;
      49             :         struct ldb_val value;
      50             : 
      51             :         char *cf_name;
      52             :         struct ldb_val cf_value;
      53             : };
      54             : 
      55             : struct ldb_dn_ext_component {
      56             : 
      57             :         const char *name;
      58             :         struct ldb_val value;
      59             : };
      60             : 
      61             : struct ldb_dn {
      62             : 
      63             :         struct ldb_context *ldb;
      64             : 
      65             :         /* Special DNs are always linearized */
      66             :         bool special;
      67             :         bool invalid;
      68             : 
      69             :         bool valid_case;
      70             : 
      71             :         char *linearized;
      72             :         char *ext_linearized;
      73             :         char *casefold;
      74             : 
      75             :         unsigned int comp_num;
      76             :         struct ldb_dn_component *components;
      77             : 
      78             :         unsigned int ext_comp_num;
      79             :         struct ldb_dn_ext_component *ext_components;
      80             : };
      81             : 
      82             : /* it is helpful to be able to break on this in gdb */
      83       20198 : static void ldb_dn_mark_invalid(struct ldb_dn *dn)
      84             : {
      85       20198 :         dn->invalid = true;
      86       20181 : }
      87             : 
      88             : /* strdn may be NULL */
      89   912137993 : struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx,
      90             :                                    struct ldb_context *ldb,
      91             :                                    const struct ldb_val *strdn)
      92             : {
      93    25117705 :         struct ldb_dn *dn;
      94             : 
      95   912137993 :         if (ldb == NULL || strdn == NULL) {
      96           0 :                 return NULL;
      97             :         }
      98   912137993 :         if (strdn->data
      99   882823916 :             && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) {
     100             :                 /* The RDN must not contain a character with value 0x0 */
     101           0 :                 return NULL;
     102             :         }
     103             : 
     104   912137990 :         dn = talloc_zero(mem_ctx, struct ldb_dn);
     105   912137990 :         LDB_DN_NULL_FAILED(dn);
     106             : 
     107   912137990 :         dn->ldb = talloc_get_type(ldb, struct ldb_context);
     108   912137990 :         if (dn->ldb == NULL) {
     109             :                 /* the caller probably got the arguments to
     110             :                    ldb_dn_new() mixed up */
     111           0 :                 talloc_free(dn);
     112           0 :                 return NULL;
     113             :         }
     114             : 
     115  1769549729 :         if (strdn->data && strdn->length) {
     116   881919086 :                 const char *data = (const char *)strdn->data;
     117   881919086 :                 size_t length = strdn->length;
     118             : 
     119   881919086 :                 if (data[0] == '@') {
     120   411746873 :                         dn->special = true;
     121             :                 }
     122   881919086 :                 dn->ext_linearized = talloc_strndup(dn, data, length);
     123   881919086 :                 LDB_DN_NULL_FAILED(dn->ext_linearized);
     124             : 
     125   881919086 :                 if (data[0] == '<') {
     126    41908812 :                         const char *p_save, *p = dn->ext_linearized;
     127     2309986 :                         do {
     128   121539960 :                                 p_save = p;
     129   121539960 :                                 p = strstr(p, ">;");
     130   121539960 :                                 if (p) {
     131    78524648 :                                         p = p + 2;
     132             :                                 }
     133   121539960 :                         } while (p);
     134             : 
     135    43015312 :                         if (p_save == dn->ext_linearized) {
     136     8454974 :                                 dn->linearized = talloc_strdup(dn, "");
     137             :                         } else {
     138    34560338 :                                 dn->linearized = talloc_strdup(dn, p_save);
     139             :                         }
     140    43015312 :                         LDB_DN_NULL_FAILED(dn->linearized);
     141             :                 } else {
     142   838903774 :                         dn->linearized = dn->ext_linearized;
     143   838903774 :                         dn->ext_linearized = NULL;
     144             :                 }
     145             :         } else {
     146    30218904 :                 dn->linearized = talloc_strdup(dn, "");
     147    30218904 :                 LDB_DN_NULL_FAILED(dn->linearized);
     148             :         }
     149             : 
     150   887020288 :         return dn;
     151             : 
     152           0 : failed:
     153           0 :         talloc_free(dn);
     154           0 :         return NULL;
     155             : }
     156             : 
     157             : /* strdn may be NULL */
     158   343360520 : struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx,
     159             :                           struct ldb_context *ldb,
     160             :                           const char *strdn)
     161             : {
     162    11250084 :         struct ldb_val blob;
     163   343360520 :         blob.data = discard_const_p(uint8_t, strdn);
     164   343360520 :         blob.length = strdn ? strlen(strdn) : 0;
     165   343360520 :         return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
     166             : }
     167             : 
     168   200783003 : struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx,
     169             :                               struct ldb_context *ldb,
     170             :                               const char *new_fmt, ...)
     171             : {
     172     6580859 :         char *strdn;
     173     6580859 :         va_list ap;
     174             : 
     175   200783003 :         if (! ldb) return NULL;
     176             : 
     177   200783003 :         va_start(ap, new_fmt);
     178   200783003 :         strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
     179   200783003 :         va_end(ap);
     180             : 
     181   200783003 :         if (strdn) {
     182   200783003 :                 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
     183   200783003 :                 talloc_free(strdn);
     184   200783003 :                 return dn;
     185             :         }
     186             : 
     187           0 :         return NULL;
     188             : }
     189             : 
     190             : /* see RFC2253 section 2.4 */
     191   233022306 : static int ldb_dn_escape_internal(char *dst, const char *src, int len)
     192             : {
     193    14344417 :         char c;
     194    14344417 :         char *d;
     195    14344417 :         int i;
     196   233022306 :         d = dst;
     197             : 
     198  2238541212 :         for (i = 0; i < len; i++){
     199  2005518906 :                 c = src[i];
     200  2005518906 :                 switch (c) {
     201    14873450 :                 case ' ':
     202    14873450 :                         if (i == 0 || i == len - 1) {
     203             :                                 /* if at the beginning or end
     204             :                                  * of the string then escape */
     205           0 :                                 *d++ = '\\';
     206           0 :                                 *d++ = c;
     207             :                         } else {
     208             :                                 /* otherwise don't escape */
     209    14873450 :                                 *d++ = c;
     210             :                         }
     211    13942079 :                         break;
     212             : 
     213       37089 :                 case '#':
     214             :                         /* despite the RFC, windows escapes a #
     215             :                            anywhere in the string */
     216             :                 case ',':
     217             :                 case '+':
     218             :                 case '"':
     219             :                 case '\\':
     220             :                 case '<':
     221             :                 case '>':
     222             :                 case '?':
     223             :                         /* these must be escaped using \c form */
     224       37089 :                         *d++ = '\\';
     225       37089 :                         *d++ = c;
     226       37089 :                         break;
     227             : 
     228     1698258 :                 case ';':
     229             :                 case '\r':
     230             :                 case '\n':
     231             :                 case '=':
     232             :                 case '\0': {
     233             :                         /* any others get \XX form */
     234         925 :                         unsigned char v;
     235     1698258 :                         const char *hexbytes = "0123456789ABCDEF";
     236     1698258 :                         v = (const unsigned char)c;
     237     1698258 :                         *d++ = '\\';
     238     1698258 :                         *d++ = hexbytes[v>>4];
     239     1698258 :                         *d++ = hexbytes[v&0xF];
     240     1698258 :                         break;
     241             :                 }
     242  1988910109 :                 default:
     243  1988910109 :                         *d++ = c;
     244             :                 }
     245             :         }
     246             : 
     247             :         /* return the length of the resulting string */
     248   233022306 :         return (d - dst);
     249             : }
     250             : 
     251    15615701 : char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value)
     252             : {
     253      952973 :         char *dst;
     254      952973 :         size_t len;
     255    15615701 :         if (!value.length)
     256           2 :                 return NULL;
     257             : 
     258             :         /* allocate destination string, it will be at most 3 times the source */
     259    15615699 :         dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
     260    15615699 :         if ( ! dst) {
     261           0 :                 talloc_free(dst);
     262           0 :                 return NULL;
     263             :         }
     264             : 
     265    15615699 :         len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
     266             : 
     267    15615699 :         dst = talloc_realloc(mem_ctx, dst, char, len + 1);
     268    15615699 :         if ( ! dst) {
     269           0 :                 talloc_free(dst);
     270           0 :                 return NULL;
     271             :         }
     272    15615699 :         dst[len] = '\0';
     273    15615699 :         return dst;
     274             : }
     275             : 
     276             : /*
     277             :   explode a DN string into a ldb_dn structure
     278             :   based on RFC4514 except that we don't support multiple valued RDNs
     279             : 
     280             :   TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints
     281             :   DN must be compliant with RFC2253
     282             : */
     283  1225665028 : static bool ldb_dn_explode(struct ldb_dn *dn)
     284             : {
     285  1225665028 :         char *p, *ex_name = NULL, *ex_value = NULL, *data, *d, *dt, *t;
     286  1225665028 :         bool trim = true;
     287  1225665028 :         bool in_extended = true;
     288  1225665028 :         bool in_ex_name = false;
     289  1225665028 :         bool in_ex_value = false;
     290  1225665028 :         bool in_attr = false;
     291  1225665028 :         bool in_value = false;
     292  1225665028 :         bool in_quote = false;
     293  1225665028 :         bool is_oid = false;
     294  1225665028 :         bool escape = false;
     295    36094505 :         unsigned int x;
     296  1225665028 :         size_t l = 0;
     297    36094505 :         int ret;
     298    36094505 :         char *parse_dn;
     299    36094505 :         bool is_index;
     300             : 
     301  1225665028 :         if (dn == NULL || dn->invalid) {
     302         723 :                 return false;
     303             :         }
     304             : 
     305  1225664305 :         if (dn->components != NULL) {
     306   640498188 :                 return true;
     307             :         }
     308             : 
     309   562720863 :         if (dn->ext_linearized != NULL) {
     310    38602473 :                 parse_dn = dn->ext_linearized;
     311             :         } else {
     312   523251918 :                 parse_dn = dn->linearized;
     313             :         }
     314             : 
     315   562720863 :         if (parse_dn == NULL) {
     316           0 :                 return false;
     317             :         }
     318             : 
     319   562720863 :         is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
     320             : 
     321             :         /* Empty DNs */
     322   562720863 :         if (parse_dn[0] == '\0') {
     323    30678793 :                 return true;
     324             :         }
     325             : 
     326             :         /* Special DNs case */
     327   531110702 :         if (dn->special) {
     328   255999470 :                 return true;
     329             :         }
     330             : 
     331   267434537 :         LDB_FREE(dn->ext_components);
     332   267434537 :         dn->ext_comp_num = 0;
     333   267434537 :         dn->comp_num = 0;
     334             : 
     335             :         /* in the common case we have 3 or more components */
     336             :         /* make sure all components are zeroed, other functions depend on it */
     337   267434537 :         dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
     338   267434537 :         if (dn->components == NULL) {
     339           0 :                 return false;
     340             :         }
     341             : 
     342             :         /* Components data space is allocated here once */
     343   267434537 :         data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
     344   267434537 :         if (data == NULL) {
     345           0 :                 goto failed;
     346             :         }
     347             : 
     348   262393349 :         p = parse_dn;
     349   262393349 :         t = NULL;
     350   262393349 :         d = dt = data;
     351             : 
     352 26108309096 :         while (*p) {
     353 25849330763 :                 if (in_extended) {
     354             : 
     355  3267902146 :                         if (!in_ex_name && !in_ex_value) {
     356             : 
     357   337778610 :                                 if (p[0] == '<') {
     358    78799063 :                                         p++;
     359    78799063 :                                         ex_name = d;
     360    78799063 :                                         in_ex_name = true;
     361    78799063 :                                         continue;
     362             :                                 } else {
     363   258979547 :                                         in_extended = false;
     364   258979547 :                                         in_attr = true;
     365   258979547 :                                         dt = d;
     366             : 
     367   258979547 :                                         continue;
     368             :                                 }
     369             :                         }
     370             : 
     371  2930123536 :                         if (in_ex_name && *p == '=') {
     372    78799059 :                                 *d++ = '\0';
     373    78799059 :                                 p++;
     374    78799059 :                                 ex_value = d;
     375    78799059 :                                 in_ex_name = false;
     376    78799059 :                                 in_ex_value = true;
     377    78799059 :                                 continue;
     378             :                         }
     379             : 
     380  2851324477 :                         if (in_ex_value && *p == '>') {
     381    78799059 :                                 struct ldb_dn_ext_component *ext_comp = NULL;
     382     1164902 :                                 const struct ldb_dn_extended_syntax *ext_syntax;
     383    78799059 :                                 struct ldb_val ex_val = {
     384             :                                         .data = (uint8_t *)ex_value,
     385    78799059 :                                         .length = d - ex_value
     386             :                                 };
     387             : 
     388    78799059 :                                 *d++ = '\0';
     389    78799059 :                                 p++;
     390    78799059 :                                 in_ex_value = false;
     391             : 
     392             :                                 /* Process name and ex_value */
     393             : 
     394    78799059 :                                 ext_comp = talloc_realloc(
     395             :                                         dn,
     396             :                                         dn->ext_components,
     397             :                                         struct ldb_dn_ext_component,
     398             :                                         dn->ext_comp_num + 1);
     399             : 
     400    78799059 :                                 if (ext_comp == NULL) {
     401             :                                         /* ouch ! */
     402         450 :                                         goto failed;
     403             :                                 }
     404             : 
     405    78799059 :                                 dn->ext_components = ext_comp;
     406             : 
     407    78799059 :                                 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
     408    78799059 :                                 if (ext_syntax == NULL) {
     409             :                                         /* We don't know about this type of extended DN */
     410           9 :                                         goto failed;
     411             :                                 }
     412             : 
     413    78799050 :                                 dn->ext_components[dn->ext_comp_num].name = ext_syntax->name;
     414    78799050 :                                 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
     415    77634149 :                                                           &ex_val, &dn->ext_components[dn->ext_comp_num].value);
     416    78799050 :                                 if (ret != LDB_SUCCESS) {
     417         441 :                                         ldb_dn_mark_invalid(dn);
     418         441 :                                         goto failed;
     419             :                                 }
     420             : 
     421    78798609 :                                 dn->ext_comp_num++;
     422             : 
     423    78798609 :                                 if (*p == '\0') {
     424             :                                         /* We have reached the end (extended component only)! */
     425     8454536 :                                         talloc_free(data);
     426     8454536 :                                         return true;
     427             : 
     428    70344073 :                                 } else if (*p == ';') {
     429    70344073 :                                         p++;
     430    70344073 :                                         continue;
     431             :                                 } else {
     432           0 :                                         ldb_dn_mark_invalid(dn);
     433           0 :                                         goto failed;
     434             :                                 }
     435             :                         }
     436             : 
     437  2772525418 :                         *d++ = *p++;
     438  2772525418 :                         continue;
     439             :                 }
     440 22581428617 :                 if (in_attr) {
     441  4493094045 :                         if (trim) {
     442  1519105664 :                                 if (*p == ' ') {
     443    34066664 :                                         p++;
     444    34066664 :                                         continue;
     445             :                                 }
     446             : 
     447             :                                 /* first char */
     448  1485039000 :                                 trim = false;
     449             : 
     450  1485039000 :                                 if (!isascii(*p)) {
     451             :                                         /* attr names must be ascii only */
     452           0 :                                         ldb_dn_mark_invalid(dn);
     453           0 :                                         goto failed;
     454             :                                 }
     455             : 
     456  1485039000 :                                 if (isdigit(*p)) {
     457           0 :                                         is_oid = true;
     458             :                                 } else
     459  1485039000 :                                 if ( ! isalpha(*p)) {
     460             :                                         /* not a digit nor an alpha,
     461             :                                          * invalid attribute name */
     462           7 :                                         ldb_dn_mark_invalid(dn);
     463           7 :                                         goto failed;
     464             :                                 }
     465             : 
     466             :                                 /* Copy this character across from parse_dn,
     467             :                                  * now we have trimmed out spaces */
     468  1485038993 :                                 *d++ = *p++;
     469  1485038993 :                                 continue;
     470             :                         }
     471             : 
     472  2973988381 :                         if (*p == ' ') {
     473          96 :                                 p++;
     474             :                                 /* valid only if we are at the end */
     475          96 :                                 trim = true;
     476          96 :                                 continue;
     477             :                         }
     478             : 
     479  2973988285 :                         if (*p == '=') {
     480             :                                 /* attribute terminated */
     481  1485019152 :                                 in_attr = false;
     482  1485019152 :                                 in_value = true;
     483  1485019152 :                                 trim = true;
     484  1485019152 :                                 l = 0;
     485             : 
     486             :                                 /* Terminate this string in d
     487             :                                  * (which is a copy of parse_dn
     488             :                                  *  with spaces trimmed) */
     489  1485019152 :                                 *d++ = '\0';
     490  1485019152 :                                 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
     491  1485019152 :                                 if (dn->components[dn->comp_num].name == NULL) {
     492             :                                         /* ouch */
     493           0 :                                         goto failed;
     494             :                                 }
     495             : 
     496  1485019152 :                                 dt = d;
     497             : 
     498  1485019152 :                                 p++;
     499  1485019152 :                                 continue;
     500             :                         }
     501             : 
     502  1488969133 :                         if (!isascii(*p)) {
     503             :                                 /* attr names must be ascii only */
     504           0 :                                 ldb_dn_mark_invalid(dn);
     505           0 :                                 goto failed;
     506             :                         }
     507             : 
     508  1488969133 :                         if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
     509             :                                 /* not a digit nor a dot,
     510             :                                  * invalid attribute oid */
     511           0 :                                 ldb_dn_mark_invalid(dn);
     512           0 :                                 goto failed;
     513             :                         } else
     514  1488969133 :                         if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
     515             :                                 /* not ALPHA, DIGIT or HYPHEN */
     516        1211 :                                 ldb_dn_mark_invalid(dn);
     517        1211 :                                 goto failed;
     518             :                         }
     519             : 
     520  1488967922 :                         *d++ = *p++;
     521  1488967922 :                         continue;
     522             :                 }
     523             : 
     524 18088334572 :                 if (in_value) {
     525 18088334572 :                         if (in_quote) {
     526           0 :                                 if (*p == '\"') {
     527           0 :                                         if (p[-1] != '\\') {
     528           0 :                                                 p++;
     529           0 :                                                 in_quote = false;
     530           0 :                                                 continue;
     531             :                                         }
     532             :                                 }
     533           0 :                                 *d++ = *p++;
     534           0 :                                 l++;
     535           0 :                                 continue;
     536             :                         }
     537             : 
     538 18088334572 :                         if (trim) {
     539  1485019144 :                                 if (*p == ' ') {
     540           0 :                                         p++;
     541           0 :                                         continue;
     542             :                                 }
     543             : 
     544             :                                 /* first char */
     545  1485019144 :                                 trim = false;
     546             : 
     547  1485019144 :                                 if (*p == '\"') {
     548           0 :                                         in_quote = true;
     549           0 :                                         p++;
     550           0 :                                         continue;
     551             :                                 }
     552             :                         }
     553             : 
     554 18088334572 :                         switch (*p) {
     555             : 
     556             :                         /* TODO: support ber encoded values
     557             :                         case '#':
     558             :                         */
     559             : 
     560  1226086209 :                         case ',':
     561  1226086209 :                                 if (escape) {
     562       26847 :                                         *d++ = *p++;
     563       26847 :                                         l++;
     564       26847 :                                         escape = false;
     565       26847 :                                         continue;
     566             :                                 }
     567             :                                 /* ok found value terminator */
     568             : 
     569  1226059362 :                                 if (t != NULL) {
     570             :                                         /* trim back */
     571          44 :                                         d -= (p - t);
     572          44 :                                         l -= (p - t);
     573          44 :                                         t = NULL;
     574             :                                 }
     575             : 
     576  1226059362 :                                 in_attr = true;
     577  1226059362 :                                 in_value = false;
     578  1226059362 :                                 trim = true;
     579             : 
     580  1226059362 :                                 p++;
     581  1226059362 :                                 *d++ = '\0';
     582             : 
     583             :                                 /*
     584             :                                  * This talloc_memdup() is OK with the
     585             :                                  * +1 because *d has been set to '\0'
     586             :                                  * just above
     587             :                                  */
     588  2452118724 :                                 dn->components[dn->comp_num].value.data = \
     589  1226059362 :                                         (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
     590  1226059362 :                                 dn->components[dn->comp_num].value.length = l;
     591  1226059362 :                                 if (dn->components[dn->comp_num].value.data == NULL) {
     592             :                                         /* ouch ! */
     593           0 :                                         goto failed;
     594             :                                 }
     595  1226059362 :                                 talloc_set_name_const(dn->components[dn->comp_num].value.data,
     596  1201832934 :                                                       (const char *)dn->components[dn->comp_num].value.data);
     597             : 
     598  1226059362 :                                 dt = d;
     599             : 
     600  1226059362 :                                 dn->comp_num++;
     601  1226059362 :                                 if (dn->comp_num > 2) {
     602   716884316 :                                         dn->components = talloc_realloc(dn,
     603             :                                                                         dn->components,
     604             :                                                                         struct ldb_dn_component,
     605             :                                                                         dn->comp_num + 1);
     606   716884316 :                                         if (dn->components == NULL) {
     607             :                                                 /* ouch ! */
     608           0 :                                                 goto failed;
     609             :                                         }
     610             :                                         /* make sure all components are zeroed, other functions depend on this */
     611   716884316 :                                         memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
     612             :                                 }
     613             : 
     614  1226059362 :                                 continue;
     615             : 
     616           0 :                         case '+':
     617             :                         case '=':
     618             :                                 /* to main compatibility with earlier
     619             :                                 versions of ldb indexing, we have to
     620             :                                 accept the base64 encoded binary index
     621             :                                 values, which contain a '+' or '='
     622             :                                 which should normally be escaped */
     623           0 :                                 if (is_index) {
     624           0 :                                         if (t != NULL) {
     625           0 :                                                 t = NULL;
     626             :                                         }
     627           0 :                                         *d++ = *p++;
     628           0 :                                         l++;
     629           0 :                                         break;
     630             :                                 }
     631             : 
     632           0 :                                 FALL_THROUGH;
     633             :                         case '\"':
     634             :                         case '<':
     635             :                         case '>':
     636             :                         case ';':
     637             :                                 /* a string with not escaped specials is invalid (tested) */
     638           0 :                                 if (!escape) {
     639           0 :                                         ldb_dn_mark_invalid(dn);
     640           0 :                                         goto failed;
     641             :                                 }
     642           0 :                                 escape = false;
     643             : 
     644           0 :                                 *d++ = *p++;
     645           0 :                                 l++;
     646             : 
     647           0 :                                 if (t != NULL) {
     648           0 :                                         t = NULL;
     649             :                                 }
     650           0 :                                 break;
     651             : 
     652    85398718 :                         case '\\':
     653    85398718 :                                 if (!escape) {
     654    85387918 :                                         escape = true;
     655    85387918 :                                         p++;
     656    85387918 :                                         continue;
     657             :                                 }
     658       10800 :                                 escape = false;
     659             : 
     660       10800 :                                 *d++ = *p++;
     661       10800 :                                 l++;
     662             : 
     663       10800 :                                 if (t != NULL) {
     664           0 :                                         t = NULL;
     665             :                                 }
     666       10800 :                                 break;
     667             : 
     668 16776849645 :                         default:
     669 16776849645 :                                 if (escape) {
     670    85350271 :                                         if (isxdigit(p[0]) && isxdigit(p[1])) {
     671    85350271 :                                                 if (sscanf(p, "%02x", &x) != 1) {
     672             :                                                         /* invalid escaping sequence */
     673           0 :                                                         ldb_dn_mark_invalid(dn);
     674           0 :                                                         goto failed;
     675             :                                                 }
     676    85350271 :                                                 p += 2;
     677    85350271 :                                                 *d++ = (unsigned char)x;
     678             :                                         } else {
     679           0 :                                                 *d++ = *p++;
     680             :                                         }
     681             : 
     682    85350271 :                                         escape = false;
     683    85350271 :                                         l++;
     684    85350271 :                                         if (t != NULL) {
     685           0 :                                                 t = NULL;
     686             :                                         }
     687    85349363 :                                         break;
     688             :                                 }
     689             : 
     690 16691499374 :                                 if (*p == ' ') {
     691   124206161 :                                         if (t == NULL) {
     692   124202068 :                                                 t = p;
     693             :                                         }
     694             :                                 } else {
     695 16312065475 :                                         if (t != NULL) {
     696   123092302 :                                                 t = NULL;
     697             :                                         }
     698             :                                 }
     699             : 
     700 16691499374 :                                 *d++ = *p++;
     701 16691499374 :                                 l++;
     702             : 
     703 16691499374 :                                 break;
     704             :                         }
     705             : 
     706             :                 }
     707             :         }
     708             : 
     709   258978333 :         if (in_attr || in_quote) {
     710             :                 /* invalid dn */
     711       18539 :                 ldb_dn_mark_invalid(dn);
     712       18539 :                 goto failed;
     713             :         }
     714             : 
     715   258959794 :         if (in_value) {
     716             :                 /* save last element */
     717   258959790 :                 if (t != NULL) {
     718             :                         /* trim back */
     719         190 :                         d -= (p - t);
     720         190 :                         l -= (p - t);
     721             :                 }
     722             : 
     723   258959790 :                 *d++ = '\0';
     724             :                 /*
     725             :                  * This talloc_memdup() is OK with the
     726             :                  * +1 because *d has been set to '\0'
     727             :                  * just above.
     728             :                  */
     729   258959790 :                 dn->components[dn->comp_num].value.length = l;
     730   517919580 :                 dn->components[dn->comp_num].value.data =
     731   258959790 :                         (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
     732   258959790 :                 if (dn->components[dn->comp_num].value.data == NULL) {
     733             :                         /* ouch */
     734           0 :                         goto failed;
     735             :                 }
     736   258959790 :                 talloc_set_name_const(dn->components[dn->comp_num].value.data,
     737   254147698 :                         (const char *)dn->components[dn->comp_num].value.data);
     738             : 
     739   258959790 :                 dn->comp_num++;
     740             :         }
     741   258959794 :         talloc_free(data);
     742   258959794 :         return true;
     743             : 
     744       20207 : failed:
     745       20207 :         LDB_FREE(dn->components); /* "data" is implicitly free'd */
     746       20207 :         dn->comp_num = 0;
     747       20207 :         LDB_FREE(dn->ext_components);
     748       20207 :         dn->ext_comp_num = 0;
     749             : 
     750       20207 :         return false;
     751             : }
     752             : 
     753  1128150298 : bool ldb_dn_validate(struct ldb_dn *dn)
     754             : {
     755  1128150298 :         return ldb_dn_explode(dn);
     756             : }
     757             : 
     758   760060689 : const char *ldb_dn_get_linearized(struct ldb_dn *dn)
     759             : {
     760    24986840 :         unsigned int i;
     761    24986840 :         size_t len;
     762    24986840 :         char *d, *n;
     763             : 
     764   760060689 :         if ( ! dn || ( dn->invalid)) return NULL;
     765             : 
     766   760060324 :         if (dn->linearized) return dn->linearized;
     767             : 
     768    10690797 :         if ( ! dn->components) {
     769           0 :                 ldb_dn_mark_invalid(dn);
     770           0 :                 return NULL;
     771             :         }
     772             : 
     773    10690797 :         if (dn->comp_num == 0) {
     774      539110 :                 dn->linearized = talloc_strdup(dn, "");
     775      539110 :                 if ( ! dn->linearized) return NULL;
     776      539110 :                 return dn->linearized;
     777             :         }
     778             : 
     779             :         /* calculate maximum possible length of DN */
     780    66323386 :         for (len = 0, i = 0; i < dn->comp_num; i++) {
     781             :                 /* name len */
     782    56171699 :                 len += strlen(dn->components[i].name);
     783             :                 /* max escaped data len */
     784    56171699 :                 len += (dn->components[i].value.length * 3);
     785    56171699 :                 len += 2; /* '=' and ',' */
     786             :         }
     787    10151687 :         dn->linearized = talloc_array(dn, char, len);
     788    10151687 :         if ( ! dn->linearized) return NULL;
     789             : 
     790     9525834 :         d = dn->linearized;
     791             : 
     792    66323386 :         for (i = 0; i < dn->comp_num; i++) {
     793             : 
     794             :                 /* copy the name */
     795    56171699 :                 n = dn->components[i].name;
     796   168515676 :                 while (*n) *d++ = *n++;
     797             : 
     798    56171699 :                 *d++ = '=';
     799             : 
     800             :                 /* and the value */
     801   112343398 :                 d += ldb_dn_escape_internal( d,
     802    56171699 :                                 (char *)dn->components[i].value.data,
     803    56171699 :                                 dn->components[i].value.length);
     804    56171699 :                 *d++ = ',';
     805             :         }
     806             : 
     807    10151687 :         *(--d) = '\0';
     808             : 
     809             :         /* don't waste more memory than necessary */
     810    10151687 :         dn->linearized = talloc_realloc(dn, dn->linearized,
     811             :                                         char, (d - dn->linearized + 1));
     812             : 
     813    10151687 :         return dn->linearized;
     814             : }
     815             : 
     816    49365983 : static int ldb_dn_extended_component_compare(const void *p1, const void *p2)
     817             : {
     818    49365983 :         const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1;
     819    49365983 :         const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2;
     820    49365983 :         return strcmp(ec1->name, ec2->name);
     821             : }
     822             : 
     823    27679602 : char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode)
     824             : {
     825    27679602 :         const char *linearized = ldb_dn_get_linearized(dn);
     826    27679602 :         char *p = NULL;
     827      619614 :         unsigned int i;
     828             : 
     829    27679602 :         if (!linearized) {
     830          96 :                 return NULL;
     831             :         }
     832             : 
     833    27679506 :         if (!ldb_dn_has_extended(dn)) {
     834     1539289 :                 return talloc_strdup(mem_ctx, linearized);
     835             :         }
     836             : 
     837    26140217 :         if (!ldb_dn_validate(dn)) {
     838           3 :                 return NULL;
     839             :         }
     840             : 
     841             :         /* sort the extended components by name. The idea is to make
     842             :          * the resulting DNs consistent, plus to ensure that we put
     843             :          * 'DELETED' first, so it can be very quickly recognised
     844             :          */
     845    26140214 :         TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num,
     846             :                        ldb_dn_extended_component_compare);
     847             : 
     848    77181035 :         for (i = 0; i < dn->ext_comp_num; i++) {
     849      626413 :                 const struct ldb_dn_extended_syntax *ext_syntax;
     850    51040821 :                 const char *name = dn->ext_components[i].name;
     851    51040821 :                 struct ldb_val ec_val = dn->ext_components[i].value;
     852      626413 :                 struct ldb_val val;
     853      626413 :                 int ret;
     854             : 
     855    51040821 :                 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
     856    51040821 :                 if (!ext_syntax) {
     857           0 :                         return NULL;
     858             :                 }
     859             : 
     860    51040821 :                 if (mode == 1) {
     861    40837367 :                         ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
     862             :                                                         &ec_val, &val);
     863    10203454 :                 } else if (mode == 0) {
     864    10203454 :                         ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
     865             :                                                         &ec_val, &val);
     866             :                 } else {
     867           0 :                         ret = -1;
     868             :                 }
     869             : 
     870    51040821 :                 if (ret != LDB_SUCCESS) {
     871           0 :                         return NULL;
     872             :                 }
     873             : 
     874    51040821 :                 if (i == 0) {
     875    26140210 :                         p = talloc_asprintf(mem_ctx, "<%s=%.*s>",
     876             :                                             name,
     877    26140210 :                                             (int)val.length,
     878             :                                             val.data);
     879             :                 } else {
     880    24900611 :                         talloc_asprintf_addbuf(&p, ";<%s=%.*s>",
     881             :                                                name,
     882    24900611 :                                                (int)val.length,
     883             :                                                val.data);
     884             :                 }
     885             : 
     886    51040821 :                 talloc_free(val.data);
     887             :         }
     888             : 
     889    26140214 :         if (dn->ext_comp_num && *linearized) {
     890    24901588 :                 talloc_asprintf_addbuf(&p, ";%s", linearized);
     891             :         }
     892             : 
     893    26140214 :         if (!p) {
     894           4 :                 return NULL;
     895             :         }
     896             : 
     897    25629507 :         return p;
     898             : }
     899             : 
     900             : /*
     901             :   filter out all but an acceptable list of extended DN components
     902             :  */
     903    16520348 : void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list)
     904             : {
     905      202699 :         unsigned int i;
     906    58040569 :         for (i=0; i<dn->ext_comp_num; i++) {
     907    41520221 :                 if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) {
     908    19020215 :                         ARRAY_DEL_ELEMENT(
     909        3052 :                                 dn->ext_components, i, dn->ext_comp_num);
     910    19020215 :                         dn->ext_comp_num--;
     911    19020215 :                         i--;
     912             :                 }
     913             :         }
     914    16520348 :         LDB_FREE(dn->ext_linearized);
     915    16520348 : }
     916             : 
     917             : 
     918   171634128 : char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
     919             : {
     920   171634128 :         return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
     921             : }
     922             : 
     923             : /*
     924             :   casefold a dn. We need to casefold the attribute names, and canonicalize
     925             :   attribute values of case insensitive attributes.
     926             : */
     927             : 
     928   278021909 : static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
     929             : {
     930     4271111 :         unsigned int i;
     931     4271111 :         int ret;
     932             : 
     933   278021909 :         if ( ! dn || dn->invalid) return false;
     934             : 
     935   278021909 :         if (dn->valid_case) return true;
     936             : 
     937   139238187 :         if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
     938         892 :                 return false;
     939             :         }
     940             : 
     941   881459024 :         for (i = 0; i < dn->comp_num; i++) {
     942    12223318 :                 const struct ldb_schema_attribute *a;
     943             : 
     944  1484443458 :                 dn->components[i].cf_name =
     945   742221729 :                         ldb_attr_casefold(dn->components,
     946   742221729 :                                           dn->components[i].name);
     947   742221729 :                 if (!dn->components[i].cf_name) {
     948           0 :                         goto failed;
     949             :                 }
     950             : 
     951   742221729 :                 a = ldb_schema_attribute_by_name(dn->ldb,
     952   729998411 :                                                  dn->components[i].cf_name);
     953             : 
     954   754445047 :                 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
     955   742221729 :                                                  &(dn->components[i].value),
     956   742221729 :                                                  &(dn->components[i].cf_value));
     957   742221729 :                 if (ret != 0) {
     958           0 :                         goto failed;
     959             :                 }
     960             :         }
     961             : 
     962   139237295 :         dn->valid_case = true;
     963             : 
     964   139237295 :         return true;
     965             : 
     966           0 : failed:
     967           0 :         for (i = 0; i < dn->comp_num; i++) {
     968           0 :                 LDB_FREE(dn->components[i].cf_name);
     969           0 :                 LDB_FREE(dn->components[i].cf_value.data);
     970             :         }
     971           0 :         return false;
     972             : }
     973             : 
     974   499459983 : const char *ldb_dn_get_casefold(struct ldb_dn *dn)
     975             : {
     976    15898788 :         unsigned int i;
     977    15898788 :         size_t len;
     978    15898788 :         char *d, *n;
     979             : 
     980   499459983 :         if (dn->casefold) return dn->casefold;
     981             : 
     982   312836725 :         if (dn->special) {
     983   280376172 :                 dn->casefold = talloc_strdup(dn, dn->linearized);
     984   280376172 :                 if (!dn->casefold) return NULL;
     985   280376172 :                 dn->valid_case = true;
     986   280376172 :                 return dn->casefold;
     987             :         }
     988             : 
     989    32460553 :         if ( ! ldb_dn_casefold_internal(dn)) {
     990           0 :                 return NULL;
     991             :         }
     992             : 
     993    32460553 :         if (dn->comp_num == 0) {
     994        1506 :                 dn->casefold = talloc_strdup(dn, "");
     995        1506 :                 return dn->casefold;
     996             :         }
     997             : 
     998             :         /* calculate maximum possible length of DN */
     999   193693955 :         for (len = 0, i = 0; i < dn->comp_num; i++) {
    1000             :                 /* name len */
    1001   161234908 :                 len += strlen(dn->components[i].cf_name);
    1002             :                 /* max escaped data len */
    1003   161234908 :                 len += (dn->components[i].cf_value.length * 3);
    1004   161234908 :                 len += 2; /* '=' and ',' */
    1005             :         }
    1006    32459047 :         dn->casefold = talloc_array(dn, char, len);
    1007    32459047 :         if ( ! dn->casefold) return NULL;
    1008             : 
    1009    30487276 :         d = dn->casefold;
    1010             : 
    1011   193693955 :         for (i = 0; i < dn->comp_num; i++) {
    1012             : 
    1013             :                 /* copy the name */
    1014   161234908 :                 n = dn->components[i].cf_name;
    1015   485228321 :                 while (*n) *d++ = *n++;
    1016             : 
    1017   161234908 :                 *d++ = '=';
    1018             : 
    1019             :                 /* and the value */
    1020   322469816 :                 d += ldb_dn_escape_internal( d,
    1021   161234908 :                                 (char *)dn->components[i].cf_value.data,
    1022   161234908 :                                 dn->components[i].cf_value.length);
    1023   161234908 :                 *d++ = ',';
    1024             :         }
    1025    32459047 :         *(--d) = '\0';
    1026             : 
    1027             :         /* don't waste more memory than necessary */
    1028    32459047 :         dn->casefold = talloc_realloc(dn, dn->casefold,
    1029             :                                       char, strlen(dn->casefold) + 1);
    1030             : 
    1031    32459047 :         return dn->casefold;
    1032             : }
    1033             : 
    1034     2465955 : char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1035             : {
    1036     2465955 :         return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
    1037             : }
    1038             : 
    1039             : /* Determine if dn is below base, in the ldap tree.  Used for
    1040             :  * evaluating a subtree search.
    1041             :  * 0 if they match, otherwise non-zero
    1042             :  */
    1043             : 
    1044   571835147 : int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
    1045             : {
    1046    12227128 :         int ret;
    1047    12227128 :         unsigned int n_base, n_dn;
    1048             : 
    1049   571835147 :         if ( ! base || base->invalid) return 1;
    1050   571835147 :         if ( ! dn || dn->invalid) return -1;
    1051             : 
    1052   571835147 :         if (( ! base->valid_case) || ( ! dn->valid_case)) {
    1053   394089011 :                 if (base->linearized && dn->linearized && dn->special == base->special) {
    1054             :                         /* try with a normal compare first, if we are lucky
    1055             :                          * we will avoid exploding and casefolding */
    1056     6448340 :                         int dif;
    1057   386534805 :                         dif = strlen(dn->linearized) - strlen(base->linearized);
    1058   386534805 :                         if (dif < 0) {
    1059   125643944 :                                 return dif;
    1060             :                         }
    1061   258526972 :                         if (strcmp(base->linearized,
    1062   258526972 :                                    &dn->linearized[dif]) == 0) {
    1063   148685815 :                                 return 0;
    1064             :                         }
    1065             :                 }
    1066             : 
    1067   113695199 :                 if ( ! ldb_dn_casefold_internal(base)) {
    1068           0 :                         return 1;
    1069             :                 }
    1070             : 
    1071   113695199 :                 if ( ! ldb_dn_casefold_internal(dn)) {
    1072           0 :                         return -1;
    1073             :                 }
    1074             : 
    1075             :         }
    1076             : 
    1077             :         /* if base has more components,
    1078             :          * they don't have the same base */
    1079   291441335 :         if (base->comp_num > dn->comp_num) {
    1080    54810605 :                 return (dn->comp_num - base->comp_num);
    1081             :         }
    1082             : 
    1083   236630730 :         if ((dn->comp_num == 0) || (base->comp_num == 0)) {
    1084           1 :                 if (dn->special && base->special) {
    1085           0 :                         return strcmp(base->linearized, dn->linearized);
    1086           1 :                 } else if (dn->special) {
    1087           0 :                         return -1;
    1088           1 :                 } else if (base->special) {
    1089           0 :                         return 1;
    1090             :                 } else {
    1091           0 :                         return 0;
    1092             :                 }
    1093             :         }
    1094             : 
    1095   236630729 :         n_base = base->comp_num - 1;
    1096   236630729 :         n_dn = dn->comp_num - 1;
    1097             : 
    1098  1111949372 :         while (n_base != (unsigned int) -1) {
    1099  1016210749 :                 char *b_name = base->components[n_base].cf_name;
    1100  1016210749 :                 char *dn_name = dn->components[n_dn].cf_name;
    1101             : 
    1102  1016210749 :                 char *b_vdata = (char *)base->components[n_base].cf_value.data;
    1103  1016210749 :                 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
    1104             : 
    1105  1016210749 :                 size_t b_vlen = base->components[n_base].cf_value.length;
    1106  1016210749 :                 size_t dn_vlen = dn->components[n_dn].cf_value.length;
    1107             : 
    1108             :                 /* compare attr names */
    1109  1016210749 :                 ret = strcmp(b_name, dn_name);
    1110  1016210749 :                 if (ret != 0) return ret;
    1111             : 
    1112             :                 /* compare attr.cf_value. */
    1113   924371550 :                 if (b_vlen != dn_vlen) {
    1114    47332497 :                         return b_vlen - dn_vlen;
    1115             :                 }
    1116   877039053 :                 ret = strncmp(b_vdata, dn_vdata, b_vlen);
    1117   877039053 :                 if (ret != 0) return ret;
    1118             : 
    1119   875318643 :                 n_base--;
    1120   875318643 :                 n_dn--;
    1121             :         }
    1122             : 
    1123    92220013 :         return 0;
    1124             : }
    1125             : 
    1126             : /* compare DNs using casefolding compare functions.
    1127             : 
    1128             :    If they match, then return 0
    1129             :  */
    1130             : 
    1131    68679370 : int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
    1132             : {
    1133     4461837 :         unsigned int i;
    1134     4461837 :         int ret;
    1135             : 
    1136    68679370 :         if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
    1137           2 :                 return -1;
    1138             :         }
    1139             : 
    1140    68679368 :         if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
    1141    10542913 :                 if (dn0->linearized && dn1->linearized) {
    1142             :                         /* try with a normal compare first, if we are lucky
    1143             :                          * we will avoid exploding and casefolding */
    1144     8430834 :                         if (strcmp(dn0->linearized, dn1->linearized) == 0) {
    1145     1443554 :                                 return 0;
    1146             :                         }
    1147             :                 }
    1148             : 
    1149     9085479 :                 if ( ! ldb_dn_casefold_internal(dn0)) {
    1150           0 :                         return 1;
    1151             :                 }
    1152             : 
    1153     9085479 :                 if ( ! ldb_dn_casefold_internal(dn1)) {
    1154         892 :                         return -1;
    1155             :                 }
    1156             : 
    1157             :         }
    1158             : 
    1159    67221042 :         if (dn0->comp_num != dn1->comp_num) {
    1160    41544887 :                 return (dn1->comp_num - dn0->comp_num);
    1161             :         }
    1162             : 
    1163    25676155 :         if (dn0->comp_num == 0) {
    1164     1102372 :                 if (dn0->special && dn1->special) {
    1165     1102372 :                         return strcmp(dn0->linearized, dn1->linearized);
    1166           0 :                 } else if (dn0->special) {
    1167           0 :                         return 1;
    1168           0 :                 } else if (dn1->special) {
    1169           0 :                         return -1;
    1170             :                 } else {
    1171           0 :                         return 0;
    1172             :                 }
    1173             :         }
    1174             : 
    1175    72081396 :         for (i = 0; i < dn0->comp_num; i++) {
    1176    61811012 :                 char *dn0_name = dn0->components[i].cf_name;
    1177    61811012 :                 char *dn1_name = dn1->components[i].cf_name;
    1178             : 
    1179    61811012 :                 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
    1180    61811012 :                 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
    1181             : 
    1182    61811012 :                 size_t dn0_vlen = dn0->components[i].cf_value.length;
    1183    61811012 :                 size_t dn1_vlen = dn1->components[i].cf_value.length;
    1184             : 
    1185             :                 /* compare attr names */
    1186    61811012 :                 ret = strcmp(dn0_name, dn1_name);
    1187    61811012 :                 if (ret != 0) {
    1188     3434907 :                         return ret;
    1189             :                 }
    1190             : 
    1191             :                 /* compare attr.cf_value. */
    1192    58376105 :                 if (dn0_vlen != dn1_vlen) {
    1193     6093458 :                         return dn0_vlen - dn1_vlen;
    1194             :                 }
    1195    52282647 :                 ret = strncmp(dn0_vdata, dn1_vdata, dn0_vlen);
    1196    52282647 :                 if (ret != 0) {
    1197     4775034 :                         return ret;
    1198             :                 }
    1199             :         }
    1200             : 
    1201     9737302 :         return 0;
    1202             : }
    1203             : 
    1204   412139271 : static struct ldb_dn_component ldb_dn_copy_component(
    1205             :                                                 TALLOC_CTX *mem_ctx,
    1206             :                                                 struct ldb_dn_component *src)
    1207             : {
    1208    20813391 :         struct ldb_dn_component dst;
    1209             : 
    1210   412139271 :         memset(&dst, 0, sizeof(dst));
    1211             : 
    1212   412139271 :         if (src == NULL) {
    1213           0 :                 return dst;
    1214             :         }
    1215             : 
    1216   412139271 :         dst.value = ldb_val_dup(mem_ctx, &(src->value));
    1217   412139271 :         if (dst.value.data == NULL) {
    1218           0 :                 return dst;
    1219             :         }
    1220             : 
    1221   412139271 :         dst.name = talloc_strdup(mem_ctx, src->name);
    1222   412139271 :         if (dst.name == NULL) {
    1223           0 :                 LDB_FREE(dst.value.data);
    1224           0 :                 return dst;
    1225             :         }
    1226             : 
    1227   412139271 :         if (src->cf_value.data) {
    1228   342080677 :                 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
    1229   342080677 :                 if (dst.cf_value.data == NULL) {
    1230           0 :                         LDB_FREE(dst.value.data);
    1231           0 :                         LDB_FREE(dst.name);
    1232           0 :                         return dst;
    1233             :                 }
    1234             : 
    1235   342080677 :                 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
    1236   342080677 :                 if (dst.cf_name == NULL) {
    1237           0 :                         LDB_FREE(dst.cf_name);
    1238           0 :                         LDB_FREE(dst.value.data);
    1239           0 :                         LDB_FREE(dst.name);
    1240           0 :                         return dst;
    1241             :                 }
    1242             :         } else {
    1243    66988967 :                 dst.cf_value.data = NULL;
    1244    66988967 :                 dst.cf_name = NULL;
    1245             :         }
    1246             : 
    1247   412139271 :         return dst;
    1248             : }
    1249             : 
    1250    32073211 : static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
    1251             :                                                 TALLOC_CTX *mem_ctx,
    1252             :                                                 struct ldb_dn_ext_component *src)
    1253             : {
    1254      932011 :         struct ldb_dn_ext_component dst;
    1255             : 
    1256    32073211 :         memset(&dst, 0, sizeof(dst));
    1257             : 
    1258    32073211 :         if (src == NULL) {
    1259           0 :                 return dst;
    1260             :         }
    1261             : 
    1262    32073211 :         dst.value = ldb_val_dup(mem_ctx, &(src->value));
    1263    32073211 :         if (dst.value.data == NULL) {
    1264           0 :                 return dst;
    1265             :         }
    1266             : 
    1267    32073211 :         dst.name = talloc_strdup(mem_ctx, src->name);
    1268    32073211 :         if (dst.name == NULL) {
    1269           0 :                 LDB_FREE(dst.value.data);
    1270           0 :                 return dst;
    1271             :         }
    1272             : 
    1273    32073211 :         return dst;
    1274             : }
    1275             : 
    1276    78772541 : struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1277             : {
    1278     3798803 :         struct ldb_dn *new_dn;
    1279             : 
    1280    78772541 :         if (!dn || dn->invalid) {
    1281           2 :                 return NULL;
    1282             :         }
    1283             : 
    1284    78772539 :         new_dn = talloc_zero(mem_ctx, struct ldb_dn);
    1285    78772539 :         if ( !new_dn) {
    1286           0 :                 return NULL;
    1287             :         }
    1288             : 
    1289    78772539 :         *new_dn = *dn;
    1290             : 
    1291    78772539 :         if (dn->components) {
    1292     3576581 :                 unsigned int i;
    1293             : 
    1294    73649084 :                 new_dn->components =
    1295    70072503 :                         talloc_zero_array(new_dn,
    1296             :                                           struct ldb_dn_component,
    1297             :                                           dn->comp_num);
    1298    70072503 :                 if ( ! new_dn->components) {
    1299           0 :                         talloc_free(new_dn);
    1300           0 :                         return NULL;
    1301             :                 }
    1302             : 
    1303   466537628 :                 for (i = 0; i < dn->comp_num; i++) {
    1304   396465125 :                         new_dn->components[i] =
    1305   396465125 :                                 ldb_dn_copy_component(new_dn->components,
    1306   396465125 :                                                       &dn->components[i]);
    1307   396465125 :                         if ( ! new_dn->components[i].value.data) {
    1308           0 :                                 talloc_free(new_dn);
    1309           0 :                                 return NULL;
    1310             :                         }
    1311             :                 }
    1312             :         }
    1313             : 
    1314    78772539 :         if (dn->ext_components) {
    1315      801400 :                 unsigned int i;
    1316             : 
    1317    25897167 :                 new_dn->ext_components =
    1318    25095767 :                         talloc_zero_array(new_dn,
    1319             :                                           struct ldb_dn_ext_component,
    1320             :                                           dn->ext_comp_num);
    1321    25095767 :                 if ( ! new_dn->ext_components) {
    1322           0 :                         talloc_free(new_dn);
    1323           0 :                         return NULL;
    1324             :                 }
    1325             : 
    1326    57168978 :                 for (i = 0; i < dn->ext_comp_num; i++) {
    1327    32073211 :                         new_dn->ext_components[i] =
    1328    32073211 :                                  ldb_dn_ext_copy_component(
    1329    32073211 :                                                 new_dn->ext_components,
    1330    32073211 :                                                 &dn->ext_components[i]);
    1331    32073211 :                         if ( ! new_dn->ext_components[i].value.data) {
    1332           0 :                                 talloc_free(new_dn);
    1333           0 :                                 return NULL;
    1334             :                         }
    1335             :                 }
    1336             :         }
    1337             : 
    1338    78772539 :         if (dn->casefold) {
    1339    44744950 :                 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
    1340    44744950 :                 if ( ! new_dn->casefold) {
    1341           0 :                         talloc_free(new_dn);
    1342           0 :                         return NULL;
    1343             :                 }
    1344             :         }
    1345             : 
    1346    78772539 :         if (dn->linearized) {
    1347    78628231 :                 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
    1348    78628231 :                 if ( ! new_dn->linearized) {
    1349           0 :                         talloc_free(new_dn);
    1350           0 :                         return NULL;
    1351             :                 }
    1352             :         }
    1353             : 
    1354    78772539 :         if (dn->ext_linearized) {
    1355     2809382 :                 new_dn->ext_linearized = talloc_strdup(new_dn,
    1356     1356298 :                                                         dn->ext_linearized);
    1357     1453084 :                 if ( ! new_dn->ext_linearized) {
    1358           0 :                         talloc_free(new_dn);
    1359           0 :                         return NULL;
    1360             :                 }
    1361             :         }
    1362             : 
    1363    74973736 :         return new_dn;
    1364             : }
    1365             : 
    1366             : /* modify the given dn by adding a base.
    1367             :  *
    1368             :  * return true if successful and false if not
    1369             :  * if false is returned the dn may be marked invalid
    1370             :  */
    1371      626633 : bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
    1372             : {
    1373        4928 :         const char *s;
    1374        4928 :         char *t;
    1375             : 
    1376      626633 :         if ( !base || base->invalid || !dn || dn->invalid) {
    1377           0 :                 return false;
    1378             :         }
    1379             : 
    1380      626633 :         if (dn == base) {
    1381           0 :                 return false; /* or we will visit infinity */
    1382             :         }
    1383             : 
    1384      626633 :         if (dn->components) {
    1385         479 :                 unsigned int i;
    1386             : 
    1387      452813 :                 if ( ! ldb_dn_validate(base)) {
    1388           0 :                         return false;
    1389             :                 }
    1390             : 
    1391      452813 :                 s = NULL;
    1392      452813 :                 if (dn->valid_case) {
    1393           2 :                         if ( ! (s = ldb_dn_get_casefold(base))) {
    1394           0 :                                 return false;
    1395             :                         }
    1396             :                 }
    1397             : 
    1398      452813 :                 dn->components = talloc_realloc(dn,
    1399             :                                                 dn->components,
    1400             :                                                 struct ldb_dn_component,
    1401             :                                                 dn->comp_num + base->comp_num);
    1402      452813 :                 if ( ! dn->components) {
    1403           0 :                         ldb_dn_mark_invalid(dn);
    1404           0 :                         return false;
    1405             :                 }
    1406             : 
    1407     2984908 :                 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
    1408     2532095 :                         dn->components[dn->comp_num] =
    1409     2532095 :                                 ldb_dn_copy_component(dn->components,
    1410     2532095 :                                                         &base->components[i]);
    1411     2532095 :                         if (dn->components[dn->comp_num].value.data == NULL) {
    1412           0 :                                 ldb_dn_mark_invalid(dn);
    1413           0 :                                 return false;
    1414             :                         }
    1415             :                 }
    1416             : 
    1417      452813 :                 if (dn->casefold && s) {
    1418           0 :                         if (*dn->casefold) {
    1419           0 :                                 t = talloc_asprintf(dn, "%s,%s",
    1420             :                                                     dn->casefold, s);
    1421             :                         } else {
    1422           0 :                                 t = talloc_strdup(dn, s);
    1423             :                         }
    1424           0 :                         LDB_FREE(dn->casefold);
    1425           0 :                         dn->casefold = t;
    1426             :                 }
    1427             :         }
    1428             : 
    1429      626633 :         if (dn->linearized) {
    1430             : 
    1431      176466 :                 s = ldb_dn_get_linearized(base);
    1432      176466 :                 if ( ! s) {
    1433           0 :                         return false;
    1434             :                 }
    1435             : 
    1436      176466 :                 if (*dn->linearized) {
    1437       14415 :                         t = talloc_asprintf(dn, "%s,%s",
    1438             :                                             dn->linearized, s);
    1439             :                 } else {
    1440      162051 :                         t = talloc_strdup(dn, s);
    1441             :                 }
    1442      176466 :                 if ( ! t) {
    1443           0 :                         ldb_dn_mark_invalid(dn);
    1444           0 :                         return false;
    1445             :                 }
    1446      176466 :                 LDB_FREE(dn->linearized);
    1447      176466 :                 dn->linearized = t;
    1448             :         }
    1449             : 
    1450             :         /* Wipe the ext_linearized DN,
    1451             :          * the GUID and SID are almost certainly no longer valid */
    1452      626633 :         LDB_FREE(dn->ext_linearized);
    1453      626633 :         LDB_FREE(dn->ext_components);
    1454      626633 :         dn->ext_comp_num = 0;
    1455             : 
    1456      626633 :         return true;
    1457             : }
    1458             : 
    1459             : /* modify the given dn by adding a base.
    1460             :  *
    1461             :  * return true if successful and false if not
    1462             :  * if false is returned the dn may be marked invalid
    1463             :  */
    1464           2 : bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
    1465             : {
    1466           2 :         struct ldb_dn *base;
    1467           2 :         char *base_str;
    1468           2 :         va_list ap;
    1469           2 :         bool ret;
    1470             : 
    1471           2 :         if ( !dn || dn->invalid) {
    1472           0 :                 return false;
    1473             :         }
    1474             : 
    1475           2 :         va_start(ap, base_fmt);
    1476           2 :         base_str = talloc_vasprintf(dn, base_fmt, ap);
    1477           2 :         va_end(ap);
    1478             : 
    1479           2 :         if (base_str == NULL) {
    1480           0 :                 return false;
    1481             :         }
    1482             : 
    1483           2 :         base = ldb_dn_new(base_str, dn->ldb, base_str);
    1484             : 
    1485           2 :         ret = ldb_dn_add_base(dn, base);
    1486             : 
    1487           2 :         talloc_free(base_str);
    1488             : 
    1489           2 :         return ret;
    1490             : }
    1491             : 
    1492             : /* modify the given dn by adding children elements.
    1493             :  *
    1494             :  * return true if successful and false if not
    1495             :  * if false is returned the dn may be marked invalid
    1496             :  */
    1497     6786024 : bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
    1498             : {
    1499      368712 :         const char *s;
    1500      368712 :         char *t;
    1501             : 
    1502     6786024 :         if ( !child || child->invalid || !dn || dn->invalid) {
    1503           0 :                 return false;
    1504             :         }
    1505             : 
    1506     6786024 :         if (dn->components) {
    1507      365025 :                 unsigned int n;
    1508      365025 :                 unsigned int i, j;
    1509             : 
    1510     6545651 :                 if (dn->comp_num == 0) {
    1511           0 :                         return false;
    1512             :                 }
    1513             : 
    1514     6545651 :                 if ( ! ldb_dn_validate(child)) {
    1515           0 :                         return false;
    1516             :                 }
    1517             : 
    1518     6545651 :                 s = NULL;
    1519     6545651 :                 if (dn->valid_case) {
    1520     4644432 :                         if ( ! (s = ldb_dn_get_casefold(child))) {
    1521           0 :                                 return false;
    1522             :                         }
    1523             :                 }
    1524             : 
    1525     6545651 :                 n = dn->comp_num + child->comp_num;
    1526             : 
    1527     6545651 :                 dn->components = talloc_realloc(dn,
    1528             :                                                 dn->components,
    1529             :                                                 struct ldb_dn_component,
    1530             :                                                 n);
    1531     6545651 :                 if ( ! dn->components) {
    1532           0 :                         ldb_dn_mark_invalid(dn);
    1533           0 :                         return false;
    1534             :                 }
    1535             : 
    1536    35334029 :                 for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1;
    1537    28788378 :                      i--, j--) {
    1538    28788378 :                         dn->components[j] = dn->components[i];
    1539             :                 }
    1540             : 
    1541    19156687 :                 for (i = 0; i < child->comp_num; i++) {
    1542    12611036 :                         dn->components[i] =
    1543    12611036 :                                 ldb_dn_copy_component(dn->components,
    1544    12611036 :                                                         &child->components[i]);
    1545    12611036 :                         if (dn->components[i].value.data == NULL) {
    1546           0 :                                 ldb_dn_mark_invalid(dn);
    1547           0 :                                 return false;
    1548             :                         }
    1549             :                 }
    1550             : 
    1551     6545651 :                 dn->comp_num = n;
    1552             : 
    1553     6545651 :                 if (dn->casefold && s) {
    1554     3382424 :                         t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
    1555     3382424 :                         LDB_FREE(dn->casefold);
    1556     3382424 :                         dn->casefold = t;
    1557             :                 }
    1558             :         }
    1559             : 
    1560     6786024 :         if (dn->linearized) {
    1561     6778938 :                 if (dn->linearized[0] == '\0') {
    1562           0 :                         return false;
    1563             :                 }
    1564             : 
    1565     6778937 :                 s = ldb_dn_get_linearized(child);
    1566     6778937 :                 if ( ! s) {
    1567           0 :                         return false;
    1568             :                 }
    1569             : 
    1570     6778937 :                 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
    1571     6778937 :                 if ( ! t) {
    1572           0 :                         ldb_dn_mark_invalid(dn);
    1573           0 :                         return false;
    1574             :                 }
    1575     6778937 :                 LDB_FREE(dn->linearized);
    1576     6778937 :                 dn->linearized = t;
    1577             :         }
    1578             : 
    1579             :         /* Wipe the ext_linearized DN,
    1580             :          * the GUID and SID are almost certainly no longer valid */
    1581     6786023 :         LDB_FREE(dn->ext_linearized);
    1582     6786023 :         LDB_FREE(dn->ext_components);
    1583     6786023 :         dn->ext_comp_num = 0;
    1584             : 
    1585     6786023 :         return true;
    1586             : }
    1587             : 
    1588             : /* modify the given dn by adding children elements.
    1589             :  *
    1590             :  * return true if successful and false if not
    1591             :  * if false is returned the dn may be marked invalid
    1592             :  */
    1593     6591199 : bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
    1594             : {
    1595      367432 :         struct ldb_dn *child;
    1596      367432 :         char *child_str;
    1597      367432 :         va_list ap;
    1598      367432 :         bool ret;
    1599             : 
    1600     6591199 :         if ( !dn || dn->invalid) {
    1601           0 :                 return false;
    1602             :         }
    1603             : 
    1604     6591199 :         va_start(ap, child_fmt);
    1605     6591199 :         child_str = talloc_vasprintf(dn, child_fmt, ap);
    1606     6591199 :         va_end(ap);
    1607             : 
    1608     6591199 :         if (child_str == NULL) {
    1609           0 :                 return false;
    1610             :         }
    1611             : 
    1612     6591199 :         child = ldb_dn_new(child_str, dn->ldb, child_str);
    1613             : 
    1614     6591199 :         ret = ldb_dn_add_child(dn, child);
    1615             : 
    1616     6591199 :         talloc_free(child_str);
    1617             : 
    1618     6591199 :         return ret;
    1619             : }
    1620             : 
    1621             : /* modify the given dn by adding a single child element.
    1622             :  *
    1623             :  * return true if successful and false if not
    1624             :  * if false is returned the dn may be marked invalid
    1625             :  */
    1626       25097 : bool ldb_dn_add_child_val(struct ldb_dn *dn,
    1627             :                           const char *rdn,
    1628             :                           struct ldb_val value)
    1629             : {
    1630           8 :         bool ret;
    1631           8 :         int ldb_ret;
    1632       25097 :         struct ldb_dn *child = NULL;
    1633             : 
    1634       25097 :         if ( !dn || dn->invalid) {
    1635           0 :                 return false;
    1636             :         }
    1637             : 
    1638       25097 :         child = ldb_dn_new(dn, dn->ldb, "X=Y");
    1639       25097 :         ret = ldb_dn_add_child(dn, child);
    1640             : 
    1641       25097 :         if (ret == false) {
    1642           0 :                 return false;
    1643             :         }
    1644             : 
    1645       25097 :         ldb_ret = ldb_dn_set_component(dn,
    1646             :                                        0,
    1647             :                                        rdn,
    1648             :                                        value);
    1649       25097 :         if (ldb_ret != LDB_SUCCESS) {
    1650           0 :                 return false;
    1651             :         }
    1652             : 
    1653       25089 :         return true;
    1654             : }
    1655             : 
    1656      596795 : bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
    1657             : {
    1658         454 :         unsigned int i;
    1659             : 
    1660      596795 :         if ( ! ldb_dn_validate(dn)) {
    1661           0 :                 return false;
    1662             :         }
    1663             : 
    1664      596795 :         if (dn->comp_num < num) {
    1665           0 :                 return false;
    1666             :         }
    1667             : 
    1668             :         /* free components */
    1669     3802194 :         for (i = dn->comp_num - num; i < dn->comp_num; i++) {
    1670     3205399 :                 LDB_FREE(dn->components[i].name);
    1671     3205399 :                 LDB_FREE(dn->components[i].value.data);
    1672     3205399 :                 LDB_FREE(dn->components[i].cf_name);
    1673     3205399 :                 LDB_FREE(dn->components[i].cf_value.data);
    1674             :         }
    1675             : 
    1676      596795 :         dn->comp_num -= num;
    1677             : 
    1678      596795 :         if (dn->valid_case) {
    1679      293887 :                 for (i = 0; i < dn->comp_num; i++) {
    1680      146937 :                         LDB_FREE(dn->components[i].cf_name);
    1681      146937 :                         LDB_FREE(dn->components[i].cf_value.data);
    1682             :                 }
    1683      146950 :                 dn->valid_case = false;
    1684             :         }
    1685             : 
    1686      596795 :         LDB_FREE(dn->casefold);
    1687      596795 :         LDB_FREE(dn->linearized);
    1688             : 
    1689             :         /* Wipe the ext_linearized DN,
    1690             :          * the GUID and SID are almost certainly no longer valid */
    1691      596795 :         LDB_FREE(dn->ext_linearized);
    1692      596795 :         LDB_FREE(dn->ext_components);
    1693      596795 :         dn->ext_comp_num = 0;
    1694             : 
    1695      596795 :         return true;
    1696             : }
    1697             : 
    1698    12901975 : bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
    1699             : {
    1700      781054 :         unsigned int i, j;
    1701             : 
    1702    12901975 :         if ( ! ldb_dn_validate(dn)) {
    1703           0 :                 return false;
    1704             :         }
    1705             : 
    1706    12901975 :         if (dn->comp_num < num) {
    1707           1 :                 return false;
    1708             :         }
    1709             : 
    1710    83514708 :         for (i = 0, j = num; j < dn->comp_num; i++, j++) {
    1711    70612734 :                 if (i < num) {
    1712    12900528 :                         LDB_FREE(dn->components[i].name);
    1713    12900528 :                         LDB_FREE(dn->components[i].value.data);
    1714    12900528 :                         LDB_FREE(dn->components[i].cf_name);
    1715    12900528 :                         LDB_FREE(dn->components[i].cf_value.data);
    1716             :                 }
    1717    70612734 :                 dn->components[i] = dn->components[j];
    1718             :         }
    1719             : 
    1720    12901974 :         dn->comp_num -= num;
    1721             : 
    1722    12901974 :         if (dn->valid_case) {
    1723    60784810 :                 for (i = 0; i < dn->comp_num; i++) {
    1724    51407736 :                         LDB_FREE(dn->components[i].cf_name);
    1725    51407736 :                         LDB_FREE(dn->components[i].cf_value.data);
    1726             :                 }
    1727     9377074 :                 dn->valid_case = false;
    1728             :         }
    1729             : 
    1730    12901974 :         LDB_FREE(dn->casefold);
    1731    12901974 :         LDB_FREE(dn->linearized);
    1732             : 
    1733             :         /* Wipe the ext_linearized DN,
    1734             :          * the GUID and SID are almost certainly no longer valid */
    1735    12901974 :         LDB_FREE(dn->ext_linearized);
    1736    12901974 :         LDB_FREE(dn->ext_components);
    1737    12901974 :         dn->ext_comp_num = 0;
    1738             : 
    1739    12901974 :         return true;
    1740             : }
    1741             : 
    1742             : 
    1743             : /* replace the components of a DN with those from another DN, without
    1744             :  * touching the extended components
    1745             :  *
    1746             :  * return true if successful and false if not
    1747             :  * if false is returned the dn may be marked invalid
    1748             :  */
    1749      116861 : bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn)
    1750             : {
    1751         131 :         unsigned int i;
    1752             : 
    1753      116861 :         if ( ! ldb_dn_validate(dn) || ! ldb_dn_validate(new_dn)) {
    1754           0 :                 return false;
    1755             :         }
    1756             : 
    1757             :         /* free components */
    1758      759887 :         for (i = 0; i < dn->comp_num; i++) {
    1759      643026 :                 LDB_FREE(dn->components[i].name);
    1760      643026 :                 LDB_FREE(dn->components[i].value.data);
    1761      643026 :                 LDB_FREE(dn->components[i].cf_name);
    1762      643026 :                 LDB_FREE(dn->components[i].cf_value.data);
    1763             :         }
    1764             : 
    1765      116861 :         dn->components = talloc_realloc(dn,
    1766             :                                         dn->components,
    1767             :                                         struct ldb_dn_component,
    1768             :                                         new_dn->comp_num);
    1769      116861 :         if (dn->components == NULL) {
    1770           0 :                 ldb_dn_mark_invalid(dn);
    1771           0 :                 return false;
    1772             :         }
    1773             : 
    1774      116861 :         dn->comp_num = new_dn->comp_num;
    1775      116861 :         dn->valid_case = new_dn->valid_case;
    1776             : 
    1777      647876 :         for (i = 0; i < dn->comp_num; i++) {
    1778      531015 :                 dn->components[i] = ldb_dn_copy_component(dn->components, &new_dn->components[i]);
    1779      531015 :                 if (dn->components[i].name == NULL) {
    1780           0 :                         ldb_dn_mark_invalid(dn);
    1781           0 :                         return false;
    1782             :                 }
    1783             :         }
    1784      116861 :         if (new_dn->linearized == NULL) {
    1785           0 :                 dn->linearized = NULL;
    1786             :         } else {
    1787      116861 :                 dn->linearized = talloc_strdup(dn, new_dn->linearized);
    1788      116861 :                 if (dn->linearized == NULL) {
    1789           0 :                         ldb_dn_mark_invalid(dn);
    1790           0 :                         return false;
    1791             :                 }
    1792             :         }
    1793             : 
    1794      116730 :         return true;
    1795             : }
    1796             : 
    1797             : 
    1798    12897716 : struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1799             : {
    1800      781024 :         struct ldb_dn *new_dn;
    1801             : 
    1802    12897716 :         new_dn = ldb_dn_copy(mem_ctx, dn);
    1803    12897716 :         if ( !new_dn ) {
    1804           2 :                 return NULL;
    1805             :         }
    1806             : 
    1807    12897714 :         if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
    1808           1 :                 talloc_free(new_dn);
    1809           1 :                 return NULL;
    1810             :         }
    1811             : 
    1812    12116689 :         return new_dn;
    1813             : }
    1814             : 
    1815             : /* Create a 'canonical name' string from a DN:
    1816             : 
    1817             :    ie dc=samba,dc=org -> samba.org/
    1818             :       uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
    1819             : 
    1820             :    There are two formats,
    1821             :    the EX format has the last '/' replaced with a newline (\n).
    1822             : 
    1823             : */
    1824     2649032 : static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) {
    1825      149595 :         unsigned int i;
    1826      149595 :         TALLOC_CTX *tmpctx;
    1827     2649032 :         char *cracked = NULL;
    1828     2649032 :         const char *format = (ex_format ? "\n" : "/" );
    1829             : 
    1830     2649032 :         if ( ! ldb_dn_validate(dn)) {
    1831           0 :                 return NULL;
    1832             :         }
    1833             : 
    1834     2649032 :         tmpctx = talloc_new(mem_ctx);
    1835             : 
    1836             :         /* Walk backwards down the DN, grabbing 'dc' components at first */
    1837    11507537 :         for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) {
    1838    11211174 :                 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
    1839     2211315 :                         break;
    1840             :                 }
    1841     8858505 :                 if (cracked) {
    1842     6209543 :                         cracked = talloc_asprintf(tmpctx, "%s.%s",
    1843             :                                                   ldb_dn_escape_value(tmpctx,
    1844     5884483 :                                                         dn->components[i].value),
    1845             :                                                   cracked);
    1846             :                 } else {
    1847     2648962 :                         cracked = ldb_dn_escape_value(tmpctx,
    1848     2499368 :                                                         dn->components[i].value);
    1849             :                 }
    1850     8858505 :                 if (!cracked) {
    1851           0 :                         goto done;
    1852             :                 }
    1853             :         }
    1854             : 
    1855             :         /* Only domain components?  Finish here */
    1856     2649032 :         if (i == (unsigned int) -1) {
    1857      296363 :                 cracked = talloc_strdup_append_buffer(cracked, format);
    1858      296363 :                 talloc_steal(mem_ctx, cracked);
    1859      296363 :                 goto done;
    1860             :         }
    1861             : 
    1862             :         /* Now walk backwards appending remaining components */
    1863     6492215 :         for (; i > 0; i--) {
    1864     4139546 :                 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
    1865             :                                                         ldb_dn_escape_value(tmpctx,
    1866     4139546 :                                                         dn->components[i].value));
    1867     4139546 :                 if (!cracked) {
    1868           0 :                         goto done;
    1869             :                 }
    1870             :         }
    1871             : 
    1872             :         /* Last one, possibly a newline for the 'ex' format */
    1873     2352669 :         cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
    1874             :                                                 ldb_dn_escape_value(tmpctx,
    1875     2352669 :                                                         dn->components[i].value));
    1876             : 
    1877     2352669 :         talloc_steal(mem_ctx, cracked);
    1878     2649032 : done:
    1879     2649032 :         talloc_free(tmpctx);
    1880     2649032 :         return cracked;
    1881             : }
    1882             : 
    1883             : /* Wrapper functions for the above, for the two different string formats */
    1884     2648768 : char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
    1885     2648768 :         return ldb_dn_canonical(mem_ctx, dn, 0);
    1886             : 
    1887             : }
    1888             : 
    1889         264 : char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
    1890         264 :         return ldb_dn_canonical(mem_ctx, dn, 1);
    1891             : }
    1892             : 
    1893    26107708 : int ldb_dn_get_comp_num(struct ldb_dn *dn)
    1894             : {
    1895    26107708 :         if ( ! ldb_dn_validate(dn)) {
    1896         182 :                 return -1;
    1897             :         }
    1898    26107526 :         return dn->comp_num;
    1899             : }
    1900             : 
    1901    14736469 : int ldb_dn_get_extended_comp_num(struct ldb_dn *dn)
    1902             : {
    1903    14736469 :         if ( ! ldb_dn_validate(dn)) {
    1904         182 :                 return -1;
    1905             :         }
    1906    14736287 :         return dn->ext_comp_num;
    1907             : }
    1908             : 
    1909        9135 : const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
    1910             : {
    1911        9135 :         if ( ! ldb_dn_validate(dn)) {
    1912           0 :                 return NULL;
    1913             :         }
    1914        9135 :         if (num >= dn->comp_num) return NULL;
    1915        9123 :         return dn->components[num].name;
    1916             : }
    1917             : 
    1918      597096 : const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
    1919             :                                                 unsigned int num)
    1920             : {
    1921      597096 :         if ( ! ldb_dn_validate(dn)) {
    1922           0 :                 return NULL;
    1923             :         }
    1924      597096 :         if (num >= dn->comp_num) return NULL;
    1925      597096 :         return &dn->components[num].value;
    1926             : }
    1927             : 
    1928    70320613 : const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
    1929             : {
    1930    70320613 :         if ( ! ldb_dn_validate(dn)) {
    1931           0 :                 return NULL;
    1932             :         }
    1933    70320613 :         if (dn->comp_num == 0) return NULL;
    1934    56439476 :         return dn->components[0].name;
    1935             : }
    1936             : 
    1937    56078424 : const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
    1938             : {
    1939    56078424 :         if ( ! ldb_dn_validate(dn)) {
    1940           2 :                 return NULL;
    1941             :         }
    1942    56078422 :         if (dn->comp_num == 0) return NULL;
    1943    42197285 :         return &dn->components[0].value;
    1944             : }
    1945             : 
    1946     1225358 : int ldb_dn_set_component(struct ldb_dn *dn, int num,
    1947             :                          const char *name, const struct ldb_val val)
    1948             : {
    1949      156807 :         char *n;
    1950      156807 :         struct ldb_val v;
    1951             : 
    1952     1225358 :         if ( ! ldb_dn_validate(dn)) {
    1953           0 :                 return LDB_ERR_OTHER;
    1954             :         }
    1955             : 
    1956     1225358 :         if (num < 0) {
    1957           0 :                 return LDB_ERR_OTHER;
    1958             :         }
    1959             : 
    1960     1225358 :         if ((unsigned)num >= dn->comp_num) {
    1961           3 :                 return LDB_ERR_OTHER;
    1962             :         }
    1963             : 
    1964     1225355 :         if (val.length > val.length + 1) {
    1965           0 :                 return LDB_ERR_OTHER;
    1966             :         }
    1967             : 
    1968     1225355 :         n = talloc_strdup(dn, name);
    1969     1225355 :         if ( ! n) {
    1970           0 :                 return LDB_ERR_OTHER;
    1971             :         }
    1972             : 
    1973     1225355 :         v.length = val.length;
    1974             : 
    1975             :         /*
    1976             :          * This is like talloc_memdup(dn, v.data, v.length + 1), but
    1977             :          * avoids the over-read
    1978             :          */
    1979     1225355 :         v.data = (uint8_t *)talloc_size(dn, v.length+1);
    1980     1225355 :         if ( ! v.data) {
    1981           0 :                 talloc_free(n);
    1982           0 :                 return LDB_ERR_OTHER;
    1983             :         }
    1984     1225355 :         memcpy(v.data, val.data, val.length);
    1985             : 
    1986             :         /*
    1987             :          * Enforce NUL termination outside the stated length, as is
    1988             :          * traditional in LDB
    1989             :          */
    1990     1225355 :         v.data[v.length] = '\0';
    1991             : 
    1992     1225355 :         talloc_free(dn->components[num].name);
    1993     1225355 :         talloc_free(dn->components[num].value.data);
    1994     1225355 :         dn->components[num].name = n;
    1995     1225355 :         dn->components[num].value = v;
    1996             : 
    1997     1225355 :         if (dn->valid_case) {
    1998             :                 unsigned int i;
    1999     4935810 :                 for (i = 0; i < dn->comp_num; i++) {
    2000     4264994 :                         LDB_FREE(dn->components[i].cf_name);
    2001     4264994 :                         LDB_FREE(dn->components[i].cf_value.data);
    2002             :                 }
    2003      670816 :                 dn->valid_case = false;
    2004             :         }
    2005     1225355 :         LDB_FREE(dn->casefold);
    2006     1225355 :         LDB_FREE(dn->linearized);
    2007             : 
    2008             :         /* Wipe the ext_linearized DN,
    2009             :          * the GUID and SID are almost certainly no longer valid */
    2010     1225355 :         LDB_FREE(dn->ext_linearized);
    2011     1225355 :         LDB_FREE(dn->ext_components);
    2012     1225355 :         dn->ext_comp_num = 0;
    2013             : 
    2014     1225355 :         return LDB_SUCCESS;
    2015             : }
    2016             : 
    2017   255376358 : const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
    2018             :                                                     const char *name)
    2019             : {
    2020     6761714 :         unsigned int i;
    2021   255376358 :         if ( ! ldb_dn_validate(dn)) {
    2022         718 :                 return NULL;
    2023             :         }
    2024   319908567 :         for (i=0; i < dn->ext_comp_num; i++) {
    2025   127973718 :                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
    2026    63440791 :                         return &dn->ext_components[i].value;
    2027             :                 }
    2028             :         }
    2029   186831981 :         return NULL;
    2030             : }
    2031             : 
    2032   156103841 : int ldb_dn_set_extended_component(struct ldb_dn *dn,
    2033             :                                   const char *name, const struct ldb_val *val)
    2034             : {
    2035     3714267 :         struct ldb_dn_ext_component *p;
    2036     3714267 :         unsigned int i;
    2037     3714267 :         struct ldb_val v2;
    2038     3714267 :         const struct ldb_dn_extended_syntax *ext_syntax;
    2039             :         
    2040   156103841 :         if ( ! ldb_dn_validate(dn)) {
    2041           0 :                 return LDB_ERR_OTHER;
    2042             :         }
    2043             : 
    2044   156103841 :         ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
    2045   156103841 :         if (ext_syntax == NULL) {
    2046             :                 /* We don't know how to handle this type of thing */
    2047           0 :                 return LDB_ERR_INVALID_DN_SYNTAX;
    2048             :         }
    2049             : 
    2050   247153272 :         for (i=0; i < dn->ext_comp_num; i++) {
    2051    91060078 :                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
    2052       10647 :                         if (val) {
    2053       10647 :                                 dn->ext_components[i].value =
    2054       10647 :                                         ldb_val_dup(dn->ext_components, val);
    2055             : 
    2056       10647 :                                 dn->ext_components[i].name = ext_syntax->name;
    2057       10647 :                                 if (!dn->ext_components[i].value.data) {
    2058           0 :                                         ldb_dn_mark_invalid(dn);
    2059           0 :                                         return LDB_ERR_OPERATIONS_ERROR;
    2060             :                                 }
    2061             :                         } else {
    2062           0 :                                 ARRAY_DEL_ELEMENT(
    2063             :                                         dn->ext_components,
    2064             :                                         i,
    2065           0 :                                         dn->ext_comp_num);
    2066           0 :                                 dn->ext_comp_num--;
    2067             : 
    2068           0 :                                 dn->ext_components = talloc_realloc(dn,
    2069             :                                                    dn->ext_components,
    2070             :                                                    struct ldb_dn_ext_component,
    2071             :                                                    dn->ext_comp_num);
    2072           0 :                                 if (!dn->ext_components) {
    2073           0 :                                         ldb_dn_mark_invalid(dn);
    2074           0 :                                         return LDB_ERR_OPERATIONS_ERROR;
    2075             :                                 }
    2076             :                         }
    2077       10647 :                         LDB_FREE(dn->ext_linearized);
    2078             : 
    2079       10647 :                         return LDB_SUCCESS;
    2080             :                 }
    2081             :         }
    2082             : 
    2083   156093194 :         if (val == NULL) {
    2084             :                 /* removing a value that doesn't exist is not an error */
    2085           0 :                 return LDB_SUCCESS;
    2086             :         }
    2087             : 
    2088   156093194 :         v2 = *val;
    2089             : 
    2090   159807401 :         p = dn->ext_components
    2091   156093194 :                 = talloc_realloc(dn,
    2092             :                                  dn->ext_components,
    2093             :                                  struct ldb_dn_ext_component,
    2094             :                                  dn->ext_comp_num + 1);
    2095   156093194 :         if (!dn->ext_components) {
    2096           0 :                 ldb_dn_mark_invalid(dn);
    2097           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2098             :         }
    2099             : 
    2100   156093194 :         p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2);
    2101   156093194 :         p[dn->ext_comp_num].name = talloc_strdup(p, name);
    2102             : 
    2103   156093194 :         if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
    2104           0 :                 ldb_dn_mark_invalid(dn);
    2105           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2106             :         }
    2107   156093194 :         dn->ext_components = p;
    2108   156093194 :         dn->ext_comp_num++;
    2109             : 
    2110   156093194 :         LDB_FREE(dn->ext_linearized);
    2111             : 
    2112   156093194 :         return LDB_SUCCESS;
    2113             : }
    2114             : 
    2115    45911895 : void ldb_dn_remove_extended_components(struct ldb_dn *dn)
    2116             : {
    2117    45911895 :         LDB_FREE(dn->ext_linearized);
    2118    45911895 :         LDB_FREE(dn->ext_components);
    2119    45911895 :         dn->ext_comp_num = 0;
    2120    45911895 : }
    2121             : 
    2122        4506 : bool ldb_dn_is_valid(struct ldb_dn *dn)
    2123             : {
    2124        4506 :         if ( ! dn) return false;
    2125        4506 :         return ! dn->invalid;
    2126             : }
    2127             : 
    2128  1846871839 : bool ldb_dn_is_special(struct ldb_dn *dn)
    2129             : {
    2130  1846871839 :         if ( ! dn || dn->invalid) return false;
    2131  1846871838 :         return dn->special;
    2132             : }
    2133             : 
    2134   456959282 : bool ldb_dn_has_extended(struct ldb_dn *dn)
    2135             : {
    2136   456959282 :         if ( ! dn || dn->invalid) return false;
    2137   456959282 :         if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
    2138   442345831 :         return dn->ext_comp_num != 0;
    2139             : }
    2140             : 
    2141    15856702 : bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
    2142             : {
    2143    15856702 :         if ( ! dn || dn->invalid) return false;
    2144    15856702 :         return ! strcmp(dn->linearized, check);
    2145             : }
    2146             : 
    2147   393887883 : bool ldb_dn_is_null(struct ldb_dn *dn)
    2148             : {
    2149   393887883 :         if ( ! dn || dn->invalid) return false;
    2150   393887883 :         if (ldb_dn_has_extended(dn)) return false;
    2151   341426106 :         if (dn->linearized && (dn->linearized[0] == '\0')) return true;
    2152   304736176 :         return false;
    2153             : }
    2154             : 
    2155             : /*
    2156             :   this updates dn->components, taking the components from ref_dn.
    2157             :   This is used by code that wants to update the DN path of a DN
    2158             :   while not impacting on the extended DN components
    2159             :  */
    2160       10918 : int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn)
    2161             : {
    2162       10918 :         dn->components = talloc_realloc(dn, dn->components,
    2163             :                                         struct ldb_dn_component, ref_dn->comp_num);
    2164       10918 :         if (!dn->components) {
    2165           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2166             :         }
    2167       10918 :         memcpy(dn->components, ref_dn->components,
    2168       10918 :                sizeof(struct ldb_dn_component)*ref_dn->comp_num);
    2169       10918 :         dn->comp_num = ref_dn->comp_num;
    2170             : 
    2171       10918 :         LDB_FREE(dn->casefold);
    2172       10918 :         LDB_FREE(dn->linearized);
    2173       10918 :         LDB_FREE(dn->ext_linearized);
    2174             : 
    2175       10918 :         return LDB_SUCCESS;
    2176             : }
    2177             : 
    2178             : /*
    2179             :   minimise a DN. The caller must pass in a validated DN.
    2180             : 
    2181             :   If the DN has an extended component then only the first extended
    2182             :   component is kept, the DN string is stripped.
    2183             : 
    2184             :   The existing dn is modified
    2185             :  */
    2186     8102642 : bool ldb_dn_minimise(struct ldb_dn *dn)
    2187             : {
    2188      291240 :         unsigned int i;
    2189             : 
    2190     8102642 :         if (!ldb_dn_validate(dn)) {
    2191           0 :                 return false;
    2192             :         }
    2193     8102642 :         if (dn->ext_comp_num == 0) {
    2194           0 :                 return true;
    2195             :         }
    2196             : 
    2197             :         /* free components */
    2198    41344595 :         for (i = 0; i < dn->comp_num; i++) {
    2199    33241953 :                 LDB_FREE(dn->components[i].name);
    2200    33241953 :                 LDB_FREE(dn->components[i].value.data);
    2201    33241953 :                 LDB_FREE(dn->components[i].cf_name);
    2202    33241953 :                 LDB_FREE(dn->components[i].cf_value.data);
    2203             :         }
    2204     8102642 :         dn->comp_num = 0;
    2205     8102642 :         dn->valid_case = false;
    2206             : 
    2207     8102642 :         LDB_FREE(dn->casefold);
    2208     8102642 :         LDB_FREE(dn->linearized);
    2209             : 
    2210             :         /* note that we don't free dn->components as this there are
    2211             :          * several places in ldb_dn.c that rely on it being non-NULL
    2212             :          * for an exploded DN
    2213             :          */
    2214             : 
    2215    11522462 :         for (i = 1; i < dn->ext_comp_num; i++) {
    2216     3419820 :                 LDB_FREE(dn->ext_components[i].value.data);
    2217             :         }
    2218     8102642 :         dn->ext_comp_num = 1;
    2219             : 
    2220     8102642 :         dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1);
    2221     8102642 :         if (dn->ext_components == NULL) {
    2222           0 :                 ldb_dn_mark_invalid(dn);
    2223           0 :                 return false;
    2224             :         }
    2225             : 
    2226     8102642 :         LDB_FREE(dn->ext_linearized);
    2227             : 
    2228     8102642 :         return true;
    2229             : }
    2230             : 
    2231      917105 : struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn)
    2232             : {
    2233      917105 :         return dn->ldb;
    2234             : }

Generated by: LCOV version 1.14