LCOV - code coverage report
Current view: top level - lib/ldb/common - ldb_dn.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 942 1140 82.6 %
Date: 2024-04-21 15:09:00 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) TALLOC_FREE(x)
      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       19949 : static void ldb_dn_mark_invalid(struct ldb_dn *dn)
      84             : {
      85       19949 :         dn->invalid = true;
      86       19930 : }
      87             : 
      88             : /* strdn may be NULL */
      89   917197685 : 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    25374748 :         struct ldb_dn *dn;
      94             : 
      95   917197685 :         if (ldb == NULL || strdn == NULL) {
      96           0 :                 return NULL;
      97             :         }
      98   917197685 :         if (strdn->data
      99   887701708 :             && (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   917197682 :         dn = talloc_zero(mem_ctx, struct ldb_dn);
     105   917197682 :         LDB_DN_NULL_FAILED(dn);
     106             : 
     107   917197682 :         dn->ldb = talloc_get_type(ldb, struct ldb_context);
     108   917197682 :         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  1779235414 :         if (strdn->data && strdn->length) {
     116   886790506 :                 const char *data = (const char *)strdn->data;
     117   886790506 :                 size_t length = strdn->length;
     118             : 
     119   886790506 :                 if (data[0] == '@') {
     120   413798608 :                         dn->special = true;
     121             :                 }
     122   886790506 :                 dn->ext_linearized = talloc_strndup(dn, data, length);
     123   886790506 :                 LDB_DN_NULL_FAILED(dn->ext_linearized);
     124             : 
     125   886790506 :                 if (data[0] == '<') {
     126    42466883 :                         const char *p_save, *p = dn->ext_linearized;
     127     2322040 :                         do {
     128   123006953 :                                 p_save = p;
     129   123006953 :                                 p = strstr(p, ">;");
     130   123006953 :                                 if (p) {
     131    79427619 :                                         p = p + 2;
     132             :                                 }
     133   123006953 :                         } while (p);
     134             : 
     135    43579334 :                         if (p_save == dn->ext_linearized) {
     136     8470124 :                                 dn->linearized = talloc_strdup(dn, "");
     137             :                         } else {
     138    35109210 :                                 dn->linearized = talloc_strdup(dn, p_save);
     139             :                         }
     140    43579334 :                         LDB_DN_NULL_FAILED(dn->linearized);
     141             :                 } else {
     142   843211172 :                         dn->linearized = dn->ext_linearized;
     143   843211172 :                         dn->ext_linearized = NULL;
     144             :                 }
     145             :         } else {
     146    30407176 :                 dn->linearized = talloc_strdup(dn, "");
     147    30407176 :                 LDB_DN_NULL_FAILED(dn->linearized);
     148             :         }
     149             : 
     150   891822937 :         return dn;
     151             : 
     152           0 : failed:
     153           0 :         talloc_free(dn);
     154           0 :         return NULL;
     155             : }
     156             : 
     157             : /* strdn may be NULL */
     158   345095843 : struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx,
     159             :                           struct ldb_context *ldb,
     160             :                           const char *strdn)
     161             : {
     162    11391814 :         struct ldb_val blob;
     163   345095843 :         blob.data = discard_const_p(uint8_t, strdn);
     164   345095843 :         blob.length = strdn ? strlen(strdn) : 0;
     165   345095843 :         return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
     166             : }
     167             : 
     168   201755502 : struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx,
     169             :                               struct ldb_context *ldb,
     170             :                               const char *new_fmt, ...)
     171             : {
     172     6647543 :         char *strdn;
     173     6647543 :         va_list ap;
     174             : 
     175   201755502 :         if (! ldb) return NULL;
     176             : 
     177   201755502 :         va_start(ap, new_fmt);
     178   201755502 :         strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
     179   201755502 :         va_end(ap);
     180             : 
     181   201755502 :         if (strdn) {
     182   201755502 :                 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
     183   201755502 :                 talloc_free(strdn);
     184   201755502 :                 return dn;
     185             :         }
     186             : 
     187           0 :         return NULL;
     188             : }
     189             : 
     190             : /* see RFC2253 section 2.4 */
     191   233569421 : static int ldb_dn_escape_internal(char *dst, const char *src, int len)
     192             : {
     193    14403401 :         char c;
     194    14403401 :         char *d;
     195    14403401 :         int i;
     196   233569421 :         d = dst;
     197             : 
     198  2242387301 :         for (i = 0; i < len; i++){
     199  2008817880 :                 c = src[i];
     200  2008817880 :                 switch (c) {
     201    15007853 :                 case ' ':
     202    15007853 :                         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    15007853 :                                 *d++ = c;
     210             :                         }
     211    14074605 :                         break;
     212             : 
     213       37087 :                 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       37087 :                         *d++ = '\\';
     225       37087 :                         *d++ = c;
     226       37087 :                         break;
     227             : 
     228     1696423 :                 case ';':
     229             :                 case '\r':
     230             :                 case '\n':
     231             :                 case '=':
     232             :                 case '\0': {
     233             :                         /* any others get \XX form */
     234         927 :                         unsigned char v;
     235     1696423 :                         const char *hexbytes = "0123456789ABCDEF";
     236     1696423 :                         v = (const unsigned char)c;
     237     1696423 :                         *d++ = '\\';
     238     1696423 :                         *d++ = hexbytes[v>>4];
     239     1696423 :                         *d++ = hexbytes[v&0xF];
     240     1696423 :                         break;
     241             :                 }
     242  1992076517 :                 default:
     243  1992076517 :                         *d++ = c;
     244             :                 }
     245             :         }
     246             : 
     247             :         /* return the length of the resulting string */
     248   233569421 :         return (d - dst);
     249             : }
     250             : 
     251    15561603 : char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value)
     252             : {
     253      957728 :         char *dst;
     254      957728 :         size_t len;
     255    15561603 :         if (!value.length)
     256           2 :                 return NULL;
     257             : 
     258             :         /* allocate destination string, it will be at most 3 times the source */
     259    15561601 :         dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
     260    15561601 :         if ( ! dst) {
     261           0 :                 talloc_free(dst);
     262           0 :                 return NULL;
     263             :         }
     264             : 
     265    15561601 :         len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
     266             : 
     267    15561601 :         dst = talloc_realloc(mem_ctx, dst, char, len + 1);
     268    15561601 :         if ( ! dst) {
     269           0 :                 talloc_free(dst);
     270           0 :                 return NULL;
     271             :         }
     272    15561601 :         dst[len] = '\0';
     273    15561601 :         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  1231503079 : static bool ldb_dn_explode(struct ldb_dn *dn)
     284             : {
     285  1231503079 :         char *p, *ex_name = NULL, *ex_value = NULL, *data, *d, *dt, *t;
     286  1231503079 :         bool trim = true;
     287  1231503079 :         bool in_extended = true;
     288  1231503079 :         bool in_ex_name = false;
     289  1231503079 :         bool in_ex_value = false;
     290  1231503079 :         bool in_attr = false;
     291  1231503079 :         bool in_value = false;
     292  1231503079 :         bool in_quote = false;
     293  1231503079 :         bool is_oid = false;
     294  1231503079 :         bool escape = false;
     295    36347095 :         unsigned int x;
     296  1231503079 :         size_t l = 0;
     297    36347095 :         int ret;
     298    36347095 :         char *parse_dn;
     299    36347095 :         bool is_index;
     300             : 
     301  1231503079 :         if (dn == NULL || dn->invalid) {
     302         718 :                 return false;
     303             :         }
     304             : 
     305  1231502356 :         if (dn->components != NULL) {
     306   643692392 :                 return true;
     307             :         }
     308             : 
     309   565266444 :         if (dn->ext_linearized != NULL) {
     310    38945203 :                 parse_dn = dn->ext_linearized;
     311             :         } else {
     312   525452749 :                 parse_dn = dn->linearized;
     313             :         }
     314             : 
     315   565266444 :         if (parse_dn == NULL) {
     316           0 :                 return false;
     317             :         }
     318             : 
     319   565266444 :         is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
     320             : 
     321             :         /* Empty DNs */
     322   565266444 :         if (parse_dn[0] == '\0') {
     323    30609776 :                 return true;
     324             :         }
     325             : 
     326             :         /* Special DNs case */
     327   533715318 :         if (dn->special) {
     328   257373328 :                 return true;
     329             :         }
     330             : 
     331   268553135 :         LDB_FREE(dn->ext_components);
     332   268553135 :         dn->ext_comp_num = 0;
     333   268553135 :         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   268553135 :         dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
     338   268553135 :         if (dn->components == NULL) {
     339           0 :                 return false;
     340             :         }
     341             : 
     342             :         /* Components data space is allocated here once */
     343   268553135 :         data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
     344   268553135 :         if (data == NULL) {
     345           0 :                 goto failed;
     346             :         }
     347             : 
     348   263479770 :         p = parse_dn;
     349   263479770 :         t = NULL;
     350   263479770 :         d = dt = data;
     351             : 
     352 26235790349 :         while (*p) {
     353 25975708588 :                 if (in_extended) {
     354             : 
     355  3289285023 :                         if (!in_ex_name && !in_ex_value) {
     356             : 
     357   339532821 :                                 if (p[0] == '<') {
     358    79449826 :                                         p++;
     359    79449826 :                                         ex_name = d;
     360    79449826 :                                         in_ex_name = true;
     361    79449826 :                                         continue;
     362             :                                 } else {
     363   260082995 :                                         in_extended = false;
     364   260082995 :                                         in_attr = true;
     365   260082995 :                                         dt = d;
     366             : 
     367   260082995 :                                         continue;
     368             :                                 }
     369             :                         }
     370             : 
     371  2949752202 :                         if (in_ex_name && *p == '=') {
     372    79449822 :                                 *d++ = '\0';
     373    79449822 :                                 p++;
     374    79449822 :                                 ex_value = d;
     375    79449822 :                                 in_ex_name = false;
     376    79449822 :                                 in_ex_value = true;
     377    79449822 :                                 continue;
     378             :                         }
     379             : 
     380  2870302380 :                         if (in_ex_value && *p == '>') {
     381    79449822 :                                 struct ldb_dn_ext_component *ext_comp = NULL;
     382     1167105 :                                 const struct ldb_dn_extended_syntax *ext_syntax;
     383    79449822 :                                 struct ldb_val ex_val = {
     384             :                                         .data = (uint8_t *)ex_value,
     385    79449822 :                                         .length = d - ex_value
     386             :                                 };
     387             : 
     388    79449822 :                                 *d++ = '\0';
     389    79449822 :                                 p++;
     390    79449822 :                                 in_ex_value = false;
     391             : 
     392             :                                 /* Process name and ex_value */
     393             : 
     394    79449822 :                                 ext_comp = talloc_realloc(
     395             :                                         dn,
     396             :                                         dn->ext_components,
     397             :                                         struct ldb_dn_ext_component,
     398             :                                         dn->ext_comp_num + 1);
     399             : 
     400    79449822 :                                 if (ext_comp == NULL) {
     401             :                                         /* ouch ! */
     402         450 :                                         goto failed;
     403             :                                 }
     404             : 
     405    79449822 :                                 dn->ext_components = ext_comp;
     406             : 
     407    79449822 :                                 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
     408    79449822 :                                 if (ext_syntax == NULL) {
     409             :                                         /* We don't know about this type of extended DN */
     410           9 :                                         goto failed;
     411             :                                 }
     412             : 
     413    79449813 :                                 dn->ext_components[dn->ext_comp_num].name = ext_syntax->name;
     414    79449813 :                                 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
     415    78282717 :                                                           &ex_val, &dn->ext_components[dn->ext_comp_num].value);
     416    79449813 :                                 if (ret != LDB_SUCCESS) {
     417         441 :                                         ldb_dn_mark_invalid(dn);
     418         441 :                                         goto failed;
     419             :                                 }
     420             : 
     421    79449372 :                                 dn->ext_comp_num++;
     422             : 
     423    79449372 :                                 if (*p == '\0') {
     424             :                                         /* We have reached the end (extended component only)! */
     425     8469686 :                                         talloc_free(data);
     426     8469686 :                                         return true;
     427             : 
     428    70979686 :                                 } else if (*p == ';') {
     429    70979686 :                                         p++;
     430    70979686 :                                         continue;
     431             :                                 } else {
     432           0 :                                         ldb_dn_mark_invalid(dn);
     433           0 :                                         goto failed;
     434             :                                 }
     435             :                         }
     436             : 
     437  2790852558 :                         *d++ = *p++;
     438  2790852558 :                         continue;
     439             :                 }
     440 22686423565 :                 if (in_attr) {
     441  4516389630 :                         if (trim) {
     442  1526869250 :                                 if (*p == ' ') {
     443    34066599 :                                         p++;
     444    34066599 :                                         continue;
     445             :                                 }
     446             : 
     447             :                                 /* first char */
     448  1492802651 :                                 trim = false;
     449             : 
     450  1492802651 :                                 if (!isascii(*p)) {
     451             :                                         /* attr names must be ascii only */
     452           0 :                                         ldb_dn_mark_invalid(dn);
     453           0 :                                         goto failed;
     454             :                                 }
     455             : 
     456  1492802651 :                                 if (isdigit(*p)) {
     457           0 :                                         is_oid = true;
     458             :                                 } else
     459  1492802651 :                                 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  1492802644 :                                 *d++ = *p++;
     469  1492802644 :                                 continue;
     470             :                         }
     471             : 
     472  2989520380 :                         if (*p == ' ') {
     473          96 :                                 p++;
     474             :                                 /* valid only if we are at the end */
     475          96 :                                 trim = true;
     476          96 :                                 continue;
     477             :                         }
     478             : 
     479  2989520284 :                         if (*p == '=') {
     480             :                                 /* attribute terminated */
     481  1492783052 :                                 in_attr = false;
     482  1492783052 :                                 in_value = true;
     483  1492783052 :                                 trim = true;
     484  1492783052 :                                 l = 0;
     485             : 
     486             :                                 /* Terminate this string in d
     487             :                                  * (which is a copy of parse_dn
     488             :                                  *  with spaces trimmed) */
     489  1492783052 :                                 *d++ = '\0';
     490  1492783052 :                                 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
     491  1492783052 :                                 if (dn->components[dn->comp_num].name == NULL) {
     492             :                                         /* ouch */
     493           0 :                                         goto failed;
     494             :                                 }
     495             : 
     496  1492783052 :                                 dt = d;
     497             : 
     498  1492783052 :                                 p++;
     499  1492783052 :                                 continue;
     500             :                         }
     501             : 
     502  1496737232 :                         if (!isascii(*p)) {
     503             :                                 /* attr names must be ascii only */
     504           0 :                                 ldb_dn_mark_invalid(dn);
     505           0 :                                 goto failed;
     506             :                         }
     507             : 
     508  1496737232 :                         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  1496737232 :                         if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
     515             :                                 /* not ALPHA, DIGIT or HYPHEN */
     516        1231 :                                 ldb_dn_mark_invalid(dn);
     517        1231 :                                 goto failed;
     518             :                         }
     519             : 
     520  1496736001 :                         *d++ = *p++;
     521  1496736001 :                         continue;
     522             :                 }
     523             : 
     524 18170033935 :                 if (in_value) {
     525 18170033935 :                         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 18170033935 :                         if (trim) {
     539  1492783075 :                                 if (*p == ' ') {
     540          31 :                                         p++;
     541          31 :                                         continue;
     542             :                                 }
     543             : 
     544             :                                 /* first char */
     545  1492783044 :                                 trim = false;
     546             : 
     547  1492783044 :                                 if (*p == '\"') {
     548           0 :                                         in_quote = true;
     549           0 :                                         p++;
     550           0 :                                         continue;
     551             :                                 }
     552             :                         }
     553             : 
     554 18170033904 :                         switch (*p) {
     555             : 
     556             :                         /* TODO: support ber encoded values
     557             :                         case '#':
     558             :                         */
     559             : 
     560  1232746415 :                         case ',':
     561  1232746415 :                                 if (escape) {
     562       26850 :                                         *d++ = *p++;
     563       26850 :                                         l++;
     564       26850 :                                         escape = false;
     565       26850 :                                         continue;
     566             :                                 }
     567             :                                 /* ok found value terminator */
     568             : 
     569  1232719565 :                                 if (t != NULL) {
     570             :                                         /* trim back */
     571          22 :                                         d -= (p - t);
     572          22 :                                         l -= (p - t);
     573          22 :                                         t = NULL;
     574             :                                 }
     575             : 
     576  1232719565 :                                 in_attr = true;
     577  1232719565 :                                 in_value = false;
     578  1232719565 :                                 trim = true;
     579             : 
     580  1232719565 :                                 p++;
     581  1232719565 :                                 *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  2465439130 :                                 dn->components[dn->comp_num].value.data = \
     589  1232719565 :                                         (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
     590  1232719565 :                                 dn->components[dn->comp_num].value.length = l;
     591  1232719565 :                                 if (dn->components[dn->comp_num].value.data == NULL) {
     592             :                                         /* ouch ! */
     593           0 :                                         goto failed;
     594             :                                 }
     595  1232719565 :                                 talloc_set_name_const(dn->components[dn->comp_num].value.data,
     596  1208454113 :                                                       (const char *)dn->components[dn->comp_num].value.data);
     597             : 
     598  1232719565 :                                 dt = d;
     599             : 
     600  1232719565 :                                 dn->comp_num++;
     601  1232719565 :                                 if (dn->comp_num > 2) {
     602   721309813 :                                         dn->components = talloc_realloc(dn,
     603             :                                                                         dn->components,
     604             :                                                                         struct ldb_dn_component,
     605             :                                                                         dn->comp_num + 1);
     606   721309813 :                                         if (dn->components == NULL) {
     607             :                                                 /* ouch ! */
     608           0 :                                                 goto failed;
     609             :                                         }
     610             :                                         /* make sure all components are zeroed, other functions depend on this */
     611   721309813 :                                         memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
     612             :                                 }
     613             : 
     614  1232719565 :                                 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    85599004 :                         case '\\':
     653    85599004 :                                 if (!escape) {
     654    85588204 :                                         escape = true;
     655    85588204 :                                         p++;
     656    85588204 :                                         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 16851688485 :                         default:
     669 16851688485 :                                 if (escape) {
     670    85550554 :                                         if (isxdigit(p[0]) && isxdigit(p[1])) {
     671    85550554 :                                                 if (sscanf(p, "%02x", &x) != 1) {
     672             :                                                         /* invalid escaping sequence */
     673           0 :                                                         ldb_dn_mark_invalid(dn);
     674           0 :                                                         goto failed;
     675             :                                                 }
     676    85550554 :                                                 p += 2;
     677    85550554 :                                                 *d++ = (unsigned char)x;
     678             :                                         } else {
     679           0 :                                                 *d++ = *p++;
     680             :                                         }
     681             : 
     682    85550554 :                                         escape = false;
     683    85550554 :                                         l++;
     684    85550554 :                                         if (t != NULL) {
     685           0 :                                                 t = NULL;
     686             :                                         }
     687    85549646 :                                         break;
     688             :                                 }
     689             : 
     690 16766137931 :                                 if (*p == ' ') {
     691   124629360 :                                         if (t == NULL) {
     692   124625289 :                                                 t = p;
     693             :                                         }
     694             :                                 } else {
     695 16385527390 :                                         if (t != NULL) {
     696   123511713 :                                                 t = NULL;
     697             :                                         }
     698             :                                 }
     699             : 
     700 16766137931 :                                 *d++ = *p++;
     701 16766137931 :                                 l++;
     702             : 
     703 16766137931 :                                 break;
     704             :                         }
     705             : 
     706             :                 }
     707             :         }
     708             : 
     709   260081761 :         if (in_attr || in_quote) {
     710             :                 /* invalid dn */
     711       18270 :                 ldb_dn_mark_invalid(dn);
     712       18270 :                 goto failed;
     713             :         }
     714             : 
     715   260063491 :         if (in_value) {
     716             :                 /* save last element */
     717   260063487 :                 if (t != NULL) {
     718             :                         /* trim back */
     719         190 :                         d -= (p - t);
     720         190 :                         l -= (p - t);
     721             :                 }
     722             : 
     723   260063487 :                 *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   260063487 :                 dn->components[dn->comp_num].value.length = l;
     730   520126974 :                 dn->components[dn->comp_num].value.data =
     731   260063487 :                         (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
     732   260063487 :                 if (dn->components[dn->comp_num].value.data == NULL) {
     733             :                         /* ouch */
     734           0 :                         goto failed;
     735             :                 }
     736   260063487 :                 talloc_set_name_const(dn->components[dn->comp_num].value.data,
     737   255219278 :                         (const char *)dn->components[dn->comp_num].value.data);
     738             : 
     739   260063487 :                 dn->comp_num++;
     740             :         }
     741   260063491 :         talloc_free(data);
     742   260063491 :         return true;
     743             : 
     744       19958 : failed:
     745       19958 :         LDB_FREE(dn->components); /* "data" is implicitly free'd */
     746       19958 :         dn->comp_num = 0;
     747       19958 :         LDB_FREE(dn->ext_components);
     748       19958 :         dn->ext_comp_num = 0;
     749             : 
     750       19958 :         return false;
     751             : }
     752             : 
     753  1133856710 : bool ldb_dn_validate(struct ldb_dn *dn)
     754             : {
     755  1133856710 :         return ldb_dn_explode(dn);
     756             : }
     757             : 
     758   763279143 : const char *ldb_dn_get_linearized(struct ldb_dn *dn)
     759             : {
     760    25217101 :         unsigned int i;
     761    25217101 :         size_t len;
     762    25217101 :         char *d, *n;
     763             : 
     764   763279143 :         if ( ! dn || ( dn->invalid)) return NULL;
     765             : 
     766   763278802 :         if (dn->linearized) return dn->linearized;
     767             : 
     768    10792089 :         if ( ! dn->components) {
     769           0 :                 ldb_dn_mark_invalid(dn);
     770           0 :                 return NULL;
     771             :         }
     772             : 
     773    10792089 :         if (dn->comp_num == 0) {
     774      531265 :                 dn->linearized = talloc_strdup(dn, "");
     775      531265 :                 if ( ! dn->linearized) return NULL;
     776      531265 :                 return dn->linearized;
     777             :         }
     778             : 
     779             :         /* calculate maximum possible length of DN */
     780    66907259 :         for (len = 0, i = 0; i < dn->comp_num; i++) {
     781             :                 /* name len */
     782    56646435 :                 len += strlen(dn->components[i].name);
     783             :                 /* max escaped data len */
     784    56646435 :                 len += (dn->components[i].value.length * 3);
     785    56646435 :                 len += 2; /* '=' and ',' */
     786             :         }
     787    10260824 :         dn->linearized = talloc_array(dn, char, len);
     788    10260824 :         if ( ! dn->linearized) return NULL;
     789             : 
     790     9633525 :         d = dn->linearized;
     791             : 
     792    66907259 :         for (i = 0; i < dn->comp_num; i++) {
     793             : 
     794             :                 /* copy the name */
     795    56646435 :                 n = dn->components[i].name;
     796   169939890 :                 while (*n) *d++ = *n++;
     797             : 
     798    56646435 :                 *d++ = '=';
     799             : 
     800             :                 /* and the value */
     801   113292870 :                 d += ldb_dn_escape_internal( d,
     802    56646435 :                                 (char *)dn->components[i].value.data,
     803    56646435 :                                 dn->components[i].value.length);
     804    56646435 :                 *d++ = ',';
     805             :         }
     806             : 
     807    10260824 :         *(--d) = '\0';
     808             : 
     809             :         /* don't waste more memory than necessary */
     810    10260824 :         dn->linearized = talloc_realloc(dn, dn->linearized,
     811             :                                         char, (d - dn->linearized + 1));
     812             : 
     813    10260824 :         return dn->linearized;
     814             : }
     815             : 
     816    49785541 : static int ldb_dn_extended_component_compare(const void *p1, const void *p2)
     817             : {
     818    49785541 :         const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1;
     819    49785541 :         const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2;
     820    49785541 :         return strcmp(ec1->name, ec2->name);
     821             : }
     822             : 
     823    27967023 : char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode)
     824             : {
     825    27967023 :         const char *linearized = ldb_dn_get_linearized(dn);
     826    27967023 :         char *p = NULL;
     827      620780 :         unsigned int i;
     828             : 
     829    27967023 :         if (!linearized) {
     830          96 :                 return NULL;
     831             :         }
     832             : 
     833    27966927 :         if (!ldb_dn_has_extended(dn)) {
     834     1564152 :                 return talloc_strdup(mem_ctx, linearized);
     835             :         }
     836             : 
     837    26402775 :         if (!ldb_dn_validate(dn)) {
     838           0 :                 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    26402772 :         TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num,
     846             :                        ldb_dn_extended_component_compare);
     847             : 
     848    77911549 :         for (i = 0; i < dn->ext_comp_num; i++) {
     849      626980 :                 const struct ldb_dn_extended_syntax *ext_syntax;
     850    51508777 :                 const char *name = dn->ext_components[i].name;
     851    51508777 :                 struct ldb_val ec_val = dn->ext_components[i].value;
     852      626980 :                 struct ldb_val val;
     853      626980 :                 int ret;
     854             : 
     855    51508777 :                 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
     856    51508777 :                 if (!ext_syntax) {
     857           0 :                         return NULL;
     858             :                 }
     859             : 
     860    51508777 :                 if (mode == 1) {
     861    41250597 :                         ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
     862             :                                                         &ec_val, &val);
     863    10258180 :                 } else if (mode == 0) {
     864    10258180 :                         ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
     865             :                                                         &ec_val, &val);
     866             :                 } else {
     867           0 :                         ret = -1;
     868             :                 }
     869             : 
     870    51508777 :                 if (ret != LDB_SUCCESS) {
     871           0 :                         return NULL;
     872             :                 }
     873             : 
     874    51508777 :                 if (i == 0) {
     875    26402768 :                         p = talloc_asprintf(mem_ctx, "<%s=%.*s>",
     876             :                                             name,
     877    26402768 :                                             (int)val.length,
     878             :                                             val.data);
     879             :                 } else {
     880    25106009 :                         talloc_asprintf_addbuf(&p, ";<%s=%.*s>",
     881             :                                                name,
     882    25106009 :                                                (int)val.length,
     883             :                                                val.data);
     884             :                 }
     885             : 
     886    51508777 :                 talloc_free(val.data);
     887             :         }
     888             : 
     889    26402772 :         if (dn->ext_comp_num && *linearized) {
     890    25158944 :                 talloc_asprintf_addbuf(&p, ";%s", linearized);
     891             :         }
     892             : 
     893    26402772 :         if (!p) {
     894           4 :                 return NULL;
     895             :         }
     896             : 
     897    25891587 :         return p;
     898             : }
     899             : 
     900             : /*
     901             :   filter out all but an acceptable list of extended DN components
     902             :  */
     903    16753293 : void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list)
     904             : {
     905      203108 :         unsigned int i;
     906    58714134 :         for (i=0; i<dn->ext_comp_num; i++) {
     907    41960841 :                 if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) {
     908    19186677 :                         ARRAY_DEL_ELEMENT(
     909        3206 :                                 dn->ext_components, i, dn->ext_comp_num);
     910    19186677 :                         dn->ext_comp_num--;
     911    19186677 :                         i--;
     912             :                 }
     913             :         }
     914    16753293 :         LDB_FREE(dn->ext_linearized);
     915    16753293 : }
     916             : 
     917             : 
     918   172561890 : char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
     919             : {
     920   172561890 :         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   278618952 : static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
     929             : {
     930     4305448 :         unsigned int i;
     931     4305448 :         int ret;
     932             : 
     933   278618952 :         if ( ! dn || dn->invalid) return false;
     934             : 
     935   278618952 :         if (dn->valid_case) return true;
     936             : 
     937   139466087 :         if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
     938         736 :                 return false;
     939             :         }
     940             : 
     941   883327282 :         for (i = 0; i < dn->comp_num; i++) {
     942    12272058 :                 const struct ldb_schema_attribute *a;
     943             : 
     944  1487723862 :                 dn->components[i].cf_name =
     945   743861931 :                         ldb_attr_casefold(dn->components,
     946   743861931 :                                           dn->components[i].name);
     947   743861931 :                 if (!dn->components[i].cf_name) {
     948           0 :                         goto failed;
     949             :                 }
     950             : 
     951   743861931 :                 a = ldb_schema_attribute_by_name(dn->ldb,
     952   731589873 :                                                  dn->components[i].cf_name);
     953             : 
     954   756133989 :                 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
     955   743861931 :                                                  &(dn->components[i].value),
     956   743861931 :                                                  &(dn->components[i].cf_value));
     957   743861931 :                 if (ret != 0) {
     958           0 :                         goto failed;
     959             :                 }
     960             :         }
     961             : 
     962   139465351 :         dn->valid_case = true;
     963             : 
     964   139465351 :         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   502543102 : const char *ldb_dn_get_casefold(struct ldb_dn *dn)
     975             : {
     976    16112516 :         unsigned int i;
     977    16112516 :         size_t len;
     978    16112516 :         char *d, *n;
     979             : 
     980   502543102 :         if (dn->casefold) return dn->casefold;
     981             : 
     982   314292807 :         if (dn->special) {
     983   281837039 :                 dn->casefold = talloc_strdup(dn, dn->linearized);
     984   281837039 :                 if (!dn->casefold) return NULL;
     985   281837039 :                 dn->valid_case = true;
     986   281837039 :                 return dn->casefold;
     987             :         }
     988             : 
     989    32455768 :         if ( ! ldb_dn_casefold_internal(dn)) {
     990           0 :                 return NULL;
     991             :         }
     992             : 
     993    32455768 :         if (dn->comp_num == 0) {
     994        1358 :                 dn->casefold = talloc_strdup(dn, "");
     995        1358 :                 return dn->casefold;
     996             :         }
     997             : 
     998             :         /* calculate maximum possible length of DN */
     999   193815795 :         for (len = 0, i = 0; i < dn->comp_num; i++) {
    1000             :                 /* name len */
    1001   161361385 :                 len += strlen(dn->components[i].cf_name);
    1002             :                 /* max escaped data len */
    1003   161361385 :                 len += (dn->components[i].cf_value.length * 3);
    1004   161361385 :                 len += 2; /* '=' and ',' */
    1005             :         }
    1006    32454410 :         dn->casefold = talloc_array(dn, char, len);
    1007    32454410 :         if ( ! dn->casefold) return NULL;
    1008             : 
    1009    30452512 :         d = dn->casefold;
    1010             : 
    1011   193815795 :         for (i = 0; i < dn->comp_num; i++) {
    1012             : 
    1013             :                 /* copy the name */
    1014   161361385 :                 n = dn->components[i].cf_name;
    1015   485615356 :                 while (*n) *d++ = *n++;
    1016             : 
    1017   161361385 :                 *d++ = '=';
    1018             : 
    1019             :                 /* and the value */
    1020   322722770 :                 d += ldb_dn_escape_internal( d,
    1021   161361385 :                                 (char *)dn->components[i].cf_value.data,
    1022   161361385 :                                 dn->components[i].cf_value.length);
    1023   161361385 :                 *d++ = ',';
    1024             :         }
    1025    32454410 :         *(--d) = '\0';
    1026             : 
    1027             :         /* don't waste more memory than necessary */
    1028    32454410 :         dn->casefold = talloc_realloc(dn, dn->casefold,
    1029             :                                       char, strlen(dn->casefold) + 1);
    1030             : 
    1031    32454410 :         return dn->casefold;
    1032             : }
    1033             : 
    1034     2464710 : char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1035             : {
    1036     2464710 :         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   574858814 : int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
    1045             : {
    1046    12305505 :         int ret;
    1047    12305505 :         unsigned int n_base, n_dn;
    1048             : 
    1049   574858814 :         if ( ! base || base->invalid) return 1;
    1050   574858814 :         if ( ! dn || dn->invalid) return -1;
    1051             : 
    1052   574858814 :         if (( ! base->valid_case) || ( ! dn->valid_case)) {
    1053   396712909 :                 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     6468510 :                         int dif;
    1057   389051555 :                         dif = strlen(dn->linearized) - strlen(base->linearized);
    1058   389051555 :                         if (dif < 0) {
    1059   126894824 :                                 return dif;
    1060             :                         }
    1061   259782343 :                         if (strcmp(base->linearized,
    1062   259782343 :                                    &dn->linearized[dif]) == 0) {
    1063   149706211 :                                 return 0;
    1064             :                         }
    1065             :                 }
    1066             : 
    1067   114028056 :                 if ( ! ldb_dn_casefold_internal(base)) {
    1068           0 :                         return 1;
    1069             :                 }
    1070             : 
    1071   114028056 :                 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   292173961 :         if (base->comp_num > dn->comp_num) {
    1080    54961221 :                 return (dn->comp_num - base->comp_num);
    1081             :         }
    1082             : 
    1083   237212740 :         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   237212739 :         n_base = base->comp_num - 1;
    1096   237212739 :         n_dn = dn->comp_num - 1;
    1097             : 
    1098  1114703527 :         while (n_base != (unsigned int) -1) {
    1099  1018896690 :                 char *b_name = base->components[n_base].cf_name;
    1100  1018896690 :                 char *dn_name = dn->components[n_dn].cf_name;
    1101             : 
    1102  1018896690 :                 char *b_vdata = (char *)base->components[n_base].cf_value.data;
    1103  1018896690 :                 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
    1104             : 
    1105  1018896690 :                 size_t b_vlen = base->components[n_base].cf_value.length;
    1106  1018896690 :                 size_t dn_vlen = dn->components[n_dn].cf_value.length;
    1107             : 
    1108             :                 /* compare attr names */
    1109  1018896690 :                 ret = strcmp(b_name, dn_name);
    1110  1018896690 :                 if (ret != 0) return ret;
    1111             : 
    1112             :                 /* compare attr.cf_value. */
    1113   926792923 :                 if (b_vlen != dn_vlen) {
    1114    47633760 :                         return NUMERIC_CMP(b_vlen, dn_vlen);
    1115             :                 }
    1116   879159163 :                 ret = strncmp(b_vdata, dn_vdata, b_vlen);
    1117   879159163 :                 if (ret != 0) return ret;
    1118             : 
    1119   877490788 :                 n_base--;
    1120   877490788 :                 n_dn--;
    1121             :         }
    1122             : 
    1123    92250482 :         return 0;
    1124             : }
    1125             : 
    1126             : /* compare DNs using casefolding compare functions.
    1127             : 
    1128             :    If they match, then return 0
    1129             :  */
    1130             : 
    1131    68284613 : int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
    1132             : {
    1133     4487022 :         unsigned int i;
    1134     4487022 :         int ret;
    1135             : 
    1136    68284613 :         if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
    1137           2 :                 return -1;
    1138             :         }
    1139             : 
    1140    68284611 :         if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
    1141    10509160 :                 if (dn0->linearized && dn1->linearized) {
    1142             :                         /* try with a normal compare first, if we are lucky
    1143             :                          * we will avoid exploding and casefolding */
    1144     8376849 :                         if (strcmp(dn0->linearized, dn1->linearized) == 0) {
    1145     1441644 :                                 return 0;
    1146             :                         }
    1147             :                 }
    1148             : 
    1149     9053536 :                 if ( ! ldb_dn_casefold_internal(dn0)) {
    1150           0 :                         return 1;
    1151             :                 }
    1152             : 
    1153     9053536 :                 if ( ! ldb_dn_casefold_internal(dn1)) {
    1154         736 :                         return -1;
    1155             :                 }
    1156             : 
    1157             :         }
    1158             : 
    1159             :         /*
    1160             :          * Notice that for comp_num, Samba reverses the usual order of
    1161             :          * comparison. A DN with fewer components is greater than one
    1162             :          * with more.
    1163             :          */
    1164    66828251 :         if (dn0->comp_num > dn1->comp_num) {
    1165    18258607 :                 return -1;
    1166    46110182 :         } else if (dn0->comp_num < dn1->comp_num) {
    1167    19671347 :                 return 1;
    1168             :         }
    1169             : 
    1170    25474574 :         if (dn0->comp_num == 0) {
    1171     1106191 :                 if (dn0->special && dn1->special) {
    1172     1106191 :                         return strcmp(dn0->linearized, dn1->linearized);
    1173           0 :                 } else if (dn0->special) {
    1174           0 :                         return 1;
    1175           0 :                 } else if (dn1->special) {
    1176           0 :                         return -1;
    1177             :                 } else {
    1178           0 :                         return 0;
    1179             :                 }
    1180             :         }
    1181             : 
    1182    71780023 :         for (i = 0; i < dn0->comp_num; i++) {
    1183    61524302 :                 char *dn0_name = dn0->components[i].cf_name;
    1184    61524302 :                 char *dn1_name = dn1->components[i].cf_name;
    1185             : 
    1186    61524302 :                 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
    1187    61524302 :                 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
    1188             : 
    1189    61524302 :                 size_t dn0_vlen = dn0->components[i].cf_value.length;
    1190    61524302 :                 size_t dn1_vlen = dn1->components[i].cf_value.length;
    1191             : 
    1192             :                 /* compare attr names */
    1193    61524302 :                 ret = strcmp(dn0_name, dn1_name);
    1194    61524302 :                 if (ret != 0) {
    1195     3414088 :                         return ret;
    1196             :                 }
    1197             : 
    1198             :                 /* compare attr.cf_value. */
    1199    58110214 :                 if (dn0_vlen != dn1_vlen) {
    1200     6021879 :                         return NUMERIC_CMP(dn0_vlen, dn1_vlen);
    1201             :                 }
    1202    52088335 :                 ret = strncmp(dn0_vdata, dn1_vdata, dn0_vlen);
    1203    52088335 :                 if (ret != 0) {
    1204     4676695 :                         return ret;
    1205             :                 }
    1206             :         }
    1207             : 
    1208     9717677 :         return 0;
    1209             : }
    1210             : 
    1211   412982283 : static struct ldb_dn_component ldb_dn_copy_component(
    1212             :                                                 TALLOC_CTX *mem_ctx,
    1213             :                                                 struct ldb_dn_component *src)
    1214             : {
    1215    20865033 :         struct ldb_dn_component dst;
    1216             : 
    1217   412982283 :         memset(&dst, 0, sizeof(dst));
    1218             : 
    1219   412982283 :         if (src == NULL) {
    1220           0 :                 return dst;
    1221             :         }
    1222             : 
    1223   412982283 :         dst.value = ldb_val_dup(mem_ctx, &(src->value));
    1224   412982283 :         if (dst.value.data == NULL) {
    1225           0 :                 return dst;
    1226             :         }
    1227             : 
    1228   412982283 :         dst.name = talloc_strdup(mem_ctx, src->name);
    1229   412982283 :         if (dst.name == NULL) {
    1230           0 :                 LDB_FREE(dst.value.data);
    1231           0 :                 return dst;
    1232             :         }
    1233             : 
    1234   412982283 :         if (src->cf_value.data) {
    1235   342827467 :                 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
    1236   342827467 :                 if (dst.cf_value.data == NULL) {
    1237           0 :                         LDB_FREE(dst.value.data);
    1238           0 :                         LDB_FREE(dst.name);
    1239           0 :                         return dst;
    1240             :                 }
    1241             : 
    1242   342827467 :                 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
    1243   342827467 :                 if (dst.cf_name == NULL) {
    1244           0 :                         LDB_FREE(dst.cf_name);
    1245           0 :                         LDB_FREE(dst.value.data);
    1246           0 :                         LDB_FREE(dst.name);
    1247           0 :                         return dst;
    1248             :                 }
    1249             :         } else {
    1250    67062705 :                 dst.cf_value.data = NULL;
    1251    67062705 :                 dst.cf_name = NULL;
    1252             :         }
    1253             : 
    1254   412982283 :         return dst;
    1255             : }
    1256             : 
    1257    32052661 : static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
    1258             :                                                 TALLOC_CTX *mem_ctx,
    1259             :                                                 struct ldb_dn_ext_component *src)
    1260             : {
    1261      932129 :         struct ldb_dn_ext_component dst;
    1262             : 
    1263    32052661 :         memset(&dst, 0, sizeof(dst));
    1264             : 
    1265    32052661 :         if (src == NULL) {
    1266           0 :                 return dst;
    1267             :         }
    1268             : 
    1269    32052661 :         dst.value = ldb_val_dup(mem_ctx, &(src->value));
    1270    32052661 :         if (dst.value.data == NULL) {
    1271           0 :                 return dst;
    1272             :         }
    1273             : 
    1274    32052661 :         dst.name = talloc_strdup(mem_ctx, src->name);
    1275    32052661 :         if (dst.name == NULL) {
    1276           0 :                 LDB_FREE(dst.value.data);
    1277           0 :                 return dst;
    1278             :         }
    1279             : 
    1280    32052661 :         return dst;
    1281             : }
    1282             : 
    1283    78886804 : struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1284             : {
    1285     3818534 :         struct ldb_dn *new_dn;
    1286             : 
    1287    78886804 :         if (!dn || dn->invalid) {
    1288           2 :                 return NULL;
    1289             :         }
    1290             : 
    1291    78886802 :         new_dn = talloc_zero(mem_ctx, struct ldb_dn);
    1292    78886802 :         if ( !new_dn) {
    1293           0 :                 return NULL;
    1294             :         }
    1295             : 
    1296    78886802 :         *new_dn = *dn;
    1297             : 
    1298    78886802 :         if (dn->components) {
    1299     3593982 :                 unsigned int i;
    1300             : 
    1301    73845603 :                 new_dn->components =
    1302    70251621 :                         talloc_zero_array(new_dn,
    1303             :                                           struct ldb_dn_component,
    1304             :                                           dn->comp_num);
    1305    70251621 :                 if ( ! new_dn->components) {
    1306           0 :                         talloc_free(new_dn);
    1307           0 :                         return NULL;
    1308             :                 }
    1309             : 
    1310   467532486 :                 for (i = 0; i < dn->comp_num; i++) {
    1311   397280865 :                         new_dn->components[i] =
    1312   397280865 :                                 ldb_dn_copy_component(new_dn->components,
    1313   397280865 :                                                       &dn->components[i]);
    1314   397280865 :                         if ( ! new_dn->components[i].value.data) {
    1315           0 :                                 talloc_free(new_dn);
    1316           0 :                                 return NULL;
    1317             :                         }
    1318             :                 }
    1319             :         }
    1320             : 
    1321    78886802 :         if (dn->ext_components) {
    1322      801495 :                 unsigned int i;
    1323             : 
    1324    25856022 :                 new_dn->ext_components =
    1325    25054527 :                         talloc_zero_array(new_dn,
    1326             :                                           struct ldb_dn_ext_component,
    1327             :                                           dn->ext_comp_num);
    1328    25054527 :                 if ( ! new_dn->ext_components) {
    1329           0 :                         talloc_free(new_dn);
    1330           0 :                         return NULL;
    1331             :                 }
    1332             : 
    1333    57107188 :                 for (i = 0; i < dn->ext_comp_num; i++) {
    1334    32052661 :                         new_dn->ext_components[i] =
    1335    32052661 :                                  ldb_dn_ext_copy_component(
    1336    32052661 :                                                 new_dn->ext_components,
    1337    32052661 :                                                 &dn->ext_components[i]);
    1338    32052661 :                         if ( ! new_dn->ext_components[i].value.data) {
    1339           0 :                                 talloc_free(new_dn);
    1340           0 :                                 return NULL;
    1341             :                         }
    1342             :                 }
    1343             :         }
    1344             : 
    1345    78886802 :         if (dn->casefold) {
    1346    44933998 :                 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
    1347    44933998 :                 if ( ! new_dn->casefold) {
    1348           0 :                         talloc_free(new_dn);
    1349           0 :                         return NULL;
    1350             :                 }
    1351             :         }
    1352             : 
    1353    78886802 :         if (dn->linearized) {
    1354    78741641 :                 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
    1355    78741641 :                 if ( ! new_dn->linearized) {
    1356           0 :                         talloc_free(new_dn);
    1357           0 :                         return NULL;
    1358             :                 }
    1359             :         }
    1360             : 
    1361    78886802 :         if (dn->ext_linearized) {
    1362     2869544 :                 new_dn->ext_linearized = talloc_strdup(new_dn,
    1363     1386343 :                                                         dn->ext_linearized);
    1364     1483201 :                 if ( ! new_dn->ext_linearized) {
    1365           0 :                         talloc_free(new_dn);
    1366           0 :                         return NULL;
    1367             :                 }
    1368             :         }
    1369             : 
    1370    75068268 :         return new_dn;
    1371             : }
    1372             : 
    1373             : /* modify the given dn by adding a base.
    1374             :  *
    1375             :  * return true if successful and false if not
    1376             :  * if false is returned the dn may be marked invalid
    1377             :  */
    1378      626502 : bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
    1379             : {
    1380        4928 :         const char *s;
    1381        4928 :         char *t;
    1382             : 
    1383      626502 :         if ( !base || base->invalid || !dn || dn->invalid) {
    1384           0 :                 return false;
    1385             :         }
    1386             : 
    1387      626502 :         if (dn == base) {
    1388           0 :                 return false; /* or we will visit infinity */
    1389             :         }
    1390             : 
    1391      626502 :         if (dn->components) {
    1392         479 :                 unsigned int i;
    1393             : 
    1394      452499 :                 if ( ! ldb_dn_validate(base)) {
    1395           0 :                         return false;
    1396             :                 }
    1397             : 
    1398      452499 :                 s = NULL;
    1399      452499 :                 if (dn->valid_case) {
    1400           2 :                         if ( ! (s = ldb_dn_get_casefold(base))) {
    1401           0 :                                 return false;
    1402             :                         }
    1403             :                 }
    1404             : 
    1405      452499 :                 dn->components = talloc_realloc(dn,
    1406             :                                                 dn->components,
    1407             :                                                 struct ldb_dn_component,
    1408             :                                                 dn->comp_num + base->comp_num);
    1409      452499 :                 if ( ! dn->components) {
    1410           0 :                         ldb_dn_mark_invalid(dn);
    1411           0 :                         return false;
    1412             :                 }
    1413             : 
    1414     2984063 :                 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
    1415     2531564 :                         dn->components[dn->comp_num] =
    1416     2531564 :                                 ldb_dn_copy_component(dn->components,
    1417     2531564 :                                                         &base->components[i]);
    1418     2531564 :                         if (dn->components[dn->comp_num].value.data == NULL) {
    1419           0 :                                 ldb_dn_mark_invalid(dn);
    1420           0 :                                 return false;
    1421             :                         }
    1422             :                 }
    1423             : 
    1424      452499 :                 if (dn->casefold && s) {
    1425           0 :                         if (*dn->casefold) {
    1426           0 :                                 t = talloc_asprintf(dn, "%s,%s",
    1427             :                                                     dn->casefold, s);
    1428             :                         } else {
    1429           0 :                                 t = talloc_strdup(dn, s);
    1430             :                         }
    1431           0 :                         LDB_FREE(dn->casefold);
    1432           0 :                         dn->casefold = t;
    1433             :                 }
    1434             :         }
    1435             : 
    1436      626502 :         if (dn->linearized) {
    1437             : 
    1438      176642 :                 s = ldb_dn_get_linearized(base);
    1439      176642 :                 if ( ! s) {
    1440           0 :                         return false;
    1441             :                 }
    1442             : 
    1443      176642 :                 if (*dn->linearized) {
    1444       14591 :                         t = talloc_asprintf(dn, "%s,%s",
    1445             :                                             dn->linearized, s);
    1446             :                 } else {
    1447      162051 :                         t = talloc_strdup(dn, s);
    1448             :                 }
    1449      176642 :                 if ( ! t) {
    1450           0 :                         ldb_dn_mark_invalid(dn);
    1451           0 :                         return false;
    1452             :                 }
    1453      176642 :                 LDB_FREE(dn->linearized);
    1454      176642 :                 dn->linearized = t;
    1455             :         }
    1456             : 
    1457             :         /* Wipe the ext_linearized DN,
    1458             :          * the GUID and SID are almost certainly no longer valid */
    1459      626502 :         LDB_FREE(dn->ext_linearized);
    1460      626502 :         LDB_FREE(dn->ext_components);
    1461      626502 :         dn->ext_comp_num = 0;
    1462             : 
    1463      626502 :         return true;
    1464             : }
    1465             : 
    1466             : /* modify the given dn by adding a base.
    1467             :  *
    1468             :  * return true if successful and false if not
    1469             :  * if false is returned the dn may be marked invalid
    1470             :  */
    1471           2 : bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
    1472             : {
    1473           2 :         struct ldb_dn *base;
    1474           2 :         char *base_str;
    1475           2 :         va_list ap;
    1476           2 :         bool ret;
    1477             : 
    1478           2 :         if ( !dn || dn->invalid) {
    1479           0 :                 return false;
    1480             :         }
    1481             : 
    1482           2 :         va_start(ap, base_fmt);
    1483           2 :         base_str = talloc_vasprintf(dn, base_fmt, ap);
    1484           2 :         va_end(ap);
    1485             : 
    1486           2 :         if (base_str == NULL) {
    1487           0 :                 return false;
    1488             :         }
    1489             : 
    1490           2 :         base = ldb_dn_new(base_str, dn->ldb, base_str);
    1491             : 
    1492           2 :         ret = ldb_dn_add_base(dn, base);
    1493             : 
    1494           2 :         talloc_free(base_str);
    1495             : 
    1496           2 :         return ret;
    1497             : }
    1498             : 
    1499             : /* modify the given dn by adding children elements.
    1500             :  *
    1501             :  * return true if successful and false if not
    1502             :  * if false is returned the dn may be marked invalid
    1503             :  */
    1504     6775999 : bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
    1505             : {
    1506      368864 :         const char *s;
    1507      368864 :         char *t;
    1508             : 
    1509     6775999 :         if ( !child || child->invalid || !dn || dn->invalid) {
    1510           0 :                 return false;
    1511             :         }
    1512             : 
    1513     6775999 :         if (dn->components) {
    1514      365173 :                 unsigned int n;
    1515      365173 :                 unsigned int i, j;
    1516             : 
    1517     6535519 :                 if (dn->comp_num == 0) {
    1518           0 :                         return false;
    1519             :                 }
    1520             : 
    1521     6535519 :                 if ( ! ldb_dn_validate(child)) {
    1522           0 :                         return false;
    1523             :                 }
    1524             : 
    1525     6535519 :                 s = NULL;
    1526     6535519 :                 if (dn->valid_case) {
    1527     4655734 :                         if ( ! (s = ldb_dn_get_casefold(child))) {
    1528           0 :                                 return false;
    1529             :                         }
    1530             :                 }
    1531             : 
    1532     6535519 :                 n = dn->comp_num + child->comp_num;
    1533             : 
    1534     6535519 :                 dn->components = talloc_realloc(dn,
    1535             :                                                 dn->components,
    1536             :                                                 struct ldb_dn_component,
    1537             :                                                 n);
    1538     6535519 :                 if ( ! dn->components) {
    1539           0 :                         ldb_dn_mark_invalid(dn);
    1540           0 :                         return false;
    1541             :                 }
    1542             : 
    1543    35289052 :                 for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1;
    1544    28753533 :                      i--, j--) {
    1545    28753533 :                         dn->components[j] = dn->components[i];
    1546             :                 }
    1547             : 
    1548    19089925 :                 for (i = 0; i < child->comp_num; i++) {
    1549    12554406 :                         dn->components[i] =
    1550    12554406 :                                 ldb_dn_copy_component(dn->components,
    1551    12554406 :                                                         &child->components[i]);
    1552    12554406 :                         if (dn->components[i].value.data == NULL) {
    1553           0 :                                 ldb_dn_mark_invalid(dn);
    1554           0 :                                 return false;
    1555             :                         }
    1556             :                 }
    1557             : 
    1558     6535519 :                 dn->comp_num = n;
    1559             : 
    1560     6535519 :                 if (dn->casefold && s) {
    1561     3393821 :                         t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
    1562     3393821 :                         LDB_FREE(dn->casefold);
    1563     3393821 :                         dn->casefold = t;
    1564             :                 }
    1565             :         }
    1566             : 
    1567     6775999 :         if (dn->linearized) {
    1568     6768915 :                 if (dn->linearized[0] == '\0') {
    1569           0 :                         return false;
    1570             :                 }
    1571             : 
    1572     6768914 :                 s = ldb_dn_get_linearized(child);
    1573     6768914 :                 if ( ! s) {
    1574           0 :                         return false;
    1575             :                 }
    1576             : 
    1577     6768914 :                 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
    1578     6768914 :                 if ( ! t) {
    1579           0 :                         ldb_dn_mark_invalid(dn);
    1580           0 :                         return false;
    1581             :                 }
    1582     6768914 :                 LDB_FREE(dn->linearized);
    1583     6768914 :                 dn->linearized = t;
    1584             :         }
    1585             : 
    1586             :         /* Wipe the ext_linearized DN,
    1587             :          * the GUID and SID are almost certainly no longer valid */
    1588     6775998 :         LDB_FREE(dn->ext_linearized);
    1589     6775998 :         LDB_FREE(dn->ext_components);
    1590     6775998 :         dn->ext_comp_num = 0;
    1591             : 
    1592     6775998 :         return true;
    1593             : }
    1594             : 
    1595             : /* modify the given dn by adding children elements.
    1596             :  *
    1597             :  * return true if successful and false if not
    1598             :  * if false is returned the dn may be marked invalid
    1599             :  */
    1600     6580769 : bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
    1601             : {
    1602      367516 :         struct ldb_dn *child;
    1603      367516 :         char *child_str;
    1604      367516 :         va_list ap;
    1605      367516 :         bool ret;
    1606             : 
    1607     6580769 :         if ( !dn || dn->invalid) {
    1608           0 :                 return false;
    1609             :         }
    1610             : 
    1611     6580769 :         va_start(ap, child_fmt);
    1612     6580769 :         child_str = talloc_vasprintf(dn, child_fmt, ap);
    1613     6580769 :         va_end(ap);
    1614             : 
    1615     6580769 :         if (child_str == NULL) {
    1616           0 :                 return false;
    1617             :         }
    1618             : 
    1619     6580769 :         child = ldb_dn_new(child_str, dn->ldb, child_str);
    1620             : 
    1621     6580769 :         ret = ldb_dn_add_child(dn, child);
    1622             : 
    1623     6580769 :         talloc_free(child_str);
    1624             : 
    1625     6580769 :         return ret;
    1626             : }
    1627             : 
    1628             : /* modify the given dn by adding a single child element.
    1629             :  *
    1630             :  * return true if successful and false if not
    1631             :  * if false is returned the dn may be marked invalid
    1632             :  */
    1633       25072 : bool ldb_dn_add_child_val(struct ldb_dn *dn,
    1634             :                           const char *rdn,
    1635             :                           struct ldb_val value)
    1636             : {
    1637          10 :         bool ret;
    1638          10 :         int ldb_ret;
    1639       25072 :         struct ldb_dn *child = NULL;
    1640             : 
    1641       25072 :         if ( !dn || dn->invalid) {
    1642           0 :                 return false;
    1643             :         }
    1644             : 
    1645       25072 :         child = ldb_dn_new(dn, dn->ldb, "X=Y");
    1646       25072 :         ret = ldb_dn_add_child(dn, child);
    1647             : 
    1648       25072 :         if (ret == false) {
    1649           0 :                 return false;
    1650             :         }
    1651             : 
    1652       25072 :         ldb_ret = ldb_dn_set_component(dn,
    1653             :                                        0,
    1654             :                                        rdn,
    1655             :                                        value);
    1656       25072 :         if (ldb_ret != LDB_SUCCESS) {
    1657           0 :                 return false;
    1658             :         }
    1659             : 
    1660       25062 :         return true;
    1661             : }
    1662             : 
    1663      595616 : bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
    1664             : {
    1665         454 :         unsigned int i;
    1666             : 
    1667      595616 :         if ( ! ldb_dn_validate(dn)) {
    1668           0 :                 return false;
    1669             :         }
    1670             : 
    1671      595616 :         if (dn->comp_num < num) {
    1672           0 :                 return false;
    1673             :         }
    1674             : 
    1675             :         /* free components */
    1676     3797809 :         for (i = dn->comp_num - num; i < dn->comp_num; i++) {
    1677     3202193 :                 LDB_FREE(dn->components[i].name);
    1678     3202193 :                 LDB_FREE(dn->components[i].value.data);
    1679     3202193 :                 LDB_FREE(dn->components[i].cf_name);
    1680     3202193 :                 LDB_FREE(dn->components[i].cf_value.data);
    1681             :         }
    1682             : 
    1683      595616 :         dn->comp_num -= num;
    1684             : 
    1685      595616 :         if (dn->valid_case) {
    1686      292127 :                 for (i = 0; i < dn->comp_num; i++) {
    1687      146057 :                         LDB_FREE(dn->components[i].cf_name);
    1688      146057 :                         LDB_FREE(dn->components[i].cf_value.data);
    1689             :                 }
    1690      146070 :                 dn->valid_case = false;
    1691             :         }
    1692             : 
    1693      595616 :         LDB_FREE(dn->casefold);
    1694      595616 :         LDB_FREE(dn->linearized);
    1695             : 
    1696             :         /* Wipe the ext_linearized DN,
    1697             :          * the GUID and SID are almost certainly no longer valid */
    1698      595616 :         LDB_FREE(dn->ext_linearized);
    1699      595616 :         LDB_FREE(dn->ext_components);
    1700      595616 :         dn->ext_comp_num = 0;
    1701             : 
    1702      595616 :         return true;
    1703             : }
    1704             : 
    1705    13025798 : bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
    1706             : {
    1707      783571 :         unsigned int i, j;
    1708             : 
    1709    13025798 :         if ( ! ldb_dn_validate(dn)) {
    1710           0 :                 return false;
    1711             :         }
    1712             : 
    1713    13025798 :         if (dn->comp_num < num) {
    1714           1 :                 return false;
    1715             :         }
    1716             : 
    1717    84182776 :         for (i = 0, j = num; j < dn->comp_num; i++, j++) {
    1718    71156979 :                 if (i < num) {
    1719    13024499 :                         LDB_FREE(dn->components[i].name);
    1720    13024499 :                         LDB_FREE(dn->components[i].value.data);
    1721    13024499 :                         LDB_FREE(dn->components[i].cf_name);
    1722    13024499 :                         LDB_FREE(dn->components[i].cf_value.data);
    1723             :                 }
    1724    71156979 :                 dn->components[i] = dn->components[j];
    1725             :         }
    1726             : 
    1727    13025797 :         dn->comp_num -= num;
    1728             : 
    1729    13025797 :         if (dn->valid_case) {
    1730    61298734 :                 for (i = 0; i < dn->comp_num; i++) {
    1731    51825385 :                         LDB_FREE(dn->components[i].cf_name);
    1732    51825385 :                         LDB_FREE(dn->components[i].cf_value.data);
    1733             :                 }
    1734     9473349 :                 dn->valid_case = false;
    1735             :         }
    1736             : 
    1737    13025797 :         LDB_FREE(dn->casefold);
    1738    13025797 :         LDB_FREE(dn->linearized);
    1739             : 
    1740             :         /* Wipe the ext_linearized DN,
    1741             :          * the GUID and SID are almost certainly no longer valid */
    1742    13025797 :         LDB_FREE(dn->ext_linearized);
    1743    13025797 :         LDB_FREE(dn->ext_components);
    1744    13025797 :         dn->ext_comp_num = 0;
    1745             : 
    1746    13025797 :         return true;
    1747             : }
    1748             : 
    1749             : 
    1750             : /* replace the components of a DN with those from another DN, without
    1751             :  * touching the extended components
    1752             :  *
    1753             :  * return true if successful and false if not
    1754             :  * if false is returned the dn may be marked invalid
    1755             :  */
    1756      126081 : bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn)
    1757             : {
    1758        1705 :         unsigned int i;
    1759             : 
    1760      126081 :         if ( ! ldb_dn_validate(dn) || ! ldb_dn_validate(new_dn)) {
    1761           0 :                 return false;
    1762             :         }
    1763             : 
    1764             :         /* free components */
    1765      859803 :         for (i = 0; i < dn->comp_num; i++) {
    1766      733722 :                 LDB_FREE(dn->components[i].name);
    1767      733722 :                 LDB_FREE(dn->components[i].value.data);
    1768      733722 :                 LDB_FREE(dn->components[i].cf_name);
    1769      733722 :                 LDB_FREE(dn->components[i].cf_value.data);
    1770             :         }
    1771             : 
    1772      126081 :         dn->components = talloc_realloc(dn,
    1773             :                                         dn->components,
    1774             :                                         struct ldb_dn_component,
    1775             :                                         new_dn->comp_num);
    1776      126081 :         if (dn->components == NULL) {
    1777           0 :                 ldb_dn_mark_invalid(dn);
    1778           0 :                 return false;
    1779             :         }
    1780             : 
    1781      126081 :         dn->comp_num = new_dn->comp_num;
    1782      126081 :         dn->valid_case = new_dn->valid_case;
    1783             : 
    1784      741529 :         for (i = 0; i < dn->comp_num; i++) {
    1785      615448 :                 dn->components[i] = ldb_dn_copy_component(dn->components, &new_dn->components[i]);
    1786      615448 :                 if (dn->components[i].name == NULL) {
    1787           0 :                         ldb_dn_mark_invalid(dn);
    1788           0 :                         return false;
    1789             :                 }
    1790             :         }
    1791      126081 :         if (new_dn->linearized == NULL) {
    1792           0 :                 dn->linearized = NULL;
    1793             :         } else {
    1794      126081 :                 dn->linearized = talloc_strdup(dn, new_dn->linearized);
    1795      126081 :                 if (dn->linearized == NULL) {
    1796           0 :                         ldb_dn_mark_invalid(dn);
    1797           0 :                         return false;
    1798             :                 }
    1799             :         }
    1800             : 
    1801      124376 :         return true;
    1802             : }
    1803             : 
    1804             : 
    1805    13021551 : struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1806             : {
    1807      783541 :         struct ldb_dn *new_dn;
    1808             : 
    1809    13021551 :         new_dn = ldb_dn_copy(mem_ctx, dn);
    1810    13021551 :         if ( !new_dn ) {
    1811           2 :                 return NULL;
    1812             :         }
    1813             : 
    1814    13021549 :         if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
    1815           1 :                 talloc_free(new_dn);
    1816           1 :                 return NULL;
    1817             :         }
    1818             : 
    1819    12238007 :         return new_dn;
    1820             : }
    1821             : 
    1822             : /* Create a 'canonical name' string from a DN:
    1823             : 
    1824             :    ie dc=samba,dc=org -> samba.org/
    1825             :       uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
    1826             : 
    1827             :    There are two formats,
    1828             :    the EX format has the last '/' replaced with a newline (\n).
    1829             : 
    1830             : */
    1831     2645904 : static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) {
    1832      151974 :         unsigned int i;
    1833      151974 :         TALLOC_CTX *tmpctx;
    1834     2645904 :         char *cracked = NULL;
    1835     2645904 :         const char *format = (ex_format ? "\n" : "/" );
    1836             : 
    1837     2645904 :         if ( ! ldb_dn_validate(dn)) {
    1838           0 :                 return NULL;
    1839             :         }
    1840             : 
    1841     2645904 :         tmpctx = talloc_new(mem_ctx);
    1842             : 
    1843             :         /* Walk backwards down the DN, grabbing 'dc' components at first */
    1844    11483242 :         for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) {
    1845    11182271 :                 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
    1846     2201990 :                         break;
    1847             :                 }
    1848     8837338 :                 if (cracked) {
    1849     6191572 :                         cracked = talloc_asprintf(tmpctx, "%s.%s",
    1850             :                                                   ldb_dn_escape_value(tmpctx,
    1851     5865848 :                                                         dn->components[i].value),
    1852             :                                                   cracked);
    1853             :                 } else {
    1854     2645766 :                         cracked = ldb_dn_escape_value(tmpctx,
    1855     2493926 :                                                         dn->components[i].value);
    1856             :                 }
    1857     8837338 :                 if (!cracked) {
    1858           0 :                         goto done;
    1859             :                 }
    1860             :         }
    1861             : 
    1862             :         /* Only domain components?  Finish here */
    1863     2645904 :         if (i == (unsigned int) -1) {
    1864      300971 :                 cracked = talloc_strdup_append_buffer(cracked, format);
    1865      300971 :                 talloc_steal(mem_ctx, cracked);
    1866      300971 :                 goto done;
    1867             :         }
    1868             : 
    1869             :         /* Now walk backwards appending remaining components */
    1870     6459284 :         for (; i > 0; i--) {
    1871     4114351 :                 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
    1872             :                                                         ldb_dn_escape_value(tmpctx,
    1873     4114351 :                                                         dn->components[i].value));
    1874     4114351 :                 if (!cracked) {
    1875           0 :                         goto done;
    1876             :                 }
    1877             :         }
    1878             : 
    1879             :         /* Last one, possibly a newline for the 'ex' format */
    1880     2344933 :         cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
    1881             :                                                 ldb_dn_escape_value(tmpctx,
    1882     2344933 :                                                         dn->components[i].value));
    1883             : 
    1884     2344933 :         talloc_steal(mem_ctx, cracked);
    1885     2645904 : done:
    1886     2645904 :         talloc_free(tmpctx);
    1887     2645904 :         return cracked;
    1888             : }
    1889             : 
    1890             : /* Wrapper functions for the above, for the two different string formats */
    1891     2645641 : char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
    1892     2645641 :         return ldb_dn_canonical(mem_ctx, dn, 0);
    1893             : 
    1894             : }
    1895             : 
    1896         263 : char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
    1897         263 :         return ldb_dn_canonical(mem_ctx, dn, 1);
    1898             : }
    1899             : 
    1900    26205658 : int ldb_dn_get_comp_num(struct ldb_dn *dn)
    1901             : {
    1902    26205658 :         if ( ! ldb_dn_validate(dn)) {
    1903         178 :                 return -1;
    1904             :         }
    1905    26205476 :         return dn->comp_num;
    1906             : }
    1907             : 
    1908    14731981 : int ldb_dn_get_extended_comp_num(struct ldb_dn *dn)
    1909             : {
    1910    14731981 :         if ( ! ldb_dn_validate(dn)) {
    1911         178 :                 return -1;
    1912             :         }
    1913    14731799 :         return dn->ext_comp_num;
    1914             : }
    1915             : 
    1916        9145 : const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
    1917             : {
    1918        9145 :         if ( ! ldb_dn_validate(dn)) {
    1919           0 :                 return NULL;
    1920             :         }
    1921        9145 :         if (num >= dn->comp_num) return NULL;
    1922        9137 :         return dn->components[num].name;
    1923             : }
    1924             : 
    1925      598482 : const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
    1926             :                                                 unsigned int num)
    1927             : {
    1928      598482 :         if ( ! ldb_dn_validate(dn)) {
    1929           0 :                 return NULL;
    1930             :         }
    1931      598482 :         if (num >= dn->comp_num) return NULL;
    1932      598482 :         return &dn->components[num].value;
    1933             : }
    1934             : 
    1935    70399952 : const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
    1936             : {
    1937    70399952 :         if ( ! ldb_dn_validate(dn)) {
    1938           0 :                 return NULL;
    1939             :         }
    1940    70399952 :         if (dn->comp_num == 0) return NULL;
    1941    56537427 :         return dn->components[0].name;
    1942             : }
    1943             : 
    1944    56142526 : const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
    1945             : {
    1946    56142526 :         if ( ! ldb_dn_validate(dn)) {
    1947           2 :                 return NULL;
    1948             :         }
    1949    56142524 :         if (dn->comp_num == 0) return NULL;
    1950    42279999 :         return &dn->components[0].value;
    1951             : }
    1952             : 
    1953     1226928 : int ldb_dn_set_component(struct ldb_dn *dn, int num,
    1954             :                          const char *name, const struct ldb_val val)
    1955             : {
    1956      156832 :         char *n;
    1957      156832 :         struct ldb_val v;
    1958             : 
    1959     1226928 :         if ( ! ldb_dn_validate(dn)) {
    1960           0 :                 return LDB_ERR_OTHER;
    1961             :         }
    1962             : 
    1963     1226928 :         if (num < 0) {
    1964           0 :                 return LDB_ERR_OTHER;
    1965             :         }
    1966             : 
    1967     1226928 :         if ((unsigned)num >= dn->comp_num) {
    1968           2 :                 return LDB_ERR_OTHER;
    1969             :         }
    1970             : 
    1971     1226926 :         if (val.length > val.length + 1) {
    1972           0 :                 return LDB_ERR_OTHER;
    1973             :         }
    1974             : 
    1975     1226926 :         n = talloc_strdup(dn, name);
    1976     1226926 :         if ( ! n) {
    1977           0 :                 return LDB_ERR_OTHER;
    1978             :         }
    1979             : 
    1980     1226926 :         v.length = val.length;
    1981             : 
    1982             :         /*
    1983             :          * This is like talloc_memdup(dn, v.data, v.length + 1), but
    1984             :          * avoids the over-read
    1985             :          */
    1986     1226926 :         v.data = (uint8_t *)talloc_size(dn, v.length+1);
    1987     1226926 :         if ( ! v.data) {
    1988           0 :                 talloc_free(n);
    1989           0 :                 return LDB_ERR_OTHER;
    1990             :         }
    1991     1226926 :         memcpy(v.data, val.data, val.length);
    1992             : 
    1993             :         /*
    1994             :          * Enforce NUL termination outside the stated length, as is
    1995             :          * traditional in LDB
    1996             :          */
    1997     1226926 :         v.data[v.length] = '\0';
    1998             : 
    1999     1226926 :         talloc_free(dn->components[num].name);
    2000     1226926 :         talloc_free(dn->components[num].value.data);
    2001     1226926 :         dn->components[num].name = n;
    2002     1226926 :         dn->components[num].value = v;
    2003             : 
    2004     1226926 :         if (dn->valid_case) {
    2005             :                 unsigned int i;
    2006     4941895 :                 for (i = 0; i < dn->comp_num; i++) {
    2007     4270230 :                         LDB_FREE(dn->components[i].cf_name);
    2008     4270230 :                         LDB_FREE(dn->components[i].cf_value.data);
    2009             :                 }
    2010      671665 :                 dn->valid_case = false;
    2011             :         }
    2012     1226926 :         LDB_FREE(dn->casefold);
    2013     1226926 :         LDB_FREE(dn->linearized);
    2014             : 
    2015             :         /* Wipe the ext_linearized DN,
    2016             :          * the GUID and SID are almost certainly no longer valid */
    2017     1226926 :         LDB_FREE(dn->ext_linearized);
    2018     1226926 :         LDB_FREE(dn->ext_components);
    2019     1226926 :         dn->ext_comp_num = 0;
    2020             : 
    2021     1226926 :         return LDB_SUCCESS;
    2022             : }
    2023             : 
    2024   256777288 : const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
    2025             :                                                     const char *name)
    2026             : {
    2027     6786727 :         unsigned int i;
    2028   256777288 :         if ( ! ldb_dn_validate(dn)) {
    2029         718 :                 return NULL;
    2030             :         }
    2031   321520615 :         for (i=0; i < dn->ext_comp_num; i++) {
    2032   128384076 :                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
    2033    63640031 :                         return &dn->ext_components[i].value;
    2034             :                 }
    2035             :         }
    2036   188010660 :         return NULL;
    2037             : }
    2038             : 
    2039   156936032 : int ldb_dn_set_extended_component(struct ldb_dn *dn,
    2040             :                                   const char *name, const struct ldb_val *val)
    2041             : {
    2042     3714430 :         struct ldb_dn_ext_component *p;
    2043     3714430 :         unsigned int i;
    2044     3714430 :         struct ldb_val v2;
    2045     3714430 :         const struct ldb_dn_extended_syntax *ext_syntax;
    2046             :         
    2047   156936032 :         if ( ! ldb_dn_validate(dn)) {
    2048           0 :                 return LDB_ERR_OTHER;
    2049             :         }
    2050             : 
    2051   156936032 :         ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
    2052   156936032 :         if (ext_syntax == NULL) {
    2053             :                 /* We don't know how to handle this type of thing */
    2054           0 :                 return LDB_ERR_INVALID_DN_SYNTAX;
    2055             :         }
    2056             : 
    2057   248718492 :         for (i=0; i < dn->ext_comp_num; i++) {
    2058    91793196 :                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
    2059       10736 :                         if (val) {
    2060       10736 :                                 dn->ext_components[i].value =
    2061       10736 :                                         ldb_val_dup(dn->ext_components, val);
    2062             : 
    2063       10736 :                                 dn->ext_components[i].name = ext_syntax->name;
    2064       10736 :                                 if (!dn->ext_components[i].value.data) {
    2065           0 :                                         ldb_dn_mark_invalid(dn);
    2066           0 :                                         return LDB_ERR_OPERATIONS_ERROR;
    2067             :                                 }
    2068             :                         } else {
    2069           0 :                                 ARRAY_DEL_ELEMENT(
    2070             :                                         dn->ext_components,
    2071             :                                         i,
    2072           0 :                                         dn->ext_comp_num);
    2073           0 :                                 dn->ext_comp_num--;
    2074             : 
    2075           0 :                                 dn->ext_components = talloc_realloc(dn,
    2076             :                                                    dn->ext_components,
    2077             :                                                    struct ldb_dn_ext_component,
    2078             :                                                    dn->ext_comp_num);
    2079           0 :                                 if (!dn->ext_components) {
    2080           0 :                                         ldb_dn_mark_invalid(dn);
    2081           0 :                                         return LDB_ERR_OPERATIONS_ERROR;
    2082             :                                 }
    2083             :                         }
    2084       10736 :                         LDB_FREE(dn->ext_linearized);
    2085             : 
    2086       10736 :                         return LDB_SUCCESS;
    2087             :                 }
    2088             :         }
    2089             : 
    2090   156925296 :         if (val == NULL) {
    2091             :                 /* removing a value that doesn't exist is not an error */
    2092           0 :                 return LDB_SUCCESS;
    2093             :         }
    2094             : 
    2095   156925296 :         v2 = *val;
    2096             : 
    2097   160639666 :         p = dn->ext_components
    2098   156925296 :                 = talloc_realloc(dn,
    2099             :                                  dn->ext_components,
    2100             :                                  struct ldb_dn_ext_component,
    2101             :                                  dn->ext_comp_num + 1);
    2102   156925296 :         if (!dn->ext_components) {
    2103           0 :                 ldb_dn_mark_invalid(dn);
    2104           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2105             :         }
    2106             : 
    2107   156925296 :         p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2);
    2108   156925296 :         p[dn->ext_comp_num].name = talloc_strdup(p, name);
    2109             : 
    2110   156925296 :         if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
    2111           0 :                 ldb_dn_mark_invalid(dn);
    2112           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2113             :         }
    2114   156925296 :         dn->ext_components = p;
    2115   156925296 :         dn->ext_comp_num++;
    2116             : 
    2117   156925296 :         LDB_FREE(dn->ext_linearized);
    2118             : 
    2119   153210926 :         return LDB_SUCCESS;
    2120             : }
    2121             : 
    2122    45941793 : void ldb_dn_remove_extended_components(struct ldb_dn *dn)
    2123             : {
    2124    45941793 :         LDB_FREE(dn->ext_linearized);
    2125    45941793 :         LDB_FREE(dn->ext_components);
    2126    45941793 :         dn->ext_comp_num = 0;
    2127    45941793 : }
    2128             : 
    2129        4504 : bool ldb_dn_is_valid(struct ldb_dn *dn)
    2130             : {
    2131        4504 :         if ( ! dn) return false;
    2132        4504 :         return ! dn->invalid;
    2133             : }
    2134             : 
    2135  1855334201 : bool ldb_dn_is_special(struct ldb_dn *dn)
    2136             : {
    2137  1855334201 :         if ( ! dn || dn->invalid) return false;
    2138  1855334200 :         return dn->special;
    2139             : }
    2140             : 
    2141   459880983 : bool ldb_dn_has_extended(struct ldb_dn *dn)
    2142             : {
    2143   459880983 :         if ( ! dn || dn->invalid) return false;
    2144   459880983 :         if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
    2145   445155395 :         return dn->ext_comp_num != 0;
    2146             : }
    2147             : 
    2148    15682110 : bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
    2149             : {
    2150    15682110 :         if ( ! dn || dn->invalid) return false;
    2151    15682110 :         return ! strcmp(dn->linearized, check);
    2152             : }
    2153             : 
    2154   396417950 : bool ldb_dn_is_null(struct ldb_dn *dn)
    2155             : {
    2156   396417950 :         if ( ! dn || dn->invalid) return false;
    2157   396417950 :         if (ldb_dn_has_extended(dn)) return false;
    2158   343986815 :         if (dn->linearized && (dn->linearized[0] == '\0')) return true;
    2159   307050221 :         return false;
    2160             : }
    2161             : 
    2162             : /*
    2163             :   this updates dn->components, taking the components from ref_dn.
    2164             :   This is used by code that wants to update the DN path of a DN
    2165             :   while not impacting on the extended DN components
    2166             :  */
    2167       10895 : int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn)
    2168             : {
    2169       10895 :         dn->components = talloc_realloc(dn, dn->components,
    2170             :                                         struct ldb_dn_component, ref_dn->comp_num);
    2171       10895 :         if (!dn->components) {
    2172           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2173             :         }
    2174       10895 :         memcpy(dn->components, ref_dn->components,
    2175       10895 :                sizeof(struct ldb_dn_component)*ref_dn->comp_num);
    2176       10895 :         dn->comp_num = ref_dn->comp_num;
    2177             : 
    2178       10895 :         LDB_FREE(dn->casefold);
    2179       10895 :         LDB_FREE(dn->linearized);
    2180       10895 :         LDB_FREE(dn->ext_linearized);
    2181             : 
    2182       10842 :         return LDB_SUCCESS;
    2183             : }
    2184             : 
    2185             : /*
    2186             :   minimise a DN. The caller must pass in a validated DN.
    2187             : 
    2188             :   If the DN has an extended component then only the first extended
    2189             :   component is kept, the DN string is stripped.
    2190             : 
    2191             :   The existing dn is modified
    2192             :  */
    2193     8076345 : bool ldb_dn_minimise(struct ldb_dn *dn)
    2194             : {
    2195      291242 :         unsigned int i;
    2196             : 
    2197     8076345 :         if (!ldb_dn_validate(dn)) {
    2198           0 :                 return false;
    2199             :         }
    2200     8076345 :         if (dn->ext_comp_num == 0) {
    2201           0 :                 return true;
    2202             :         }
    2203             : 
    2204             :         /* free components */
    2205    41263283 :         for (i = 0; i < dn->comp_num; i++) {
    2206    33186938 :                 LDB_FREE(dn->components[i].name);
    2207    33186938 :                 LDB_FREE(dn->components[i].value.data);
    2208    33186938 :                 LDB_FREE(dn->components[i].cf_name);
    2209    33186938 :                 LDB_FREE(dn->components[i].cf_value.data);
    2210             :         }
    2211     8076345 :         dn->comp_num = 0;
    2212     8076345 :         dn->valid_case = false;
    2213             : 
    2214     8076345 :         LDB_FREE(dn->casefold);
    2215     8076345 :         LDB_FREE(dn->linearized);
    2216             : 
    2217             :         /* note that we don't free dn->components as this there are
    2218             :          * several places in ldb_dn.c that rely on it being non-NULL
    2219             :          * for an exploded DN
    2220             :          */
    2221             : 
    2222    11512606 :         for (i = 1; i < dn->ext_comp_num; i++) {
    2223     3436261 :                 LDB_FREE(dn->ext_components[i].value.data);
    2224             :         }
    2225     8076345 :         dn->ext_comp_num = 1;
    2226             : 
    2227     8076345 :         dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1);
    2228     8076345 :         if (dn->ext_components == NULL) {
    2229           0 :                 ldb_dn_mark_invalid(dn);
    2230           0 :                 return false;
    2231             :         }
    2232             : 
    2233     8076345 :         LDB_FREE(dn->ext_linearized);
    2234             : 
    2235     7785103 :         return true;
    2236             : }
    2237             : 
    2238   155971152 : struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn)
    2239             : {
    2240   155971152 :         return dn->ldb;
    2241             : }

Generated by: LCOV version 1.14