LCOV - code coverage report
Current view: top level - lib/ldb/common - ldb_dn.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 946 1150 82.3 %
Date: 2024-05-31 13:13:24 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       19941 : static void ldb_dn_mark_invalid(struct ldb_dn *dn)
      84             : {
      85       19941 :         dn->invalid = true;
      86       19922 : }
      87             : 
      88             : /* strdn may be NULL */
      89   922753678 : 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    25414793 :         struct ldb_dn *dn;
      94             : 
      95   922753678 :         if (ldb == NULL || strdn == NULL) {
      96           0 :                 return NULL;
      97             :         }
      98   922753678 :         if (strdn->data
      99   893072666 :             && (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   922753675 :         dn = talloc_zero(mem_ctx, struct ldb_dn);
     105   922753675 :         LDB_DN_NULL_FAILED(dn);
     106             : 
     107   922753675 :         dn->ldb = talloc_get_type(ldb, struct ldb_context);
     108   922753675 :         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  1790099454 :         if (strdn->data && strdn->length) {
     116   892151654 :                 const char *data = (const char *)strdn->data;
     117   892151654 :                 size_t length = strdn->length;
     118             : 
     119   892151654 :                 if (data[0] == '@') {
     120   416771926 :                         dn->special = true;
     121             :                 }
     122   892151654 :                 dn->ext_linearized = talloc_strndup(dn, data, length);
     123   892151654 :                 LDB_DN_NULL_FAILED(dn->ext_linearized);
     124             : 
     125   892151654 :                 if (data[0] == '<') {
     126    42674878 :                         const char *p_save, *p = dn->ext_linearized;
     127     2343850 :                         do {
     128   123514860 :                                 p_save = p;
     129   123514860 :                                 p = strstr(p, ">;");
     130   123514860 :                                 if (p) {
     131    79717391 :                                         p = p + 2;
     132             :                                 }
     133   123514860 :                         } while (p);
     134             : 
     135    43797469 :                         if (p_save == dn->ext_linearized) {
     136     8511344 :                                 dn->linearized = talloc_strdup(dn, "");
     137             :                         } else {
     138    35286125 :                                 dn->linearized = talloc_strdup(dn, p_save);
     139             :                         }
     140    43797469 :                         LDB_DN_NULL_FAILED(dn->linearized);
     141             :                 } else {
     142   848354185 :                         dn->linearized = dn->ext_linearized;
     143   848354185 :                         dn->ext_linearized = NULL;
     144             :                 }
     145             :         } else {
     146    30602021 :                 dn->linearized = talloc_strdup(dn, "");
     147    30602021 :                 LDB_DN_NULL_FAILED(dn->linearized);
     148             :         }
     149             : 
     150   897338885 :         return dn;
     151             : 
     152           0 : failed:
     153           0 :         talloc_free(dn);
     154           0 :         return NULL;
     155             : }
     156             : 
     157             : /* strdn may be NULL */
     158   347363018 : struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx,
     159             :                           struct ldb_context *ldb,
     160             :                           const char *strdn)
     161             : {
     162    11391148 :         struct ldb_val blob;
     163   347363018 :         blob.data = discard_const_p(uint8_t, strdn);
     164   347363018 :         blob.length = strdn ? strlen(strdn) : 0;
     165   347363018 :         return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
     166             : }
     167             : 
     168   202899022 : struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx,
     169             :                               struct ldb_context *ldb,
     170             :                               const char *new_fmt, ...)
     171             : {
     172     6638984 :         char *strdn;
     173     6638984 :         va_list ap;
     174             : 
     175   202899022 :         if (! ldb) return NULL;
     176             : 
     177   202899022 :         va_start(ap, new_fmt);
     178   202899022 :         strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
     179   202899022 :         va_end(ap);
     180             : 
     181   202899022 :         if (strdn) {
     182   202899022 :                 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
     183   202899022 :                 talloc_free(strdn);
     184   202899022 :                 return dn;
     185             :         }
     186             : 
     187           0 :         return NULL;
     188             : }
     189             : 
     190             : /* see RFC2253 section 2.4 */
     191   234214531 : static int ldb_dn_escape_internal(char *dst, const char *src, int len)
     192             : {
     193    14394149 :         char c;
     194    14394149 :         char *d;
     195    14394149 :         int i;
     196   234214531 :         d = dst;
     197             : 
     198  2249262617 :         for (i = 0; i < len; i++){
     199  2015048086 :                 c = src[i];
     200  2015048086 :                 switch (c) {
     201    14973277 :                 case ' ':
     202    14973277 :                         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    14973277 :                                 *d++ = c;
     210             :                         }
     211    14038723 :                         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     1726428 :                 case ';':
     229             :                 case '\r':
     230             :                 case '\n':
     231             :                 case '=':
     232             :                 case '\0': {
     233             :                         /* any others get \XX form */
     234         927 :                         unsigned char v;
     235     1726428 :                         const char *hexbytes = "0123456789ABCDEF";
     236     1726428 :                         v = (const unsigned char)c;
     237     1726428 :                         *d++ = '\\';
     238     1726428 :                         *d++ = hexbytes[v>>4];
     239     1726428 :                         *d++ = hexbytes[v&0xF];
     240     1726428 :                         break;
     241             :                 }
     242  1998311294 :                 default:
     243  1998311294 :                         *d++ = c;
     244             :                 }
     245             :         }
     246             : 
     247             :         /* return the length of the resulting string */
     248   234214531 :         return (d - dst);
     249             : }
     250             : 
     251    15663463 : char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value)
     252             : {
     253      958552 :         char *dst;
     254      958552 :         size_t len;
     255    15663463 :         if (!value.length)
     256           2 :                 return NULL;
     257             : 
     258             :         /* allocate destination string, it will be at most 3 times the source */
     259    15663461 :         dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
     260    15663461 :         if ( ! dst) {
     261           0 :                 talloc_free(dst);
     262           0 :                 return NULL;
     263             :         }
     264             : 
     265    15663461 :         len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
     266             : 
     267    15663461 :         dst = talloc_realloc(mem_ctx, dst, char, len + 1);
     268    15663461 :         if ( ! dst) {
     269           0 :                 talloc_free(dst);
     270           0 :                 return NULL;
     271             :         }
     272    15663461 :         dst[len] = '\0';
     273    15663461 :         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  1238214336 : static bool ldb_dn_explode(struct ldb_dn *dn)
     284             : {
     285  1238214336 :         char *p, *ex_name = NULL, *ex_value = NULL, *data, *d, *dt, *t;
     286  1238214336 :         bool trim = true;
     287  1238214336 :         bool in_extended = true;
     288  1238214336 :         bool in_ex_name = false;
     289  1238214336 :         bool in_ex_value = false;
     290  1238214336 :         bool in_attr = false;
     291  1238214336 :         bool in_value = false;
     292  1238214336 :         bool in_quote = false;
     293  1238214336 :         bool is_oid = false;
     294  1238214336 :         bool escape = false;
     295    36439565 :         unsigned int x;
     296  1238214336 :         size_t l = 0;
     297    36439565 :         int ret;
     298    36439565 :         char *parse_dn;
     299    36439565 :         bool is_index;
     300             : 
     301  1238214336 :         if (dn == NULL || dn->invalid) {
     302         710 :                 return false;
     303             :         }
     304             : 
     305  1238213621 :         if (dn->components != NULL) {
     306   647423734 :                 return true;
     307             :         }
     308             : 
     309   568179146 :         if (dn->ext_linearized != NULL) {
     310    39180303 :                 parse_dn = dn->ext_linearized;
     311             :         } else {
     312   528125575 :                 parse_dn = dn->linearized;
     313             :         }
     314             : 
     315   568179146 :         if (parse_dn == NULL) {
     316           0 :                 return false;
     317             :         }
     318             : 
     319   568179146 :         is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
     320             : 
     321             :         /* Empty DNs */
     322   568179146 :         if (parse_dn[0] == '\0') {
     323    30675043 :                 return true;
     324             :         }
     325             : 
     326             :         /* Special DNs case */
     327   536575852 :         if (dn->special) {
     328   259269815 :                 return true;
     329             :         }
     330             : 
     331   269488178 :         LDB_FREE(dn->ext_components);
     332   269488178 :         dn->ext_comp_num = 0;
     333   269488178 :         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   269488178 :         dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
     338   269488178 :         if (dn->components == NULL) {
     339           0 :                 return false;
     340             :         }
     341             : 
     342             :         /* Components data space is allocated here once */
     343   269488178 :         data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
     344   269488178 :         if (data == NULL) {
     345           0 :                 goto failed;
     346             :         }
     347             : 
     348   264405469 :         p = parse_dn;
     349   264405469 :         t = NULL;
     350   264405469 :         d = dt = data;
     351             : 
     352 26334434958 :         while (*p) {
     353 26073459374 :                 if (in_extended) {
     354             : 
     355  3305833798 :                         if (!in_ex_name && !in_ex_value) {
     356             : 
     357   340750532 :                                 if (p[0] == '<') {
     358    79773714 :                                         p++;
     359    79773714 :                                         ex_name = d;
     360    79773714 :                                         in_ex_name = true;
     361    79773714 :                                         continue;
     362             :                                 } else {
     363   260976818 :                                         in_extended = false;
     364   260976818 :                                         in_attr = true;
     365   260976818 :                                         dt = d;
     366             : 
     367   260976818 :                                         continue;
     368             :                                 }
     369             :                         }
     370             : 
     371  2965083266 :                         if (in_ex_name && *p == '=') {
     372    79773710 :                                 *d++ = '\0';
     373    79773710 :                                 p++;
     374    79773710 :                                 ex_value = d;
     375    79773710 :                                 in_ex_name = false;
     376    79773710 :                                 in_ex_value = true;
     377    79773710 :                                 continue;
     378             :                         }
     379             : 
     380  2885309556 :                         if (in_ex_value && *p == '>') {
     381    79773710 :                                 struct ldb_dn_ext_component *ext_comp = NULL;
     382     1174344 :                                 const struct ldb_dn_extended_syntax *ext_syntax;
     383    79773710 :                                 struct ldb_val ex_val = {
     384             :                                         .data = (uint8_t *)ex_value,
     385    79773710 :                                         .length = d - ex_value
     386             :                                 };
     387             : 
     388    79773710 :                                 *d++ = '\0';
     389    79773710 :                                 p++;
     390    79773710 :                                 in_ex_value = false;
     391             : 
     392             :                                 /* Process name and ex_value */
     393             : 
     394    79773710 :                                 ext_comp = talloc_realloc(
     395             :                                         dn,
     396             :                                         dn->ext_components,
     397             :                                         struct ldb_dn_ext_component,
     398             :                                         dn->ext_comp_num + 1);
     399             : 
     400    79773710 :                                 if (ext_comp == NULL) {
     401             :                                         /* ouch ! */
     402         442 :                                         goto failed;
     403             :                                 }
     404             : 
     405    79773710 :                                 dn->ext_components = ext_comp;
     406             : 
     407    79773710 :                                 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
     408    79773710 :                                 if (ext_syntax == NULL) {
     409             :                                         /* We don't know about this type of extended DN */
     410           9 :                                         goto failed;
     411             :                                 }
     412             : 
     413    79773701 :                                 dn->ext_components[dn->ext_comp_num].name = ext_syntax->name;
     414    79773701 :                                 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
     415    78599366 :                                                           &ex_val, &dn->ext_components[dn->ext_comp_num].value);
     416    79773701 :                                 if (ret != LDB_SUCCESS) {
     417         433 :                                         ldb_dn_mark_invalid(dn);
     418         433 :                                         goto failed;
     419             :                                 }
     420             : 
     421    79773268 :                                 dn->ext_comp_num++;
     422             : 
     423    79773268 :                                 if (*p == '\0') {
     424             :                                         /* We have reached the end (extended component only)! */
     425     8510914 :                                         talloc_free(data);
     426     8510914 :                                         return true;
     427             : 
     428    71262354 :                                 } else if (*p == ';') {
     429    71262354 :                                         p++;
     430    71262354 :                                         continue;
     431             :                                 } else {
     432           0 :                                         ldb_dn_mark_invalid(dn);
     433           0 :                                         goto failed;
     434             :                                 }
     435             :                         }
     436             : 
     437  2805535846 :                         *d++ = *p++;
     438  2805535846 :                         continue;
     439             :                 }
     440 22767625576 :                 if (in_attr) {
     441  4535304764 :                         if (trim) {
     442  1533189141 :                                 if (*p == ' ') {
     443    34066599 :                                         p++;
     444    34066599 :                                         continue;
     445             :                                 }
     446             : 
     447             :                                 /* first char */
     448  1499122542 :                                 trim = false;
     449             : 
     450  1499122542 :                                 if (!isascii(*p)) {
     451             :                                         /* attr names must be ascii only */
     452           0 :                                         ldb_dn_mark_invalid(dn);
     453           0 :                                         goto failed;
     454             :                                 }
     455             : 
     456  1499122542 :                                 if (isdigit(*p)) {
     457           0 :                                         is_oid = true;
     458             :                                 } else
     459  1499122542 :                                 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  1499122535 :                                 *d++ = *p++;
     469  1499122535 :                                 continue;
     470             :                         }
     471             : 
     472  3002115623 :                         if (*p == ' ') {
     473          96 :                                 p++;
     474             :                                 /* valid only if we are at the end */
     475          96 :                                 trim = true;
     476          96 :                                 continue;
     477             :                         }
     478             : 
     479  3002115527 :                         if (*p == '=') {
     480             :                                 /* attribute terminated */
     481  1499102943 :                                 in_attr = false;
     482  1499102943 :                                 in_value = true;
     483  1499102943 :                                 trim = true;
     484  1499102943 :                                 l = 0;
     485             : 
     486             :                                 /* Terminate this string in d
     487             :                                  * (which is a copy of parse_dn
     488             :                                  *  with spaces trimmed) */
     489  1499102943 :                                 *d++ = '\0';
     490  1499102943 :                                 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
     491  1499102943 :                                 if (dn->components[dn->comp_num].name == NULL) {
     492             :                                         /* ouch */
     493           0 :                                         goto failed;
     494             :                                 }
     495             : 
     496  1499102943 :                                 dt = d;
     497             : 
     498  1499102943 :                                 p++;
     499  1499102943 :                                 continue;
     500             :                         }
     501             : 
     502  1503012584 :                         if (!isascii(*p)) {
     503             :                                 /* attr names must be ascii only */
     504           0 :                                 ldb_dn_mark_invalid(dn);
     505           0 :                                 goto failed;
     506             :                         }
     507             : 
     508  1503012584 :                         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  1503012584 :                         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  1503011353 :                         *d++ = *p++;
     521  1503011353 :                         continue;
     522             :                 }
     523             : 
     524 18232320812 :                 if (in_value) {
     525 18232320812 :                         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 18232320812 :                         if (trim) {
     539  1499102935 :                                 if (*p == ' ') {
     540           0 :                                         p++;
     541           0 :                                         continue;
     542             :                                 }
     543             : 
     544             :                                 /* first char */
     545  1499102935 :                                 trim = false;
     546             : 
     547  1499102935 :                                 if (*p == '\"') {
     548           0 :                                         in_quote = true;
     549           0 :                                         p++;
     550           0 :                                         continue;
     551             :                                 }
     552             :                         }
     553             : 
     554 18232320812 :                         switch (*p) {
     555             : 
     556             :                         /* TODO: support ber encoded values
     557             :                         case '#':
     558             :                         */
     559             : 
     560  1238172486 :                         case ',':
     561  1238172486 :                                 if (escape) {
     562       26853 :                                         *d++ = *p++;
     563       26853 :                                         l++;
     564       26853 :                                         escape = false;
     565       26853 :                                         continue;
     566             :                                 }
     567             :                                 /* ok found value terminator */
     568             : 
     569  1238145633 :                                 if (t != NULL) {
     570             :                                         /* trim back */
     571          22 :                                         d -= (p - t);
     572          22 :                                         l -= (p - t);
     573          22 :                                         t = NULL;
     574             :                                 }
     575             : 
     576  1238145633 :                                 in_attr = true;
     577  1238145633 :                                 in_value = false;
     578  1238145633 :                                 trim = true;
     579             : 
     580  1238145633 :                                 p++;
     581  1238145633 :                                 *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  2476291266 :                                 dn->components[dn->comp_num].value.data = \
     589  1238145633 :                                         (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
     590  1238145633 :                                 dn->components[dn->comp_num].value.length = l;
     591  1238145633 :                                 if (dn->components[dn->comp_num].value.data == NULL) {
     592             :                                         /* ouch ! */
     593           0 :                                         goto failed;
     594             :                                 }
     595  1238145633 :                                 talloc_set_name_const(dn->components[dn->comp_num].value.data,
     596  1213622004 :                                                       (const char *)dn->components[dn->comp_num].value.data);
     597             : 
     598  1238145633 :                                 dt = d;
     599             : 
     600  1238145633 :                                 dn->comp_num++;
     601  1238145633 :                                 if (dn->comp_num > 2) {
     602   724804540 :                                         dn->components = talloc_realloc(dn,
     603             :                                                                         dn->components,
     604             :                                                                         struct ldb_dn_component,
     605             :                                                                         dn->comp_num + 1);
     606   724804540 :                                         if (dn->components == NULL) {
     607             :                                                 /* ouch ! */
     608           0 :                                                 goto failed;
     609             :                                         }
     610             :                                         /* make sure all components are zeroed, other functions depend on this */
     611   724804540 :                                         memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
     612             :                                 }
     613             : 
     614  1238145633 :                                 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    85684392 :                         case '\\':
     653    85684392 :                                 if (!escape) {
     654    85673592 :                                         escape = true;
     655    85673592 :                                         p++;
     656    85673592 :                                         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 16908463934 :                         default:
     669 16908463934 :                                 if (escape) {
     670    85635939 :                                         if (isxdigit(p[0]) && isxdigit(p[1])) {
     671    85635939 :                                                 if (sscanf(p, "%02x", &x) != 1) {
     672             :                                                         /* invalid escaping sequence */
     673           0 :                                                         ldb_dn_mark_invalid(dn);
     674           0 :                                                         goto failed;
     675             :                                                 }
     676    85635939 :                                                 p += 2;
     677    85635939 :                                                 *d++ = (unsigned char)x;
     678             :                                         } else {
     679           0 :                                                 *d++ = *p++;
     680             :                                         }
     681             : 
     682    85635939 :                                         escape = false;
     683    85635939 :                                         l++;
     684    85635939 :                                         if (t != NULL) {
     685           0 :                                                 t = NULL;
     686             :                                         }
     687    85635031 :                                         break;
     688             :                                 }
     689             : 
     690 16822827995 :                                 if (*p == ' ') {
     691   124778152 :                                         if (t == NULL) {
     692   124774084 :                                                 t = p;
     693             :                                         }
     694             :                                 } else {
     695 16441101973 :                                         if (t != NULL) {
     696   123652412 :                                                 t = NULL;
     697             :                                         }
     698             :                                 }
     699             : 
     700 16822827995 :                                 *d++ = *p++;
     701 16822827995 :                                 l++;
     702             : 
     703 16822827995 :                                 break;
     704             :                         }
     705             : 
     706             :                 }
     707             :         }
     708             : 
     709   260975584 :         if (in_attr || in_quote) {
     710             :                 /* invalid dn */
     711       18270 :                 ldb_dn_mark_invalid(dn);
     712       18270 :                 goto failed;
     713             :         }
     714             : 
     715   260957314 :         if (in_value) {
     716             :                 /* save last element */
     717   260957310 :                 if (t != NULL) {
     718             :                         /* trim back */
     719         190 :                         d -= (p - t);
     720         190 :                         l -= (p - t);
     721             :                 }
     722             : 
     723   260957310 :                 *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   260957310 :                 dn->components[dn->comp_num].value.length = l;
     730   521914620 :                 dn->components[dn->comp_num].value.data =
     731   260957310 :                         (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
     732   260957310 :                 if (dn->components[dn->comp_num].value.data == NULL) {
     733             :                         /* ouch */
     734           0 :                         goto failed;
     735             :                 }
     736   260957310 :                 talloc_set_name_const(dn->components[dn->comp_num].value.data,
     737   256104760 :                         (const char *)dn->components[dn->comp_num].value.data);
     738             : 
     739   260957310 :                 dn->comp_num++;
     740             :         }
     741   260957314 :         talloc_free(data);
     742   260957314 :         return true;
     743             : 
     744       19950 : failed:
     745       19950 :         LDB_FREE(dn->components); /* "data" is implicitly free'd */
     746       19950 :         dn->comp_num = 0;
     747       19950 :         LDB_FREE(dn->ext_components);
     748       19950 :         dn->ext_comp_num = 0;
     749             : 
     750       19950 :         return false;
     751             : }
     752             : 
     753  1140556745 : bool ldb_dn_validate(struct ldb_dn *dn)
     754             : {
     755  1140556745 :         return ldb_dn_explode(dn);
     756             : }
     757             : 
     758   768911530 : const char *ldb_dn_get_linearized(struct ldb_dn *dn)
     759             : {
     760    25271307 :         unsigned int i;
     761    25271307 :         size_t len;
     762    25271307 :         char *d, *n;
     763             : 
     764   768911530 :         if ( ! dn || ( dn->invalid)) return NULL;
     765             : 
     766   768911161 :         if (dn->linearized) return dn->linearized;
     767             : 
     768    10788726 :         if ( ! dn->components) {
     769           0 :                 ldb_dn_mark_invalid(dn);
     770           0 :                 return NULL;
     771             :         }
     772             : 
     773    10788726 :         if (dn->comp_num == 0) {
     774      529229 :                 dn->linearized = talloc_strdup(dn, "");
     775      529229 :                 if ( ! dn->linearized) return NULL;
     776      529229 :                 return dn->linearized;
     777             :         }
     778             : 
     779             :         /* calculate maximum possible length of DN */
     780    66940524 :         for (len = 0, i = 0; i < dn->comp_num; i++) {
     781             :                 /* name len */
     782    56681027 :                 len += strlen(dn->components[i].name);
     783             :                 /* max escaped data len */
     784    56681027 :                 len += (dn->components[i].value.length * 3);
     785    56681027 :                 len += 2; /* '=' and ',' */
     786             :         }
     787    10259497 :         dn->linearized = talloc_array(dn, char, len);
     788    10259497 :         if ( ! dn->linearized) return NULL;
     789             : 
     790     9630636 :         d = dn->linearized;
     791             : 
     792    66940524 :         for (i = 0; i < dn->comp_num; i++) {
     793             : 
     794             :                 /* copy the name */
     795    56681027 :                 n = dn->components[i].name;
     796   170043666 :                 while (*n) *d++ = *n++;
     797             : 
     798    56681027 :                 *d++ = '=';
     799             : 
     800             :                 /* and the value */
     801   113362054 :                 d += ldb_dn_escape_internal( d,
     802    56681027 :                                 (char *)dn->components[i].value.data,
     803    56681027 :                                 dn->components[i].value.length);
     804    56681027 :                 *d++ = ',';
     805             :         }
     806             : 
     807    10259497 :         *(--d) = '\0';
     808             : 
     809             :         /* don't waste more memory than necessary */
     810    10259497 :         dn->linearized = talloc_realloc(dn, dn->linearized,
     811             :                                         char, (d - dn->linearized + 1));
     812             : 
     813    10259497 :         return dn->linearized;
     814             : }
     815             : 
     816    49949302 : static int ldb_dn_extended_component_compare(const void *p1, const void *p2)
     817             : {
     818    49949302 :         const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1;
     819    49949302 :         const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2;
     820    49949302 :         return strcmp(ec1->name, ec2->name);
     821             : }
     822             : 
     823    28148791 : char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode)
     824             : {
     825    28148791 :         const char *linearized = ldb_dn_get_linearized(dn);
     826    28148791 :         char *p = NULL;
     827      621861 :         unsigned int i;
     828             : 
     829    28148791 :         if (!linearized) {
     830          96 :                 return NULL;
     831             :         }
     832             : 
     833    28148695 :         if (!ldb_dn_has_extended(dn)) {
     834     1540215 :                 return talloc_strdup(mem_ctx, linearized);
     835             :         }
     836             : 
     837    26608480 :         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    26608477 :         TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num,
     846             :                        ldb_dn_extended_component_compare);
     847             : 
     848    78386735 :         for (i = 0; i < dn->ext_comp_num; i++) {
     849      629250 :                 const struct ldb_dn_extended_syntax *ext_syntax;
     850    51778258 :                 const char *name = dn->ext_components[i].name;
     851    51778258 :                 struct ldb_val ec_val = dn->ext_components[i].value;
     852      629250 :                 struct ldb_val val;
     853      629250 :                 int ret;
     854             : 
     855    51778258 :                 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
     856    51778258 :                 if (!ext_syntax) {
     857           0 :                         return NULL;
     858             :                 }
     859             : 
     860    51778258 :                 if (mode == 1) {
     861    41460512 :                         ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
     862             :                                                         &ec_val, &val);
     863    10317746 :                 } else if (mode == 0) {
     864    10317746 :                         ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
     865             :                                                         &ec_val, &val);
     866             :                 } else {
     867           0 :                         ret = -1;
     868             :                 }
     869             : 
     870    51778258 :                 if (ret != LDB_SUCCESS) {
     871           0 :                         return NULL;
     872             :                 }
     873             : 
     874    51778258 :                 if (i == 0) {
     875    26608473 :                         p = talloc_asprintf(mem_ctx, "<%s=%.*s>",
     876             :                                             name,
     877    26608473 :                                             (int)val.length,
     878             :                                             val.data);
     879             :                 } else {
     880    25169785 :                         talloc_asprintf_addbuf(&p, ";<%s=%.*s>",
     881             :                                                name,
     882    25169785 :                                                (int)val.length,
     883             :                                                val.data);
     884             :                 }
     885             : 
     886    51778258 :                 talloc_free(val.data);
     887             :         }
     888             : 
     889    26608477 :         if (dn->ext_comp_num && *linearized) {
     890    25367092 :                 talloc_asprintf_addbuf(&p, ";%s", linearized);
     891             :         }
     892             : 
     893    26608477 :         if (!p) {
     894           4 :                 return NULL;
     895             :         }
     896             : 
     897    26096089 :         return p;
     898             : }
     899             : 
     900             : /*
     901             :   filter out all but an acceptable list of extended DN components
     902             :  */
     903    16917634 : void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list)
     904             : {
     905      204154 :         unsigned int i;
     906    59106973 :         for (i=0; i<dn->ext_comp_num; i++) {
     907    42189339 :                 if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) {
     908    19263128 :                         ARRAY_DEL_ELEMENT(
     909        3206 :                                 dn->ext_components, i, dn->ext_comp_num);
     910    19263128 :                         dn->ext_comp_num--;
     911    19263128 :                         i--;
     912             :                 }
     913             :         }
     914    16917634 :         LDB_FREE(dn->ext_linearized);
     915    16917634 : }
     916             : 
     917             : 
     918   173491613 : char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
     919             : {
     920   173491613 :         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   278944105 : static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
     929             : {
     930     4283213 :         unsigned int i;
     931     4283213 :         int ret;
     932             : 
     933   278944105 :         if ( ! dn || dn->invalid) return false;
     934             : 
     935   278944105 :         if (dn->valid_case) return true;
     936             : 
     937   139606743 :         if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
     938         736 :                 return false;
     939             :         }
     940             : 
     941   884937330 :         for (i = 0; i < dn->comp_num; i++) {
     942    12268069 :                 const struct ldb_schema_attribute *a;
     943             : 
     944  1490662646 :                 dn->components[i].cf_name =
     945   745331323 :                         ldb_attr_casefold(dn->components,
     946   745331323 :                                           dn->components[i].name);
     947   745331323 :                 if (!dn->components[i].cf_name) {
     948           0 :                         goto failed;
     949             :                 }
     950             : 
     951   745331323 :                 a = ldb_schema_attribute_by_name(dn->ldb,
     952   733063254 :                                                  dn->components[i].cf_name);
     953             : 
     954   757599392 :                 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
     955   745331323 :                                                  &(dn->components[i].value),
     956   745331323 :                                                  &(dn->components[i].cf_value));
     957   745331323 :                 if (ret != 0) {
     958           0 :                         goto failed;
     959             :                 }
     960             :         }
     961             : 
     962   139606007 :         dn->valid_case = true;
     963             : 
     964   139606007 :         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   506552513 : const char *ldb_dn_get_casefold(struct ldb_dn *dn)
     975             : {
     976    16139704 :         unsigned int i;
     977    16139704 :         size_t len;
     978    16139704 :         char *d, *n;
     979             : 
     980   506552513 :         if (dn->casefold) return dn->casefold;
     981             : 
     982   316310234 :         if (dn->special) {
     983   283831089 :                 dn->casefold = talloc_strdup(dn, dn->linearized);
     984   283831089 :                 if (!dn->casefold) return NULL;
     985   283831089 :                 dn->valid_case = true;
     986   283831089 :                 return dn->casefold;
     987             :         }
     988             : 
     989    32479145 :         if ( ! ldb_dn_casefold_internal(dn)) {
     990           0 :                 return NULL;
     991             :         }
     992             : 
     993    32479145 :         if (dn->comp_num == 0) {
     994        1372 :                 dn->casefold = talloc_strdup(dn, "");
     995        1372 :                 return dn->casefold;
     996             :         }
     997             : 
     998             :         /* calculate maximum possible length of DN */
     999   194347816 :         for (len = 0, i = 0; i < dn->comp_num; i++) {
    1000             :                 /* name len */
    1001   161870043 :                 len += strlen(dn->components[i].cf_name);
    1002             :                 /* max escaped data len */
    1003   161870043 :                 len += (dn->components[i].cf_value.length * 3);
    1004   161870043 :                 len += 2; /* '=' and ',' */
    1005             :         }
    1006    32477773 :         dn->casefold = talloc_array(dn, char, len);
    1007    32477773 :         if ( ! dn->casefold) return NULL;
    1008             : 
    1009    30507698 :         d = dn->casefold;
    1010             : 
    1011   194347816 :         for (i = 0; i < dn->comp_num; i++) {
    1012             : 
    1013             :                 /* copy the name */
    1014   161870043 :                 n = dn->components[i].cf_name;
    1015   487097061 :                 while (*n) *d++ = *n++;
    1016             : 
    1017   161870043 :                 *d++ = '=';
    1018             : 
    1019             :                 /* and the value */
    1020   323740086 :                 d += ldb_dn_escape_internal( d,
    1021   161870043 :                                 (char *)dn->components[i].cf_value.data,
    1022   161870043 :                                 dn->components[i].cf_value.length);
    1023   161870043 :                 *d++ = ',';
    1024             :         }
    1025    32477773 :         *(--d) = '\0';
    1026             : 
    1027             :         /* don't waste more memory than necessary */
    1028    32477773 :         dn->casefold = talloc_realloc(dn, dn->casefold,
    1029             :                                       char, strlen(dn->casefold) + 1);
    1030             : 
    1031    32477773 :         return dn->casefold;
    1032             : }
    1033             : 
    1034     2473993 : char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1035             : {
    1036     2473993 :         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             :  *
    1042             :  * 0 if they match, otherwise non-zero.
    1043             :  *
    1044             :  * This is not for use in a qsort()-like function, as the comparison
    1045             :  * is not symmetric.
    1046             :  */
    1047             : 
    1048   577865297 : int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
    1049             : {
    1050    12373459 :         int ret;
    1051    12373459 :         unsigned int n_base, n_dn;
    1052             : 
    1053   577865297 :         if ( ! base || base->invalid) return 1;
    1054   577865297 :         if ( ! dn || dn->invalid) return -1;
    1055             : 
    1056   577865297 :         if (( ! base->valid_case) || ( ! dn->valid_case)) {
    1057   398937530 :                 if (base->linearized && dn->linearized && dn->special == base->special) {
    1058             :                         /* try with a normal compare first, if we are lucky
    1059             :                          * we will avoid exploding and casefolding */
    1060     6512193 :                         int dif;
    1061   391284656 :                         dif = strlen(dn->linearized) - strlen(base->linearized);
    1062   391284656 :                         if (dif < 0) {
    1063   128216228 :                                 return dif;
    1064             :                         }
    1065   260675053 :                         if (strcmp(base->linearized,
    1066   260675053 :                                    &dn->linearized[dif]) == 0) {
    1067   150442347 :                                 return 0;
    1068             :                         }
    1069             :                 }
    1070             : 
    1071   114153850 :                 if ( ! ldb_dn_casefold_internal(base)) {
    1072           0 :                         return 1;
    1073             :                 }
    1074             : 
    1075   114153850 :                 if ( ! ldb_dn_casefold_internal(dn)) {
    1076           0 :                         return -1;
    1077             :                 }
    1078             : 
    1079             :         }
    1080             : 
    1081             :         /* if base has more components,
    1082             :          * they don't have the same base */
    1083   293081617 :         if (base->comp_num > dn->comp_num) {
    1084    55049042 :                 return (dn->comp_num - base->comp_num);
    1085             :         }
    1086             : 
    1087   238032575 :         if ((dn->comp_num == 0) || (base->comp_num == 0)) {
    1088           1 :                 if (dn->special && base->special) {
    1089           0 :                         return strcmp(base->linearized, dn->linearized);
    1090           1 :                 } else if (dn->special) {
    1091           0 :                         return -1;
    1092           1 :                 } else if (base->special) {
    1093           0 :                         return 1;
    1094             :                 } else {
    1095           0 :                         return 0;
    1096             :                 }
    1097             :         }
    1098             : 
    1099   238032574 :         n_base = base->comp_num - 1;
    1100   238032574 :         n_dn = dn->comp_num - 1;
    1101             : 
    1102  1118711367 :         while (n_base != (unsigned int) -1) {
    1103  1022457088 :                 char *b_name = base->components[n_base].cf_name;
    1104  1022457088 :                 char *dn_name = dn->components[n_dn].cf_name;
    1105             : 
    1106  1022457088 :                 char *b_vdata = (char *)base->components[n_base].cf_value.data;
    1107  1022457088 :                 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
    1108             : 
    1109  1022457088 :                 size_t b_vlen = base->components[n_base].cf_value.length;
    1110  1022457088 :                 size_t dn_vlen = dn->components[n_dn].cf_value.length;
    1111             : 
    1112             :                 /* compare attr names */
    1113  1022457088 :                 ret = strcmp(b_name, dn_name);
    1114  1022457088 :                 if (ret != 0) return ret;
    1115             : 
    1116             :                 /* compare attr.cf_value. */
    1117   930106300 :                 if (b_vlen != dn_vlen) {
    1118    47745133 :                         return NUMERIC_CMP(b_vlen, dn_vlen);
    1119             :                 }
    1120   882361167 :                 ret = strncmp(b_vdata, dn_vdata, b_vlen);
    1121   882361167 :                 if (ret != 0) return ret;
    1122             : 
    1123   880678793 :                 n_base--;
    1124   880678793 :                 n_dn--;
    1125             :         }
    1126             : 
    1127    92683698 :         return 0;
    1128             : }
    1129             : 
    1130             : /* compare DNs using casefolding compare functions.
    1131             : 
    1132             :    If they match, then return 0
    1133             :  */
    1134             : 
    1135    67617739 : int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
    1136             : {
    1137     4491657 :         unsigned int i;
    1138     4491657 :         int ret;
    1139             :         /*
    1140             :          * If used in sort, we shift NULL and invalid DNs to the end.
    1141             :          *
    1142             :          * If ldb_dn_casefold_internal() fails, that goes to the end too, so
    1143             :          * we end up with:
    1144             :          *
    1145             :          * | normal DNs, sorted | casefold failed DNs | invalid DNs | NULLs |
    1146             :          */
    1147             : 
    1148    67617739 :         if (dn0 == dn1) {
    1149             :                 /* this includes the both-NULL case */
    1150        3060 :                 return 0;
    1151             :         }
    1152    67614580 :         if (dn0 == NULL) {
    1153           0 :                 return 1;
    1154             :         }
    1155    67614580 :         if (dn1 == NULL) {
    1156           0 :                 return -1;
    1157             :         }
    1158    67614580 :         if (dn0->invalid && dn1->invalid) {
    1159           0 :                 return 0;
    1160             :         }
    1161    67614580 :         if (dn0->invalid) {
    1162           2 :                 return 1;
    1163             :         }
    1164    67614578 :         if (dn1->invalid) {
    1165           0 :                 return -1;
    1166             :         }
    1167             : 
    1168    67614578 :         if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
    1169     9591005 :                 if (dn0->linearized && dn1->linearized) {
    1170             :                         /* try with a normal compare first, if we are lucky
    1171             :                          * we will avoid exploding and casefolding */
    1172     7457630 :                         if (strcmp(dn0->linearized, dn1->linearized) == 0) {
    1173      498320 :                                 return 0;
    1174             :                         }
    1175             :                 }
    1176             : 
    1177     9078630 :                 if ( ! ldb_dn_casefold_internal(dn0)) {
    1178           0 :                         return 1;
    1179             :                 }
    1180             : 
    1181     9078630 :                 if ( ! ldb_dn_casefold_internal(dn1)) {
    1182         736 :                         return -1;
    1183             :                 }
    1184             : 
    1185             :         }
    1186             : 
    1187             :         /*
    1188             :          * Notice that for comp_num, Samba reverses the usual order of
    1189             :          * comparison. A DN with fewer components is greater than one
    1190             :          * with more.
    1191             :          */
    1192    67101467 :         if (dn0->comp_num > dn1->comp_num) {
    1193    18244024 :                 return -1;
    1194    46397535 :         } else if (dn0->comp_num < dn1->comp_num) {
    1195    19731211 :                 return 1;
    1196             :         }
    1197             : 
    1198    25698699 :         if (dn0->comp_num == 0) {
    1199     1107079 :                 if (dn0->special && dn1->special) {
    1200     1107079 :                         return strcmp(dn0->linearized, dn1->linearized);
    1201           0 :                 } else if (dn0->special) {
    1202           0 :                         return 1;
    1203           0 :                 } else if (dn1->special) {
    1204           0 :                         return -1;
    1205             :                 } else {
    1206           0 :                         return 0;
    1207             :                 }
    1208             :         }
    1209             : 
    1210    72269935 :         for (i = 0; i < dn0->comp_num; i++) {
    1211    61949132 :                 char *dn0_name = dn0->components[i].cf_name;
    1212    61949132 :                 char *dn1_name = dn1->components[i].cf_name;
    1213             : 
    1214    61949132 :                 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
    1215    61949132 :                 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
    1216             : 
    1217    61949132 :                 size_t dn0_vlen = dn0->components[i].cf_value.length;
    1218    61949132 :                 size_t dn1_vlen = dn1->components[i].cf_value.length;
    1219             : 
    1220             :                 /* compare attr names */
    1221    61949132 :                 ret = strcmp(dn0_name, dn1_name);
    1222    61949132 :                 if (ret != 0) {
    1223     3406944 :                         return ret;
    1224             :                 }
    1225             : 
    1226             :                 /* compare attr.cf_value. */
    1227    58542188 :                 if (dn0_vlen != dn1_vlen) {
    1228     6105071 :                         return NUMERIC_CMP(dn0_vlen, dn1_vlen);
    1229             :                 }
    1230    52437117 :                 ret = strncmp(dn0_vdata, dn1_vdata, dn0_vlen);
    1231    52437117 :                 if (ret != 0) {
    1232     4758802 :                         return ret;
    1233             :                 }
    1234             :         }
    1235             : 
    1236     9781948 :         return 0;
    1237             : }
    1238             : 
    1239   414572550 : static struct ldb_dn_component ldb_dn_copy_component(
    1240             :                                                 TALLOC_CTX *mem_ctx,
    1241             :                                                 struct ldb_dn_component *src)
    1242             : {
    1243    20889697 :         struct ldb_dn_component dst;
    1244             : 
    1245   414572550 :         memset(&dst, 0, sizeof(dst));
    1246             : 
    1247   414572550 :         if (src == NULL) {
    1248           0 :                 return dst;
    1249             :         }
    1250             : 
    1251   414572550 :         dst.value = ldb_val_dup(mem_ctx, &(src->value));
    1252   414572550 :         if (dst.value.data == NULL) {
    1253           0 :                 return dst;
    1254             :         }
    1255             : 
    1256   414572550 :         dst.name = talloc_strdup(mem_ctx, src->name);
    1257   414572550 :         if (dst.name == NULL) {
    1258           0 :                 LDB_FREE(dst.value.data);
    1259           0 :                 return dst;
    1260             :         }
    1261             : 
    1262   414572550 :         if (src->cf_value.data) {
    1263   344270471 :                 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
    1264   344270471 :                 if (dst.cf_value.data == NULL) {
    1265           0 :                         LDB_FREE(dst.value.data);
    1266           0 :                         LDB_FREE(dst.name);
    1267           0 :                         return dst;
    1268             :                 }
    1269             : 
    1270   344270471 :                 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
    1271   344270471 :                 if (dst.cf_name == NULL) {
    1272           0 :                         LDB_FREE(dst.cf_name);
    1273           0 :                         LDB_FREE(dst.value.data);
    1274           0 :                         LDB_FREE(dst.name);
    1275           0 :                         return dst;
    1276             :                 }
    1277             :         } else {
    1278    67208075 :                 dst.cf_value.data = NULL;
    1279    67208075 :                 dst.cf_name = NULL;
    1280             :         }
    1281             : 
    1282   414572550 :         return dst;
    1283             : }
    1284             : 
    1285    32253366 : static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
    1286             :                                                 TALLOC_CTX *mem_ctx,
    1287             :                                                 struct ldb_dn_ext_component *src)
    1288             : {
    1289      935203 :         struct ldb_dn_ext_component dst;
    1290             : 
    1291    32253366 :         memset(&dst, 0, sizeof(dst));
    1292             : 
    1293    32253366 :         if (src == NULL) {
    1294           0 :                 return dst;
    1295             :         }
    1296             : 
    1297    32253366 :         dst.value = ldb_val_dup(mem_ctx, &(src->value));
    1298    32253366 :         if (dst.value.data == NULL) {
    1299           0 :                 return dst;
    1300             :         }
    1301             : 
    1302    32253366 :         dst.name = talloc_strdup(mem_ctx, src->name);
    1303    32253366 :         if (dst.name == NULL) {
    1304           0 :                 LDB_FREE(dst.value.data);
    1305           0 :                 return dst;
    1306             :         }
    1307             : 
    1308    32253366 :         return dst;
    1309             : }
    1310             : 
    1311    79057930 : struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1312             : {
    1313     3809486 :         struct ldb_dn *new_dn;
    1314             : 
    1315    79057930 :         if (!dn || dn->invalid) {
    1316           2 :                 return NULL;
    1317             :         }
    1318             : 
    1319    79057928 :         new_dn = talloc_zero(mem_ctx, struct ldb_dn);
    1320    79057928 :         if ( !new_dn) {
    1321           0 :                 return NULL;
    1322             :         }
    1323             : 
    1324    79057928 :         *new_dn = *dn;
    1325             : 
    1326    79057928 :         if (dn->components) {
    1327     3583526 :                 unsigned int i;
    1328             : 
    1329    74021149 :                 new_dn->components =
    1330    70437623 :                         talloc_zero_array(new_dn,
    1331             :                                           struct ldb_dn_component,
    1332             :                                           dn->comp_num);
    1333    70437623 :                 if ( ! new_dn->components) {
    1334           0 :                         talloc_free(new_dn);
    1335           0 :                         return NULL;
    1336             :                 }
    1337             : 
    1338   469266758 :                 for (i = 0; i < dn->comp_num; i++) {
    1339   398829135 :                         new_dn->components[i] =
    1340   398829135 :                                 ldb_dn_copy_component(new_dn->components,
    1341   398829135 :                                                       &dn->components[i]);
    1342   398829135 :                         if ( ! new_dn->components[i].value.data) {
    1343           0 :                                 talloc_free(new_dn);
    1344           0 :                                 return NULL;
    1345             :                         }
    1346             :                 }
    1347             :         }
    1348             : 
    1349    79057928 :         if (dn->ext_components) {
    1350      803234 :                 unsigned int i;
    1351             : 
    1352    26079314 :                 new_dn->ext_components =
    1353    25276080 :                         talloc_zero_array(new_dn,
    1354             :                                           struct ldb_dn_ext_component,
    1355             :                                           dn->ext_comp_num);
    1356    25276080 :                 if ( ! new_dn->ext_components) {
    1357           0 :                         talloc_free(new_dn);
    1358           0 :                         return NULL;
    1359             :                 }
    1360             : 
    1361    57529446 :                 for (i = 0; i < dn->ext_comp_num; i++) {
    1362    32253366 :                         new_dn->ext_components[i] =
    1363    32253366 :                                  ldb_dn_ext_copy_component(
    1364    32253366 :                                                 new_dn->ext_components,
    1365    32253366 :                                                 &dn->ext_components[i]);
    1366    32253366 :                         if ( ! new_dn->ext_components[i].value.data) {
    1367           0 :                                 talloc_free(new_dn);
    1368           0 :                                 return NULL;
    1369             :                         }
    1370             :                 }
    1371             :         }
    1372             : 
    1373    79057928 :         if (dn->casefold) {
    1374    44912576 :                 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
    1375    44912576 :                 if ( ! new_dn->casefold) {
    1376           0 :                         talloc_free(new_dn);
    1377           0 :                         return NULL;
    1378             :                 }
    1379             :         }
    1380             : 
    1381    79057928 :         if (dn->linearized) {
    1382    78912460 :                 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
    1383    78912460 :                 if ( ! new_dn->linearized) {
    1384           0 :                         talloc_free(new_dn);
    1385           0 :                         return NULL;
    1386             :                 }
    1387             :         }
    1388             : 
    1389    79057928 :         if (dn->ext_linearized) {
    1390     2905868 :                 new_dn->ext_linearized = talloc_strdup(new_dn,
    1391     1404505 :                                                         dn->ext_linearized);
    1392     1501363 :                 if ( ! new_dn->ext_linearized) {
    1393           0 :                         talloc_free(new_dn);
    1394           0 :                         return NULL;
    1395             :                 }
    1396             :         }
    1397             : 
    1398    75248442 :         return new_dn;
    1399             : }
    1400             : 
    1401             : /* modify the given dn by adding a base.
    1402             :  *
    1403             :  * return true if successful and false if not
    1404             :  * if false is returned the dn may be marked invalid
    1405             :  */
    1406      629172 : bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
    1407             : {
    1408        4935 :         const char *s;
    1409        4935 :         char *t;
    1410             : 
    1411      629172 :         if ( !base || base->invalid || !dn || dn->invalid) {
    1412           0 :                 return false;
    1413             :         }
    1414             : 
    1415      629172 :         if (dn == base) {
    1416           0 :                 return false; /* or we will visit infinity */
    1417             :         }
    1418             : 
    1419      629172 :         if (dn->components) {
    1420         479 :                 unsigned int i;
    1421             : 
    1422      455226 :                 if ( ! ldb_dn_validate(base)) {
    1423           0 :                         return false;
    1424             :                 }
    1425             : 
    1426      455226 :                 s = NULL;
    1427      455226 :                 if (dn->valid_case) {
    1428           2 :                         if ( ! (s = ldb_dn_get_casefold(base))) {
    1429           0 :                                 return false;
    1430             :                         }
    1431             :                 }
    1432             : 
    1433      455226 :                 dn->components = talloc_realloc(dn,
    1434             :                                                 dn->components,
    1435             :                                                 struct ldb_dn_component,
    1436             :                                                 dn->comp_num + base->comp_num);
    1437      455226 :                 if ( ! dn->components) {
    1438           0 :                         ldb_dn_mark_invalid(dn);
    1439           0 :                         return false;
    1440             :                 }
    1441             : 
    1442     2998448 :                 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
    1443     2543222 :                         dn->components[dn->comp_num] =
    1444     2543222 :                                 ldb_dn_copy_component(dn->components,
    1445     2543222 :                                                         &base->components[i]);
    1446     2543222 :                         if (dn->components[dn->comp_num].value.data == NULL) {
    1447           0 :                                 ldb_dn_mark_invalid(dn);
    1448           0 :                                 return false;
    1449             :                         }
    1450             :                 }
    1451             : 
    1452      455226 :                 if (dn->casefold && s) {
    1453           0 :                         if (*dn->casefold) {
    1454           0 :                                 t = talloc_asprintf(dn, "%s,%s",
    1455             :                                                     dn->casefold, s);
    1456             :                         } else {
    1457           0 :                                 t = talloc_strdup(dn, s);
    1458             :                         }
    1459           0 :                         LDB_FREE(dn->casefold);
    1460           0 :                         dn->casefold = t;
    1461             :                 }
    1462             :         }
    1463             : 
    1464      629172 :         if (dn->linearized) {
    1465             : 
    1466      176585 :                 s = ldb_dn_get_linearized(base);
    1467      176585 :                 if ( ! s) {
    1468           0 :                         return false;
    1469             :                 }
    1470             : 
    1471      176585 :                 if (*dn->linearized) {
    1472       14534 :                         t = talloc_asprintf(dn, "%s,%s",
    1473             :                                             dn->linearized, s);
    1474             :                 } else {
    1475      162051 :                         t = talloc_strdup(dn, s);
    1476             :                 }
    1477      176585 :                 if ( ! t) {
    1478           0 :                         ldb_dn_mark_invalid(dn);
    1479           0 :                         return false;
    1480             :                 }
    1481      176585 :                 LDB_FREE(dn->linearized);
    1482      176585 :                 dn->linearized = t;
    1483             :         }
    1484             : 
    1485             :         /* Wipe the ext_linearized DN,
    1486             :          * the GUID and SID are almost certainly no longer valid */
    1487      629172 :         LDB_FREE(dn->ext_linearized);
    1488      629172 :         LDB_FREE(dn->ext_components);
    1489      629172 :         dn->ext_comp_num = 0;
    1490             : 
    1491      629172 :         return true;
    1492             : }
    1493             : 
    1494             : /* modify the given dn by adding a base.
    1495             :  *
    1496             :  * return true if successful and false if not
    1497             :  * if false is returned the dn may be marked invalid
    1498             :  */
    1499           2 : bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
    1500             : {
    1501           2 :         struct ldb_dn *base;
    1502           2 :         char *base_str;
    1503           2 :         va_list ap;
    1504           2 :         bool ret;
    1505             : 
    1506           2 :         if ( !dn || dn->invalid) {
    1507           0 :                 return false;
    1508             :         }
    1509             : 
    1510           2 :         va_start(ap, base_fmt);
    1511           2 :         base_str = talloc_vasprintf(dn, base_fmt, ap);
    1512           2 :         va_end(ap);
    1513             : 
    1514           2 :         if (base_str == NULL) {
    1515           0 :                 return false;
    1516             :         }
    1517             : 
    1518           2 :         base = ldb_dn_new(base_str, dn->ldb, base_str);
    1519             : 
    1520           2 :         ret = ldb_dn_add_base(dn, base);
    1521             : 
    1522           2 :         talloc_free(base_str);
    1523             : 
    1524           2 :         return ret;
    1525             : }
    1526             : 
    1527             : /* modify the given dn by adding children elements.
    1528             :  *
    1529             :  * return true if successful and false if not
    1530             :  * if false is returned the dn may be marked invalid
    1531             :  */
    1532     6767589 : bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
    1533             : {
    1534      369738 :         const char *s;
    1535      369738 :         char *t;
    1536             : 
    1537     6767589 :         if ( !child || child->invalid || !dn || dn->invalid) {
    1538           0 :                 return false;
    1539             :         }
    1540             : 
    1541     6767589 :         if (dn->components) {
    1542      366047 :                 unsigned int n;
    1543      366047 :                 unsigned int i, j;
    1544             : 
    1545     6526465 :                 if (dn->comp_num == 0) {
    1546           0 :                         return false;
    1547             :                 }
    1548             : 
    1549     6526465 :                 if ( ! ldb_dn_validate(child)) {
    1550           0 :                         return false;
    1551             :                 }
    1552             : 
    1553     6526465 :                 s = NULL;
    1554     6526465 :                 if (dn->valid_case) {
    1555     4659463 :                         if ( ! (s = ldb_dn_get_casefold(child))) {
    1556           0 :                                 return false;
    1557             :                         }
    1558             :                 }
    1559             : 
    1560     6526465 :                 n = dn->comp_num + child->comp_num;
    1561             : 
    1562     6526465 :                 dn->components = talloc_realloc(dn,
    1563             :                                                 dn->components,
    1564             :                                                 struct ldb_dn_component,
    1565             :                                                 n);
    1566     6526465 :                 if ( ! dn->components) {
    1567           0 :                         ldb_dn_mark_invalid(dn);
    1568           0 :                         return false;
    1569             :                 }
    1570             : 
    1571    35246520 :                 for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1;
    1572    28720055 :                      i--, j--) {
    1573    28720055 :                         dn->components[j] = dn->components[i];
    1574             :                 }
    1575             : 
    1576    19081559 :                 for (i = 0; i < child->comp_num; i++) {
    1577    12555094 :                         dn->components[i] =
    1578    12555094 :                                 ldb_dn_copy_component(dn->components,
    1579    12555094 :                                                         &child->components[i]);
    1580    12555094 :                         if (dn->components[i].value.data == NULL) {
    1581           0 :                                 ldb_dn_mark_invalid(dn);
    1582           0 :                                 return false;
    1583             :                         }
    1584             :                 }
    1585             : 
    1586     6526465 :                 dn->comp_num = n;
    1587             : 
    1588     6526465 :                 if (dn->casefold && s) {
    1589     3391965 :                         t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
    1590     3391965 :                         LDB_FREE(dn->casefold);
    1591     3391965 :                         dn->casefold = t;
    1592             :                 }
    1593             :         }
    1594             : 
    1595     6767589 :         if (dn->linearized) {
    1596     6760501 :                 if (dn->linearized[0] == '\0') {
    1597           0 :                         return false;
    1598             :                 }
    1599             : 
    1600     6760500 :                 s = ldb_dn_get_linearized(child);
    1601     6760500 :                 if ( ! s) {
    1602           0 :                         return false;
    1603             :                 }
    1604             : 
    1605     6760500 :                 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
    1606     6760500 :                 if ( ! t) {
    1607           0 :                         ldb_dn_mark_invalid(dn);
    1608           0 :                         return false;
    1609             :                 }
    1610     6760500 :                 LDB_FREE(dn->linearized);
    1611     6760500 :                 dn->linearized = t;
    1612             :         }
    1613             : 
    1614             :         /* Wipe the ext_linearized DN,
    1615             :          * the GUID and SID are almost certainly no longer valid */
    1616     6767588 :         LDB_FREE(dn->ext_linearized);
    1617     6767588 :         LDB_FREE(dn->ext_components);
    1618     6767588 :         dn->ext_comp_num = 0;
    1619             : 
    1620     6767588 :         return true;
    1621             : }
    1622             : 
    1623             : /* modify the given dn by adding children elements.
    1624             :  *
    1625             :  * return true if successful and false if not
    1626             :  * if false is returned the dn may be marked invalid
    1627             :  */
    1628     6566766 : bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
    1629             : {
    1630      368376 :         struct ldb_dn *child;
    1631      368376 :         char *child_str;
    1632      368376 :         va_list ap;
    1633      368376 :         bool ret;
    1634             : 
    1635     6566766 :         if ( !dn || dn->invalid) {
    1636           0 :                 return false;
    1637             :         }
    1638             : 
    1639     6566766 :         va_start(ap, child_fmt);
    1640     6566766 :         child_str = talloc_vasprintf(dn, child_fmt, ap);
    1641     6566766 :         va_end(ap);
    1642             : 
    1643     6566766 :         if (child_str == NULL) {
    1644           0 :                 return false;
    1645             :         }
    1646             : 
    1647     6566766 :         child = ldb_dn_new(child_str, dn->ldb, child_str);
    1648             : 
    1649     6566766 :         ret = ldb_dn_add_child(dn, child);
    1650             : 
    1651     6566766 :         talloc_free(child_str);
    1652             : 
    1653     6566766 :         return ret;
    1654             : }
    1655             : 
    1656             : /* modify the given dn by adding a single child element.
    1657             :  *
    1658             :  * return true if successful and false if not
    1659             :  * if false is returned the dn may be marked invalid
    1660             :  */
    1661       25522 : bool ldb_dn_add_child_val(struct ldb_dn *dn,
    1662             :                           const char *rdn,
    1663             :                           struct ldb_val value)
    1664             : {
    1665          10 :         bool ret;
    1666          10 :         int ldb_ret;
    1667       25522 :         struct ldb_dn *child = NULL;
    1668             : 
    1669       25522 :         if ( !dn || dn->invalid) {
    1670           0 :                 return false;
    1671             :         }
    1672             : 
    1673       25522 :         child = ldb_dn_new(dn, dn->ldb, "X=Y");
    1674       25522 :         ret = ldb_dn_add_child(dn, child);
    1675             : 
    1676       25522 :         if (ret == false) {
    1677           0 :                 return false;
    1678             :         }
    1679             : 
    1680       25522 :         ldb_ret = ldb_dn_set_component(dn,
    1681             :                                        0,
    1682             :                                        rdn,
    1683             :                                        value);
    1684       25522 :         if (ldb_ret != LDB_SUCCESS) {
    1685           0 :                 return false;
    1686             :         }
    1687             : 
    1688       25512 :         return true;
    1689             : }
    1690             : 
    1691      603886 : bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
    1692             : {
    1693         454 :         unsigned int i;
    1694             : 
    1695      603886 :         if ( ! ldb_dn_validate(dn)) {
    1696           0 :                 return false;
    1697             :         }
    1698             : 
    1699      603886 :         if (dn->comp_num < num) {
    1700           0 :                 return false;
    1701             :         }
    1702             : 
    1703             :         /* free components */
    1704     3840056 :         for (i = dn->comp_num - num; i < dn->comp_num; i++) {
    1705     3236170 :                 LDB_FREE(dn->components[i].name);
    1706     3236170 :                 LDB_FREE(dn->components[i].value.data);
    1707     3236170 :                 LDB_FREE(dn->components[i].cf_name);
    1708     3236170 :                 LDB_FREE(dn->components[i].cf_value.data);
    1709             :         }
    1710             : 
    1711      603886 :         dn->comp_num -= num;
    1712             : 
    1713      603886 :         if (dn->valid_case) {
    1714      303213 :                 for (i = 0; i < dn->comp_num; i++) {
    1715      151600 :                         LDB_FREE(dn->components[i].cf_name);
    1716      151600 :                         LDB_FREE(dn->components[i].cf_value.data);
    1717             :                 }
    1718      151613 :                 dn->valid_case = false;
    1719             :         }
    1720             : 
    1721      603886 :         LDB_FREE(dn->casefold);
    1722      603886 :         LDB_FREE(dn->linearized);
    1723             : 
    1724             :         /* Wipe the ext_linearized DN,
    1725             :          * the GUID and SID are almost certainly no longer valid */
    1726      603886 :         LDB_FREE(dn->ext_linearized);
    1727      603886 :         LDB_FREE(dn->ext_components);
    1728      603886 :         dn->ext_comp_num = 0;
    1729             : 
    1730      603886 :         return true;
    1731             : }
    1732             : 
    1733    13026903 : bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
    1734             : {
    1735      785133 :         unsigned int i, j;
    1736             : 
    1737    13026903 :         if ( ! ldb_dn_validate(dn)) {
    1738           0 :                 return false;
    1739             :         }
    1740             : 
    1741    13026903 :         if (dn->comp_num < num) {
    1742           1 :                 return false;
    1743             :         }
    1744             : 
    1745    84243489 :         for (i = 0, j = num; j < dn->comp_num; i++, j++) {
    1746    71216587 :                 if (i < num) {
    1747    13025592 :                         LDB_FREE(dn->components[i].name);
    1748    13025592 :                         LDB_FREE(dn->components[i].value.data);
    1749    13025592 :                         LDB_FREE(dn->components[i].cf_name);
    1750    13025592 :                         LDB_FREE(dn->components[i].cf_value.data);
    1751             :                 }
    1752    71216587 :                 dn->components[i] = dn->components[j];
    1753             :         }
    1754             : 
    1755    13026902 :         dn->comp_num -= num;
    1756             : 
    1757    13026902 :         if (dn->valid_case) {
    1758    61316188 :                 for (i = 0; i < dn->comp_num; i++) {
    1759    51849733 :                         LDB_FREE(dn->components[i].cf_name);
    1760    51849733 :                         LDB_FREE(dn->components[i].cf_value.data);
    1761             :                 }
    1762     9466455 :                 dn->valid_case = false;
    1763             :         }
    1764             : 
    1765    13026902 :         LDB_FREE(dn->casefold);
    1766    13026902 :         LDB_FREE(dn->linearized);
    1767             : 
    1768             :         /* Wipe the ext_linearized DN,
    1769             :          * the GUID and SID are almost certainly no longer valid */
    1770    13026902 :         LDB_FREE(dn->ext_linearized);
    1771    13026902 :         LDB_FREE(dn->ext_components);
    1772    13026902 :         dn->ext_comp_num = 0;
    1773             : 
    1774    13026902 :         return true;
    1775             : }
    1776             : 
    1777             : 
    1778             : /* replace the components of a DN with those from another DN, without
    1779             :  * touching the extended components
    1780             :  *
    1781             :  * return true if successful and false if not
    1782             :  * if false is returned the dn may be marked invalid
    1783             :  */
    1784      129673 : bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn)
    1785             : {
    1786        1636 :         unsigned int i;
    1787             : 
    1788      129673 :         if ( ! ldb_dn_validate(dn) || ! ldb_dn_validate(new_dn)) {
    1789           0 :                 return false;
    1790             :         }
    1791             : 
    1792             :         /* free components */
    1793      896816 :         for (i = 0; i < dn->comp_num; i++) {
    1794      767143 :                 LDB_FREE(dn->components[i].name);
    1795      767143 :                 LDB_FREE(dn->components[i].value.data);
    1796      767143 :                 LDB_FREE(dn->components[i].cf_name);
    1797      767143 :                 LDB_FREE(dn->components[i].cf_value.data);
    1798             :         }
    1799             : 
    1800      129673 :         dn->components = talloc_realloc(dn,
    1801             :                                         dn->components,
    1802             :                                         struct ldb_dn_component,
    1803             :                                         new_dn->comp_num);
    1804      129673 :         if (dn->components == NULL) {
    1805           0 :                 ldb_dn_mark_invalid(dn);
    1806           0 :                 return false;
    1807             :         }
    1808             : 
    1809      129673 :         dn->comp_num = new_dn->comp_num;
    1810      129673 :         dn->valid_case = new_dn->valid_case;
    1811             : 
    1812      774772 :         for (i = 0; i < dn->comp_num; i++) {
    1813      645099 :                 dn->components[i] = ldb_dn_copy_component(dn->components, &new_dn->components[i]);
    1814      645099 :                 if (dn->components[i].name == NULL) {
    1815           0 :                         ldb_dn_mark_invalid(dn);
    1816           0 :                         return false;
    1817             :                 }
    1818             :         }
    1819      129673 :         if (new_dn->linearized == NULL) {
    1820           0 :                 dn->linearized = NULL;
    1821             :         } else {
    1822      129673 :                 dn->linearized = talloc_strdup(dn, new_dn->linearized);
    1823      129673 :                 if (dn->linearized == NULL) {
    1824           0 :                         ldb_dn_mark_invalid(dn);
    1825           0 :                         return false;
    1826             :                 }
    1827             :         }
    1828             : 
    1829      128037 :         return true;
    1830             : }
    1831             : 
    1832             : 
    1833    13022505 : struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1834             : {
    1835      785103 :         struct ldb_dn *new_dn;
    1836             : 
    1837    13022505 :         new_dn = ldb_dn_copy(mem_ctx, dn);
    1838    13022505 :         if ( !new_dn ) {
    1839           2 :                 return NULL;
    1840             :         }
    1841             : 
    1842    13022503 :         if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
    1843           1 :                 talloc_free(new_dn);
    1844           1 :                 return NULL;
    1845             :         }
    1846             : 
    1847    12237399 :         return new_dn;
    1848             : }
    1849             : 
    1850             : /* Create a 'canonical name' string from a DN:
    1851             : 
    1852             :    ie dc=samba,dc=org -> samba.org/
    1853             :       uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
    1854             : 
    1855             :    There are two formats,
    1856             :    the EX format has the last '/' replaced with a newline (\n).
    1857             : 
    1858             : */
    1859     2660892 : static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) {
    1860      152152 :         unsigned int i;
    1861      152152 :         TALLOC_CTX *tmpctx;
    1862     2660892 :         char *cracked = NULL;
    1863     2660892 :         const char *format = (ex_format ? "\n" : "/" );
    1864             : 
    1865     2660892 :         if ( ! ldb_dn_validate(dn)) {
    1866           0 :                 return NULL;
    1867             :         }
    1868             : 
    1869     2660892 :         tmpctx = talloc_new(mem_ctx);
    1870             : 
    1871             :         /* Walk backwards down the DN, grabbing 'dc' components at first */
    1872    11550723 :         for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) {
    1873    11255672 :                 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
    1874     2222842 :                         break;
    1875             :                 }
    1876     8889831 :                 if (cracked) {
    1877     6229077 :                         cracked = talloc_asprintf(tmpctx, "%s.%s",
    1878             :                                                   ldb_dn_escape_value(tmpctx,
    1879     5902819 :                                                         dn->components[i].value),
    1880             :                                                   cracked);
    1881             :                 } else {
    1882     2660754 :                         cracked = ldb_dn_escape_value(tmpctx,
    1883     2508736 :                                                         dn->components[i].value);
    1884             :                 }
    1885     8889831 :                 if (!cracked) {
    1886           0 :                         goto done;
    1887             :                 }
    1888             :         }
    1889             : 
    1890             :         /* Only domain components?  Finish here */
    1891     2660892 :         if (i == (unsigned int) -1) {
    1892      295051 :                 cracked = talloc_strdup_append_buffer(cracked, format);
    1893      295051 :                 talloc_steal(mem_ctx, cracked);
    1894      295051 :                 goto done;
    1895             :         }
    1896             : 
    1897             :         /* Now walk backwards appending remaining components */
    1898     6508651 :         for (; i > 0; i--) {
    1899     4142810 :                 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
    1900             :                                                         ldb_dn_escape_value(tmpctx,
    1901     4142810 :                                                         dn->components[i].value));
    1902     4142810 :                 if (!cracked) {
    1903           0 :                         goto done;
    1904             :                 }
    1905             :         }
    1906             : 
    1907             :         /* Last one, possibly a newline for the 'ex' format */
    1908     2365841 :         cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
    1909             :                                                 ldb_dn_escape_value(tmpctx,
    1910     2365841 :                                                         dn->components[i].value));
    1911             : 
    1912     2365841 :         talloc_steal(mem_ctx, cracked);
    1913     2660892 : done:
    1914     2660892 :         talloc_free(tmpctx);
    1915     2660892 :         return cracked;
    1916             : }
    1917             : 
    1918             : /* Wrapper functions for the above, for the two different string formats */
    1919     2660629 : char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
    1920     2660629 :         return ldb_dn_canonical(mem_ctx, dn, 0);
    1921             : 
    1922             : }
    1923             : 
    1924         263 : char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
    1925         263 :         return ldb_dn_canonical(mem_ctx, dn, 1);
    1926             : }
    1927             : 
    1928    26256457 : int ldb_dn_get_comp_num(struct ldb_dn *dn)
    1929             : {
    1930    26256457 :         if ( ! ldb_dn_validate(dn)) {
    1931         176 :                 return -1;
    1932             :         }
    1933    26256277 :         return dn->comp_num;
    1934             : }
    1935             : 
    1936    14791948 : int ldb_dn_get_extended_comp_num(struct ldb_dn *dn)
    1937             : {
    1938    14791948 :         if ( ! ldb_dn_validate(dn)) {
    1939         176 :                 return -1;
    1940             :         }
    1941    14791768 :         return dn->ext_comp_num;
    1942             : }
    1943             : 
    1944        9145 : const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
    1945             : {
    1946        9145 :         if ( ! ldb_dn_validate(dn)) {
    1947           0 :                 return NULL;
    1948             :         }
    1949        9145 :         if (num >= dn->comp_num) return NULL;
    1950        9137 :         return dn->components[num].name;
    1951             : }
    1952             : 
    1953      600160 : const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
    1954             :                                                 unsigned int num)
    1955             : {
    1956      600160 :         if ( ! ldb_dn_validate(dn)) {
    1957           0 :                 return NULL;
    1958             :         }
    1959      600160 :         if (num >= dn->comp_num) return NULL;
    1960      600160 :         return &dn->components[num].value;
    1961             : }
    1962             : 
    1963    70576582 : const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
    1964             : {
    1965    70576582 :         if ( ! ldb_dn_validate(dn)) {
    1966           0 :                 return NULL;
    1967             :         }
    1968    70576582 :         if (dn->comp_num == 0) return NULL;
    1969    56669130 :         return dn->components[0].name;
    1970             : }
    1971             : 
    1972    56364007 : const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
    1973             : {
    1974    56364007 :         if ( ! ldb_dn_validate(dn)) {
    1975           2 :                 return NULL;
    1976             :         }
    1977    56364005 :         if (dn->comp_num == 0) return NULL;
    1978    42456553 :         return &dn->components[0].value;
    1979             : }
    1980             : 
    1981     1227653 : int ldb_dn_set_component(struct ldb_dn *dn, int num,
    1982             :                          const char *name, const struct ldb_val val)
    1983             : {
    1984      156832 :         char *n;
    1985      156832 :         struct ldb_val v;
    1986             : 
    1987     1227653 :         if ( ! ldb_dn_validate(dn)) {
    1988           0 :                 return LDB_ERR_OTHER;
    1989             :         }
    1990             : 
    1991     1227653 :         if (num < 0) {
    1992           0 :                 return LDB_ERR_OTHER;
    1993             :         }
    1994             : 
    1995     1227653 :         if ((unsigned)num >= dn->comp_num) {
    1996           2 :                 return LDB_ERR_OTHER;
    1997             :         }
    1998             : 
    1999     1227651 :         if (val.length > val.length + 1) {
    2000           0 :                 return LDB_ERR_OTHER;
    2001             :         }
    2002             : 
    2003     1227651 :         n = talloc_strdup(dn, name);
    2004     1227651 :         if ( ! n) {
    2005           0 :                 return LDB_ERR_OTHER;
    2006             :         }
    2007             : 
    2008     1227651 :         v.length = val.length;
    2009             : 
    2010             :         /*
    2011             :          * This is like talloc_memdup(dn, v.data, v.length + 1), but
    2012             :          * avoids the over-read
    2013             :          */
    2014     1227651 :         v.data = (uint8_t *)talloc_size(dn, v.length+1);
    2015     1227651 :         if ( ! v.data) {
    2016           0 :                 talloc_free(n);
    2017           0 :                 return LDB_ERR_OTHER;
    2018             :         }
    2019     1227651 :         memcpy(v.data, val.data, val.length);
    2020             : 
    2021             :         /*
    2022             :          * Enforce NUL termination outside the stated length, as is
    2023             :          * traditional in LDB
    2024             :          */
    2025     1227651 :         v.data[v.length] = '\0';
    2026             : 
    2027     1227651 :         talloc_free(dn->components[num].name);
    2028     1227651 :         talloc_free(dn->components[num].value.data);
    2029     1227651 :         dn->components[num].name = n;
    2030     1227651 :         dn->components[num].value = v;
    2031             : 
    2032     1227651 :         if (dn->valid_case) {
    2033             :                 unsigned int i;
    2034     4942671 :                 for (i = 0; i < dn->comp_num; i++) {
    2035     4270899 :                         LDB_FREE(dn->components[i].cf_name);
    2036     4270899 :                         LDB_FREE(dn->components[i].cf_value.data);
    2037             :                 }
    2038      671772 :                 dn->valid_case = false;
    2039             :         }
    2040     1227651 :         LDB_FREE(dn->casefold);
    2041     1227651 :         LDB_FREE(dn->linearized);
    2042             : 
    2043             :         /* Wipe the ext_linearized DN,
    2044             :          * the GUID and SID are almost certainly no longer valid */
    2045     1227651 :         LDB_FREE(dn->ext_linearized);
    2046     1227651 :         LDB_FREE(dn->ext_components);
    2047     1227651 :         dn->ext_comp_num = 0;
    2048             : 
    2049     1227651 :         return LDB_SUCCESS;
    2050             : }
    2051             : 
    2052   258575068 : const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
    2053             :                                                     const char *name)
    2054             : {
    2055     6820075 :         unsigned int i;
    2056   258575068 :         if ( ! ldb_dn_validate(dn)) {
    2057         710 :                 return NULL;
    2058             :         }
    2059   323562933 :         for (i=0; i < dn->ext_comp_num; i++) {
    2060   129089138 :                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
    2061    64100563 :                         return &dn->ext_components[i].value;
    2062             :                 }
    2063             :         }
    2064   189321874 :         return NULL;
    2065             : }
    2066             : 
    2067   157702994 : int ldb_dn_set_extended_component(struct ldb_dn *dn,
    2068             :                                   const char *name, const struct ldb_val *val)
    2069             : {
    2070     3756199 :         struct ldb_dn_ext_component *p;
    2071     3756199 :         unsigned int i;
    2072     3756199 :         struct ldb_val v2;
    2073     3756199 :         const struct ldb_dn_extended_syntax *ext_syntax;
    2074             :         
    2075   157702994 :         if ( ! ldb_dn_validate(dn)) {
    2076           0 :                 return LDB_ERR_OTHER;
    2077             :         }
    2078             : 
    2079   157702994 :         ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
    2080   157702994 :         if (ext_syntax == NULL) {
    2081             :                 /* We don't know how to handle this type of thing */
    2082           0 :                 return LDB_ERR_INVALID_DN_SYNTAX;
    2083             :         }
    2084             : 
    2085   249745845 :         for (i=0; i < dn->ext_comp_num; i++) {
    2086    92053587 :                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
    2087       10736 :                         if (val) {
    2088       10736 :                                 dn->ext_components[i].value =
    2089       10736 :                                         ldb_val_dup(dn->ext_components, val);
    2090             : 
    2091       10736 :                                 dn->ext_components[i].name = ext_syntax->name;
    2092       10736 :                                 if (!dn->ext_components[i].value.data) {
    2093           0 :                                         ldb_dn_mark_invalid(dn);
    2094           0 :                                         return LDB_ERR_OPERATIONS_ERROR;
    2095             :                                 }
    2096             :                         } else {
    2097           0 :                                 ARRAY_DEL_ELEMENT(
    2098             :                                         dn->ext_components,
    2099             :                                         i,
    2100           0 :                                         dn->ext_comp_num);
    2101           0 :                                 dn->ext_comp_num--;
    2102             : 
    2103           0 :                                 dn->ext_components = talloc_realloc(dn,
    2104             :                                                    dn->ext_components,
    2105             :                                                    struct ldb_dn_ext_component,
    2106             :                                                    dn->ext_comp_num);
    2107           0 :                                 if (!dn->ext_components) {
    2108           0 :                                         ldb_dn_mark_invalid(dn);
    2109           0 :                                         return LDB_ERR_OPERATIONS_ERROR;
    2110             :                                 }
    2111             :                         }
    2112       10736 :                         LDB_FREE(dn->ext_linearized);
    2113             : 
    2114       10736 :                         return LDB_SUCCESS;
    2115             :                 }
    2116             :         }
    2117             : 
    2118   157692258 :         if (val == NULL) {
    2119             :                 /* removing a value that doesn't exist is not an error */
    2120           0 :                 return LDB_SUCCESS;
    2121             :         }
    2122             : 
    2123   157692258 :         v2 = *val;
    2124             : 
    2125   161448397 :         p = dn->ext_components
    2126   157692258 :                 = talloc_realloc(dn,
    2127             :                                  dn->ext_components,
    2128             :                                  struct ldb_dn_ext_component,
    2129             :                                  dn->ext_comp_num + 1);
    2130   157692258 :         if (!dn->ext_components) {
    2131           0 :                 ldb_dn_mark_invalid(dn);
    2132           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2133             :         }
    2134             : 
    2135   157692258 :         p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2);
    2136   157692258 :         p[dn->ext_comp_num].name = talloc_strdup(p, name);
    2137             : 
    2138   157692258 :         if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
    2139           0 :                 ldb_dn_mark_invalid(dn);
    2140           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2141             :         }
    2142   157692258 :         dn->ext_components = p;
    2143   157692258 :         dn->ext_comp_num++;
    2144             : 
    2145   157692258 :         LDB_FREE(dn->ext_linearized);
    2146             : 
    2147   153936119 :         return LDB_SUCCESS;
    2148             : }
    2149             : 
    2150    46042406 : void ldb_dn_remove_extended_components(struct ldb_dn *dn)
    2151             : {
    2152    46042406 :         LDB_FREE(dn->ext_linearized);
    2153    46042406 :         LDB_FREE(dn->ext_components);
    2154    46042406 :         dn->ext_comp_num = 0;
    2155    46042406 : }
    2156             : 
    2157        4504 : bool ldb_dn_is_valid(struct ldb_dn *dn)
    2158             : {
    2159        4504 :         if ( ! dn) return false;
    2160        4504 :         return ! dn->invalid;
    2161             : }
    2162             : 
    2163  1865619000 : bool ldb_dn_is_special(struct ldb_dn *dn)
    2164             : {
    2165  1865619000 :         if ( ! dn || dn->invalid) return false;
    2166  1865618999 :         return dn->special;
    2167             : }
    2168             : 
    2169   462967751 : bool ldb_dn_has_extended(struct ldb_dn *dn)
    2170             : {
    2171   462967751 :         if ( ! dn || dn->invalid) return false;
    2172   462967751 :         if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
    2173   448071327 :         return dn->ext_comp_num != 0;
    2174             : }
    2175             : 
    2176    15745040 : bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
    2177             : {
    2178    15745040 :         if ( ! dn || dn->invalid) return false;
    2179    15745040 :         return ! strcmp(dn->linearized, check);
    2180             : }
    2181             : 
    2182   399233297 : bool ldb_dn_is_null(struct ldb_dn *dn)
    2183             : {
    2184   399233297 :         if ( ! dn || dn->invalid) return false;
    2185   399233297 :         if (ldb_dn_has_extended(dn)) return false;
    2186   346429546 :         if (dn->linearized && (dn->linearized[0] == '\0')) return true;
    2187   309298945 :         return false;
    2188             : }
    2189             : 
    2190             : /*
    2191             :   this updates dn->components, taking the components from ref_dn.
    2192             :   This is used by code that wants to update the DN path of a DN
    2193             :   while not impacting on the extended DN components
    2194             :  */
    2195       11009 : int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn)
    2196             : {
    2197       11009 :         dn->components = talloc_realloc(dn, dn->components,
    2198             :                                         struct ldb_dn_component, ref_dn->comp_num);
    2199       11009 :         if (!dn->components) {
    2200           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2201             :         }
    2202       11009 :         memcpy(dn->components, ref_dn->components,
    2203       11009 :                sizeof(struct ldb_dn_component)*ref_dn->comp_num);
    2204       11009 :         dn->comp_num = ref_dn->comp_num;
    2205             : 
    2206       11009 :         LDB_FREE(dn->casefold);
    2207       11009 :         LDB_FREE(dn->linearized);
    2208       11009 :         LDB_FREE(dn->ext_linearized);
    2209             : 
    2210       10956 :         return LDB_SUCCESS;
    2211             : }
    2212             : 
    2213             : /*
    2214             :   minimise a DN. The caller must pass in a validated DN.
    2215             : 
    2216             :   If the DN has an extended component then only the first extended
    2217             :   component is kept, the DN string is stripped.
    2218             : 
    2219             :   The existing dn is modified
    2220             :  */
    2221     8073355 : bool ldb_dn_minimise(struct ldb_dn *dn)
    2222             : {
    2223      292787 :         unsigned int i;
    2224             : 
    2225     8073355 :         if (!ldb_dn_validate(dn)) {
    2226           0 :                 return false;
    2227             :         }
    2228     8073355 :         if (dn->ext_comp_num == 0) {
    2229           0 :                 return true;
    2230             :         }
    2231             : 
    2232             :         /* free components */
    2233    41337708 :         for (i = 0; i < dn->comp_num; i++) {
    2234    33264353 :                 LDB_FREE(dn->components[i].name);
    2235    33264353 :                 LDB_FREE(dn->components[i].value.data);
    2236    33264353 :                 LDB_FREE(dn->components[i].cf_name);
    2237    33264353 :                 LDB_FREE(dn->components[i].cf_value.data);
    2238             :         }
    2239     8073355 :         dn->comp_num = 0;
    2240     8073355 :         dn->valid_case = false;
    2241             : 
    2242     8073355 :         LDB_FREE(dn->casefold);
    2243     8073355 :         LDB_FREE(dn->linearized);
    2244             : 
    2245             :         /* note that we don't free dn->components as this there are
    2246             :          * several places in ldb_dn.c that rely on it being non-NULL
    2247             :          * for an exploded DN
    2248             :          */
    2249             : 
    2250    11485747 :         for (i = 1; i < dn->ext_comp_num; i++) {
    2251     3412392 :                 LDB_FREE(dn->ext_components[i].value.data);
    2252             :         }
    2253     8073355 :         dn->ext_comp_num = 1;
    2254             : 
    2255     8073355 :         dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1);
    2256     8073355 :         if (dn->ext_components == NULL) {
    2257           0 :                 ldb_dn_mark_invalid(dn);
    2258           0 :                 return false;
    2259             :         }
    2260             : 
    2261     8073355 :         LDB_FREE(dn->ext_linearized);
    2262             : 
    2263     7780568 :         return true;
    2264             : }
    2265             : 
    2266   155969315 : struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn)
    2267             : {
    2268   155969315 :         return dn->ldb;
    2269             : }

Generated by: LCOV version 1.14