LCOV - code coverage report
Current view: top level - lib/ldb/common - ldb_dn.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-lts cc996e7c Lines: 863 1067 80.9 %
Date: 2025-10-17 03:45:34 Functions: 50 51 98.0 %

          Line data    Source code
       1             : /*
       2             :    ldb database library
       3             : 
       4             :    Copyright (C) Simo Sorce 2005
       5             : 
       6             :      ** NOTE! The following LGPL license applies to the ldb
       7             :      ** library. This does NOT imply that all of Samba is released
       8             :      ** under the LGPL
       9             : 
      10             :    This library is free software; you can redistribute it and/or
      11             :    modify it under the terms of the GNU Lesser General Public
      12             :    License as published by the Free Software Foundation; either
      13             :    version 3 of the License, or (at your option) any later version.
      14             : 
      15             :    This library is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      18             :    Lesser General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU Lesser General Public
      21             :    License along with this library; if not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : /*
      25             :  *  Name: ldb
      26             :  *
      27             :  *  Component: ldb dn creation and manipulation utility functions
      28             :  *
      29             :  *  Description: - explode a dn into it's own basic elements
      30             :  *                 and put them in a structure (only if necessary)
      31             :  *               - manipulate ldb_dn structures
      32             :  *
      33             :  *  Author: Simo Sorce
      34             :  */
      35             : 
      36             : #include "ldb_private.h"
      37             : #include <ctype.h>
      38             : 
      39             : #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
      40             : 
      41             : #define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0)
      42             : 
      43             : /**
      44             :    internal ldb exploded dn structures
      45             : */
      46             : struct ldb_dn_component {
      47             : 
      48             :         char *name;
      49             :         struct ldb_val value;
      50             : 
      51             :         char *cf_name;
      52             :         struct ldb_val cf_value;
      53             : };
      54             : 
      55             : struct ldb_dn_ext_component {
      56             : 
      57             :         const char *name;
      58             :         struct ldb_val value;
      59             : };
      60             : 
      61             : struct ldb_dn {
      62             : 
      63             :         struct ldb_context *ldb;
      64             : 
      65             :         /* Special DNs are always linearized */
      66             :         bool special;
      67             :         bool invalid;
      68             : 
      69             :         bool valid_case;
      70             : 
      71             :         char *linearized;
      72             :         char *ext_linearized;
      73             :         char *casefold;
      74             : 
      75             :         unsigned int comp_num;
      76             :         struct ldb_dn_component *components;
      77             : 
      78             :         unsigned int ext_comp_num;
      79             :         struct ldb_dn_ext_component *ext_components;
      80             : };
      81             : 
      82             : /* it is helpful to be able to break on this in gdb */
      83       17910 : static void ldb_dn_mark_invalid(struct ldb_dn *dn)
      84             : {
      85       17910 :         dn->invalid = true;
      86       17910 : }
      87             : 
      88             : /* strdn may be NULL */
      89   611834276 : 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             :         struct ldb_dn *dn;
      94             : 
      95   611834276 :         if (ldb == NULL || strdn == NULL) {
      96           0 :                 return NULL;
      97             :         }
      98   611834276 :         if (strdn->data
      99   591771175 :             && (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   611834276 :         dn = talloc_zero(mem_ctx, struct ldb_dn);
     105   611834276 :         LDB_DN_NULL_FAILED(dn);
     106             : 
     107   611834276 :         dn->ldb = talloc_get_type(ldb, struct ldb_context);
     108   611834276 :         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  1202896681 :         if (strdn->data && strdn->length) {
     116   591062405 :                 const char *data = (const char *)strdn->data;
     117   591062405 :                 size_t length = strdn->length;
     118             : 
     119   591062405 :                 if (data[0] == '@') {
     120   262166325 :                         dn->special = true;
     121             :                 }
     122   591062405 :                 dn->ext_linearized = talloc_strndup(dn, data, length);
     123   591062405 :                 LDB_DN_NULL_FAILED(dn->ext_linearized);
     124             : 
     125   591062405 :                 if (data[0] == '<') {
     126    28325864 :                         const char *p_save, *p = dn->ext_linearized;
     127             :                         do {
     128    65259775 :                                 p_save = p;
     129    65259775 :                                 p = strstr(p, ">;");
     130    65259775 :                                 if (p) {
     131    36933911 :                                         p = p + 2;
     132             :                                 }
     133    65259775 :                         } while (p);
     134             : 
     135    28325864 :                         if (p_save == dn->ext_linearized) {
     136     6150669 :                                 dn->linearized = talloc_strdup(dn, "");
     137             :                         } else {
     138    22175195 :                                 dn->linearized = talloc_strdup(dn, p_save);
     139             :                         }
     140    28325864 :                         LDB_DN_NULL_FAILED(dn->linearized);
     141             :                 } else {
     142   562736541 :                         dn->linearized = dn->ext_linearized;
     143   562736541 :                         dn->ext_linearized = NULL;
     144             :                 }
     145             :         } else {
     146    20771871 :                 dn->linearized = talloc_strdup(dn, "");
     147    20771871 :                 LDB_DN_NULL_FAILED(dn->linearized);
     148             :         }
     149             : 
     150   611834276 :         return dn;
     151             : 
     152           0 : failed:
     153           0 :         talloc_free(dn);
     154           0 :         return NULL;
     155             : }
     156             : 
     157             : /* strdn may be NULL */
     158   225170831 : struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx,
     159             :                           struct ldb_context *ldb,
     160             :                           const char *strdn)
     161             : {
     162             :         struct ldb_val blob;
     163   225170831 :         blob.data = discard_const_p(uint8_t, strdn);
     164   225170831 :         blob.length = strdn ? strlen(strdn) : 0;
     165   225170831 :         return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
     166             : }
     167             : 
     168   137880959 : struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx,
     169             :                               struct ldb_context *ldb,
     170             :                               const char *new_fmt, ...)
     171             : {
     172             :         char *strdn;
     173             :         va_list ap;
     174             : 
     175   137880959 :         if (! ldb) return NULL;
     176             : 
     177   137880959 :         va_start(ap, new_fmt);
     178   137880959 :         strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
     179   137880959 :         va_end(ap);
     180             : 
     181   137880959 :         if (strdn) {
     182   137880959 :                 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
     183   137880959 :                 talloc_free(strdn);
     184   137880959 :                 return dn;
     185             :         }
     186             : 
     187           0 :         return NULL;
     188             : }
     189             : 
     190             : /* see RFC2253 section 2.4 */
     191   168101910 : static int ldb_dn_escape_internal(char *dst, const char *src, int len)
     192             : {
     193             :         char c;
     194             :         char *d;
     195             :         int i;
     196   168101910 :         d = dst;
     197             : 
     198  1610433143 :         for (i = 0; i < len; i++){
     199  1442331233 :                 c = src[i];
     200  1442331233 :                 switch (c) {
     201     8366433 :                 case ' ':
     202     8366433 :                         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     8366433 :                                 *d++ = c;
     210             :                         }
     211     8366433 :                         break;
     212             : 
     213       18225 :                 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       18225 :                         *d++ = '\\';
     225       18225 :                         *d++ = c;
     226       18225 :                         break;
     227             : 
     228     1115761 :                 case ';':
     229             :                 case '\r':
     230             :                 case '\n':
     231             :                 case '=':
     232             :                 case '\0': {
     233             :                         /* any others get \XX form */
     234             :                         unsigned char v;
     235     1115761 :                         const char *hexbytes = "0123456789ABCDEF";
     236     1115761 :                         v = (const unsigned char)c;
     237     1115761 :                         *d++ = '\\';
     238     1115761 :                         *d++ = hexbytes[v>>4];
     239     1115761 :                         *d++ = hexbytes[v&0xF];
     240     1115761 :                         break;
     241             :                 }
     242  1432830814 :                 default:
     243  1432830814 :                         *d++ = c;
     244             :                 }
     245             :         }
     246             : 
     247             :         /* return the length of the resulting string */
     248   168101910 :         return (d - dst);
     249             : }
     250             : 
     251    10529858 : char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value)
     252             : {
     253             :         char *dst;
     254             :         size_t len;
     255    10529858 :         if (!value.length)
     256           2 :                 return NULL;
     257             : 
     258             :         /* allocate destination string, it will be at most 3 times the source */
     259    10529856 :         dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
     260    10529856 :         if ( ! dst) {
     261           0 :                 talloc_free(dst);
     262           0 :                 return NULL;
     263             :         }
     264             : 
     265    10529856 :         len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
     266             : 
     267    10529856 :         dst = talloc_realloc(mem_ctx, dst, char, len + 1);
     268    10529856 :         if ( ! dst) {
     269           0 :                 talloc_free(dst);
     270           0 :                 return NULL;
     271             :         }
     272    10529856 :         dst[len] = '\0';
     273    10529856 :         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   801185529 : static bool ldb_dn_explode(struct ldb_dn *dn)
     284             : {
     285   801185529 :         char *p, *ex_name = NULL, *ex_value = NULL, *data, *d, *dt, *t;
     286   801185529 :         bool trim = true;
     287   801185529 :         bool in_extended = true;
     288   801185529 :         bool in_ex_name = false;
     289   801185529 :         bool in_ex_value = false;
     290   801185529 :         bool in_attr = false;
     291   801185529 :         bool in_value = false;
     292   801185529 :         bool in_quote = false;
     293   801185529 :         bool is_oid = false;
     294   801185529 :         bool escape = false;
     295             :         unsigned int x;
     296   801185529 :         size_t l = 0;
     297             :         int ret;
     298             :         char *parse_dn;
     299             :         bool is_index;
     300             : 
     301   801185529 :         if (dn == NULL || dn->invalid) {
     302          11 :                 return false;
     303             :         }
     304             : 
     305   801185518 :         if (dn->components != NULL) {
     306   426108909 :                 return true;
     307             :         }
     308             : 
     309   375076609 :         if (dn->ext_linearized != NULL) {
     310    25967902 :                 parse_dn = dn->ext_linearized;
     311             :         } else {
     312   349108707 :                 parse_dn = dn->linearized;
     313             :         }
     314             : 
     315   375076609 :         if (parse_dn == NULL) {
     316           0 :                 return false;
     317             :         }
     318             : 
     319   375076609 :         is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
     320             : 
     321             :         /* Empty DNs */
     322   375076609 :         if (parse_dn[0] == '\0') {
     323    20301400 :                 return true;
     324             :         }
     325             : 
     326             :         /* Special DNs case */
     327   354775209 :         if (dn->special) {
     328   168622545 :                 return true;
     329             :         }
     330             : 
     331   186152664 :         LDB_FREE(dn->ext_components);
     332   186152664 :         dn->ext_comp_num = 0;
     333   186152664 :         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   186152664 :         dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
     338   186152664 :         if (dn->components == NULL) {
     339           0 :                 return false;
     340             :         }
     341             : 
     342             :         /* Components data space is allocated here once */
     343   186152664 :         data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
     344   186152664 :         if (data == NULL) {
     345           0 :                 goto failed;
     346             :         }
     347             : 
     348   186152664 :         p = parse_dn;
     349   186152664 :         t = NULL;
     350   186152664 :         d = dt = data;
     351             : 
     352 17770929610 :         while (*p) {
     353 17449053795 :                 if (in_extended) {
     354             : 
     355  1775677701 :                         if (!in_ex_name && !in_ex_value) {
     356             : 
     357   219694776 :                                 if (p[0] == '<') {
     358    39692793 :                                         p++;
     359    39692793 :                                         ex_name = d;
     360    39692793 :                                         in_ex_name = true;
     361    39692793 :                                         continue;
     362             :                                 } else {
     363   180001983 :                                         in_extended = false;
     364   180001983 :                                         in_attr = true;
     365   180001983 :                                         dt = d;
     366             : 
     367   180001983 :                                         continue;
     368             :                                 }
     369             :                         }
     370             : 
     371  1555982925 :                         if (in_ex_name && *p == '=') {
     372    39692789 :                                 *d++ = '\0';
     373    39692789 :                                 p++;
     374    39692789 :                                 ex_value = d;
     375    39692789 :                                 in_ex_name = false;
     376    39692789 :                                 in_ex_value = true;
     377    39692789 :                                 continue;
     378             :                         }
     379             : 
     380  1516290136 :                         if (in_ex_value && *p == '>') {
     381    39692789 :                                 struct ldb_dn_ext_component *ext_comp = NULL;
     382             :                                 const struct ldb_dn_extended_syntax *ext_syntax;
     383    75757198 :                                 struct ldb_val ex_val = {
     384             :                                         .data = (uint8_t *)ex_value,
     385    39692789 :                                         .length = d - ex_value
     386             :                                 };
     387             : 
     388    39692789 :                                 *d++ = '\0';
     389    39692789 :                                 p++;
     390    39692789 :                                 in_ex_value = false;
     391             : 
     392             :                                 /* Process name and ex_value */
     393             : 
     394    39692789 :                                 ext_comp = talloc_realloc(
     395             :                                         dn,
     396             :                                         dn->ext_components,
     397             :                                         struct ldb_dn_ext_component,
     398             :                                         dn->ext_comp_num + 1);
     399             : 
     400    39692789 :                                 if (ext_comp == NULL) {
     401             :                                         /* ouch ! */
     402          10 :                                         goto failed;
     403             :                                 }
     404             : 
     405    39692789 :                                 dn->ext_components = ext_comp;
     406             : 
     407    39692789 :                                 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
     408    39692789 :                                 if (ext_syntax == NULL) {
     409             :                                         /* We don't know about this type of extended DN */
     410           8 :                                         goto failed;
     411             :                                 }
     412             : 
     413    39692781 :                                 dn->ext_components[dn->ext_comp_num].name = ext_syntax->name;
     414    75757182 :                                 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
     415    39692781 :                                                           &ex_val, &dn->ext_components[dn->ext_comp_num].value);
     416    39692781 :                                 if (ret != LDB_SUCCESS) {
     417           2 :                                         ldb_dn_mark_invalid(dn);
     418           2 :                                         goto failed;
     419             :                                 }
     420             : 
     421    39692779 :                                 dn->ext_comp_num++;
     422             : 
     423    39692779 :                                 if (*p == '\0') {
     424             :                                         /* We have reached the end (extended component only)! */
     425     6150667 :                                         talloc_free(data);
     426     6150667 :                                         return true;
     427             : 
     428    33542112 :                                 } else if (*p == ';') {
     429    33542112 :                                         p++;
     430    33542112 :                                         continue;
     431             :                                 } else {
     432           0 :                                         ldb_dn_mark_invalid(dn);
     433           0 :                                         goto failed;
     434             :                                 }
     435             :                         }
     436             : 
     437  1476597347 :                         *d++ = *p++;
     438  1476597347 :                         continue;
     439             :                 }
     440 15673376094 :                 if (in_attr) {
     441  3094234976 :                         if (trim) {
     442  1030766949 :                                 if (*p == ' ') {
     443         219 :                                         p++;
     444         219 :                                         continue;
     445             :                                 }
     446             : 
     447             :                                 /* first char */
     448  1030766730 :                                 trim = false;
     449             : 
     450  1030766730 :                                 if (!isascii(*p)) {
     451             :                                         /* attr names must be ascii only */
     452           0 :                                         ldb_dn_mark_invalid(dn);
     453           0 :                                         goto failed;
     454             :                                 }
     455             : 
     456  1030766730 :                                 if (isdigit(*p)) {
     457           0 :                                         is_oid = true;
     458             :                                 } else
     459  1030766730 :                                 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  1030766723 :                                 *d++ = *p++;
     469  1030766723 :                                 continue;
     470             :                         }
     471             : 
     472  2063468027 :                         if (*p == ' ') {
     473          48 :                                 p++;
     474             :                                 /* valid only if we are at the end */
     475          48 :                                 trim = true;
     476          48 :                                 continue;
     477             :                         }
     478             : 
     479  2063467979 :                         if (*p == '=') {
     480             :                                 /* attribute terminated */
     481  1030748782 :                                 in_attr = false;
     482  1030748782 :                                 in_value = true;
     483  1030748782 :                                 trim = true;
     484  1030748782 :                                 l = 0;
     485             : 
     486             :                                 /* Terminate this string in d
     487             :                                  * (which is a copy of parse_dn
     488             :                                  *  with spaces trimmed) */
     489  1030748782 :                                 *d++ = '\0';
     490  1030748782 :                                 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
     491  1030748782 :                                 if (dn->components[dn->comp_num].name == NULL) {
     492             :                                         /* ouch */
     493           0 :                                         goto failed;
     494             :                                 }
     495             : 
     496  1030748782 :                                 dt = d;
     497             : 
     498  1030748782 :                                 p++;
     499  1030748782 :                                 continue;
     500             :                         }
     501             : 
     502  1032719197 :                         if (!isascii(*p)) {
     503             :                                 /* attr names must be ascii only */
     504           0 :                                 ldb_dn_mark_invalid(dn);
     505           0 :                                 goto failed;
     506             :                         }
     507             : 
     508  1032719197 :                         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  1032719197 :                         if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
     515             :                                 /* not ALPHA, DIGIT or HYPHEN */
     516         409 :                                 ldb_dn_mark_invalid(dn);
     517         409 :                                 goto failed;
     518             :                         }
     519             : 
     520  1032718788 :                         *d++ = *p++;
     521  1032718788 :                         continue;
     522             :                 }
     523             : 
     524 12579141118 :                 if (in_value) {
     525 12579141118 :                         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 12579141118 :                         if (trim) {
     539  1030748774 :                                 if (*p == ' ') {
     540           0 :                                         p++;
     541           0 :                                         continue;
     542             :                                 }
     543             : 
     544             :                                 /* first char */
     545  1030748774 :                                 trim = false;
     546             : 
     547  1030748774 :                                 if (*p == '\"') {
     548           0 :                                         in_quote = true;
     549           0 :                                         p++;
     550           0 :                                         continue;
     551             :                                 }
     552             :                         }
     553             : 
     554 12579141118 :                         switch (*p) {
     555             : 
     556             :                         /* TODO: support ber encoded values
     557             :                         case '#':
     558             :                         */
     559             : 
     560   850782208 :                         case ',':
     561   850782208 :                                 if (escape) {
     562       17508 :                                         *d++ = *p++;
     563       17508 :                                         l++;
     564       17508 :                                         escape = false;
     565       17508 :                                         continue;
     566             :                                 }
     567             :                                 /* ok found value terminator */
     568             : 
     569   850764700 :                                 if (t != NULL) {
     570             :                                         /* trim back */
     571          22 :                                         d -= (p - t);
     572          22 :                                         l -= (p - t);
     573          22 :                                         t = NULL;
     574             :                                 }
     575             : 
     576   850764700 :                                 in_attr = true;
     577   850764700 :                                 in_value = false;
     578   850764700 :                                 trim = true;
     579             : 
     580   850764700 :                                 p++;
     581   850764700 :                                 *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  1701529400 :                                 dn->components[dn->comp_num].value.data = \
     589  1504199417 :                                         (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
     590   850764700 :                                 dn->components[dn->comp_num].value.length = l;
     591   850764700 :                                 if (dn->components[dn->comp_num].value.data == NULL) {
     592             :                                         /* ouch ! */
     593           0 :                                         goto failed;
     594             :                                 }
     595   850764700 :                                 talloc_set_name_const(dn->components[dn->comp_num].value.data,
     596   850764700 :                                                       (const char *)dn->components[dn->comp_num].value.data);
     597             : 
     598   850764700 :                                 dt = d;
     599             : 
     600   850764700 :                                 dn->comp_num++;
     601   850764700 :                                 if (dn->comp_num > 2) {
     602   496524515 :                                         dn->components = talloc_realloc(dn,
     603             :                                                                         dn->components,
     604             :                                                                         struct ldb_dn_component,
     605             :                                                                         dn->comp_num + 1);
     606   496524515 :                                         if (dn->components == NULL) {
     607             :                                                 /* ouch ! */
     608           0 :                                                 goto failed;
     609             :                                         }
     610             :                                         /* make sure all components are zeroed, other functions depend on this */
     611   496524515 :                                         memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
     612             :                                 }
     613             : 
     614   850764700 :                                 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             :                                 FALL_THROUGH;
     633             :                         case '\"':
     634             :                         case '<':
     635             :                         case '>':
     636             :                         case ';':
     637             :                                 /* a string with not escaped specials is invalid (tested) */
     638          14 :                                 if (!escape) {
     639           7 :                                         ldb_dn_mark_invalid(dn);
     640           7 :                                         goto failed;
     641             :                                 }
     642           7 :                                 escape = false;
     643             : 
     644           7 :                                 *d++ = *p++;
     645           7 :                                 l++;
     646             : 
     647           7 :                                 if (t != NULL) {
     648           0 :                                         t = NULL;
     649             :                                 }
     650           7 :                                 break;
     651             : 
     652    58512212 :                         case '\\':
     653    58512212 :                                 if (!escape) {
     654    58506932 :                                         escape = true;
     655    58506932 :                                         p++;
     656    58506932 :                                         continue;
     657             :                                 }
     658        5280 :                                 escape = false;
     659             : 
     660        5280 :                                 *d++ = *p++;
     661        5280 :                                 l++;
     662             : 
     663        5280 :                                 if (t != NULL) {
     664           0 :                                         t = NULL;
     665             :                                 }
     666        5280 :                                 break;
     667             : 
     668 11669846684 :                         default:
     669 11669846684 :                                 if (escape) {
     670    58484137 :                                         if (isxdigit(p[0]) && isxdigit(p[1])) {
     671    58484137 :                                                 if (sscanf(p, "%02x", &x) != 1) {
     672             :                                                         /* invalid escaping sequence */
     673           0 :                                                         ldb_dn_mark_invalid(dn);
     674           0 :                                                         goto failed;
     675             :                                                 }
     676    58484137 :                                                 p += 2;
     677    58484137 :                                                 *d++ = (unsigned char)x;
     678             :                                         } else {
     679           0 :                                                 *d++ = *p++;
     680             :                                         }
     681             : 
     682    58484137 :                                         escape = false;
     683    58484137 :                                         l++;
     684    58484137 :                                         if (t != NULL) {
     685           0 :                                                 t = NULL;
     686             :                                         }
     687    58484137 :                                         break;
     688             :                                 }
     689             : 
     690 11611362547 :                                 if (*p == ' ') {
     691    83062069 :                                         if (t == NULL) {
     692    83058399 :                                                 t = p;
     693             :                                         }
     694             :                                 } else {
     695 11528300478 :                                         if (t != NULL) {
     696    83058227 :                                                 t = NULL;
     697             :                                         }
     698             :                                 }
     699             : 
     700 11611362547 :                                 *d++ = *p++;
     701 11611362547 :                                 l++;
     702             : 
     703 11611362547 :                                 break;
     704             :                         }
     705             : 
     706           0 :                 }
     707             :         }
     708             : 
     709   180001564 :         if (in_attr || in_quote) {
     710             :                 /* invalid dn */
     711       17485 :                 ldb_dn_mark_invalid(dn);
     712       17485 :                 goto failed;
     713             :         }
     714             : 
     715   179984079 :         if (in_value) {
     716             :                 /* save last element */
     717   179984075 :                 if (t != NULL) {
     718             :                         /* trim back */
     719         150 :                         d -= (p - t);
     720         150 :                         l -= (p - t);
     721             :                 }
     722             : 
     723   179984075 :                 *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   179984075 :                 dn->components[dn->comp_num].value.length = l;
     730   359968150 :                 dn->components[dn->comp_num].value.data =
     731   316130935 :                         (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
     732   179984075 :                 if (dn->components[dn->comp_num].value.data == NULL) {
     733             :                         /* ouch */
     734           0 :                         goto failed;
     735             :                 }
     736   179984075 :                 talloc_set_name_const(dn->components[dn->comp_num].value.data,
     737   179984075 :                         (const char *)dn->components[dn->comp_num].value.data);
     738             : 
     739   179984075 :                 dn->comp_num++;
     740             :         }
     741   179984079 :         talloc_free(data);
     742   179984079 :         return true;
     743             : 
     744       17918 : failed:
     745       17918 :         LDB_FREE(dn->components); /* "data" is implicitly free'd */
     746       17918 :         dn->comp_num = 0;
     747       17918 :         LDB_FREE(dn->ext_components);
     748       17918 :         dn->ext_comp_num = 0;
     749             : 
     750       17918 :         return false;
     751             : }
     752             : 
     753   732092769 : bool ldb_dn_validate(struct ldb_dn *dn)
     754             : {
     755   732092769 :         return ldb_dn_explode(dn);
     756             : }
     757             : 
     758   528569221 : const char *ldb_dn_get_linearized(struct ldb_dn *dn)
     759             : {
     760             :         unsigned int i;
     761             :         size_t len;
     762             :         char *d, *n;
     763             : 
     764   528569221 :         if ( ! dn || ( dn->invalid)) return NULL;
     765             : 
     766   528568921 :         if (dn->linearized) return dn->linearized;
     767             : 
     768     7721704 :         if ( ! dn->components) {
     769           0 :                 ldb_dn_mark_invalid(dn);
     770           0 :                 return NULL;
     771             :         }
     772             : 
     773     7721704 :         if (dn->comp_num == 0) {
     774      200381 :                 dn->linearized = talloc_strdup(dn, "");
     775      200381 :                 if ( ! dn->linearized) return NULL;
     776      200381 :                 return dn->linearized;
     777             :         }
     778             : 
     779             :         /* calculate maximum possible length of DN */
     780    49247458 :         for (len = 0, i = 0; i < dn->comp_num; i++) {
     781             :                 /* name len */
     782    41726135 :                 len += strlen(dn->components[i].name);
     783             :                 /* max escaped data len */
     784    41726135 :                 len += (dn->components[i].value.length * 3);
     785    41726135 :                 len += 2; /* '=' and ',' */
     786             :         }
     787     7521323 :         dn->linearized = talloc_array(dn, char, len);
     788     7521323 :         if ( ! dn->linearized) return NULL;
     789             : 
     790     7521323 :         d = dn->linearized;
     791             : 
     792    49247458 :         for (i = 0; i < dn->comp_num; i++) {
     793             : 
     794             :                 /* copy the name */
     795    41726135 :                 n = dn->components[i].name;
     796    49724409 :                 while (*n) *d++ = *n++;
     797             : 
     798    41726135 :                 *d++ = '=';
     799             : 
     800             :                 /* and the value */
     801    83452270 :                 d += ldb_dn_escape_internal( d,
     802    41726135 :                                 (char *)dn->components[i].value.data,
     803    41726135 :                                 dn->components[i].value.length);
     804    41726135 :                 *d++ = ',';
     805             :         }
     806             : 
     807     7521323 :         *(--d) = '\0';
     808             : 
     809             :         /* don't waste more memory than necessary */
     810     7521323 :         dn->linearized = talloc_realloc(dn, dn->linearized,
     811             :                                         char, (d - dn->linearized + 1));
     812             : 
     813     7521323 :         return dn->linearized;
     814             : }
     815             : 
     816    12555812 : static int ldb_dn_extended_component_compare(const void *p1, const void *p2)
     817             : {
     818    12555812 :         const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1;
     819    12555812 :         const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2;
     820    12555812 :         return strcmp(ec1->name, ec2->name);
     821             : }
     822             : 
     823    17300714 : char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode)
     824             : {
     825    17300714 :         const char *linearized = ldb_dn_get_linearized(dn);
     826    17300714 :         char *p = NULL;
     827             :         unsigned int i;
     828             : 
     829    17300714 :         if (!linearized) {
     830          96 :                 return NULL;
     831             :         }
     832             : 
     833    17300618 :         if (!ldb_dn_has_extended(dn)) {
     834     1195942 :                 return talloc_strdup(mem_ctx, linearized);
     835             :         }
     836             : 
     837    16104676 :         if (!ldb_dn_validate(dn)) {
     838           3 :                 return NULL;
     839             :         }
     840             : 
     841             :         /* sort the extended components by name. The idea is to make
     842             :          * the resulting DNs consistent, plus to ensure that we put
     843             :          * 'DELETED' first, so it can be very quickly recognised
     844             :          */
     845    16104673 :         TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num,
     846             :                        ldb_dn_extended_component_compare);
     847             : 
     848    71419490 :         for (i = 0; i < dn->ext_comp_num; i++) {
     849             :                 const struct ldb_dn_extended_syntax *ext_syntax;
     850    21858376 :                 const char *name = dn->ext_components[i].name;
     851    21858376 :                 struct ldb_val ec_val = dn->ext_components[i].value;
     852             :                 struct ldb_val val;
     853             :                 int ret;
     854             : 
     855    21858376 :                 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
     856    21858376 :                 if (!ext_syntax) {
     857           0 :                         return NULL;
     858             :                 }
     859             : 
     860    21858376 :                 if (mode == 1) {
     861    13555990 :                         ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
     862             :                                                         &ec_val, &val);
     863     8302386 :                 } else if (mode == 0) {
     864     8302386 :                         ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
     865             :                                                         &ec_val, &val);
     866             :                 } else {
     867           0 :                         ret = -1;
     868             :                 }
     869             : 
     870    21858376 :                 if (ret != LDB_SUCCESS) {
     871           0 :                         return NULL;
     872             :                 }
     873             : 
     874    21858376 :                 if (i == 0) {
     875    30250587 :                         p = talloc_asprintf(mem_ctx, "<%s=%.*s>",
     876             :                                             name,
     877    16104669 :                                             (int)val.length,
     878             :                                             val.data);
     879             :                 } else {
     880    10918308 :                         p = talloc_asprintf_append_buffer(p, ";<%s=%.*s>",
     881             :                                                           name,
     882     5753707 :                                                           (int)val.length,
     883             :                                                           val.data);
     884             :                 }
     885             : 
     886    21858376 :                 talloc_free(val.data);
     887             : 
     888    21858376 :                 if (!p) {
     889           0 :                         return NULL;
     890             :                 }
     891             :         }
     892             : 
     893    16104673 :         if (dn->ext_comp_num && *linearized) {
     894    15422281 :                 p = talloc_asprintf_append_buffer(p, ";%s", linearized);
     895             :         }
     896             : 
     897    16104673 :         if (!p) {
     898           4 :                 return NULL;
     899             :         }
     900             : 
     901    16104669 :         return p;
     902             : }
     903             : 
     904             : /*
     905             :   filter out all but an acceptable list of extended DN components
     906             :  */
     907    10179682 : void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list)
     908             : {
     909             :         unsigned int i;
     910    25677386 :         for (i=0; i<dn->ext_comp_num; i++) {
     911    15497704 :                 if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) {
     912     2849344 :                         ARRAY_DEL_ELEMENT(
     913             :                                 dn->ext_components, i, dn->ext_comp_num);
     914     2849344 :                         dn->ext_comp_num--;
     915     2849344 :                         i--;
     916             :                 }
     917             :         }
     918    10179682 :         LDB_FREE(dn->ext_linearized);
     919    10179682 : }
     920             : 
     921             : 
     922   121598564 : char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
     923             : {
     924   121598564 :         return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
     925             : }
     926             : 
     927             : /*
     928             :   casefold a dn. We need to casefold the attribute names, and canonicalize
     929             :   attribute values of case insensitive attributes.
     930             : */
     931             : 
     932   196014547 : static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
     933             : {
     934             :         unsigned int i;
     935             :         int ret;
     936             : 
     937   196014547 :         if ( ! dn || dn->invalid) return false;
     938             : 
     939   196014547 :         if (dn->valid_case) return true;
     940             : 
     941    97750210 :         if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
     942         630 :                 return false;
     943             :         }
     944             : 
     945   627786378 :         for (i = 0; i < dn->comp_num; i++) {
     946             :                 const struct ldb_schema_attribute *a;
     947             : 
     948  1060073596 :                 dn->components[i].cf_name =
     949   935293556 :                         ldb_attr_casefold(dn->components,
     950   530036798 :                                           dn->components[i].name);
     951   530036798 :                 if (!dn->components[i].cf_name) {
     952           0 :                         goto failed;
     953             :                 }
     954             : 
     955   530036798 :                 a = ldb_schema_attribute_by_name(dn->ldb,
     956   530036798 :                                                  dn->components[i].cf_name);
     957             : 
     958  1340550314 :                 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
     959   530036798 :                                                  &(dn->components[i].value),
     960   530036798 :                                                  &(dn->components[i].cf_value));
     961   530036798 :                 if (ret != 0) {
     962           0 :                         goto failed;
     963             :                 }
     964             :         }
     965             : 
     966    97749580 :         dn->valid_case = true;
     967             : 
     968    97749580 :         return true;
     969             : 
     970           0 : failed:
     971           0 :         for (i = 0; i < dn->comp_num; i++) {
     972           0 :                 LDB_FREE(dn->components[i].cf_name);
     973           0 :                 LDB_FREE(dn->components[i].cf_value.data);
     974             :         }
     975           0 :         return false;
     976             : }
     977             : 
     978   320720879 : const char *ldb_dn_get_casefold(struct ldb_dn *dn)
     979             : {
     980             :         unsigned int i;
     981             :         size_t len;
     982             :         char *d, *n;
     983             : 
     984   320720879 :         if (dn->casefold) return dn->casefold;
     985             : 
     986   203506905 :         if (dn->special) {
     987   180550708 :                 dn->casefold = talloc_strdup(dn, dn->linearized);
     988   180550708 :                 if (!dn->casefold) return NULL;
     989   180550708 :                 dn->valid_case = true;
     990   180550708 :                 return dn->casefold;
     991             :         }
     992             : 
     993    22956197 :         if ( ! ldb_dn_casefold_internal(dn)) {
     994           0 :                 return NULL;
     995             :         }
     996             : 
     997    22956197 :         if (dn->comp_num == 0) {
     998        1030 :                 dn->casefold = talloc_strdup(dn, "");
     999        1030 :                 return dn->casefold;
    1000             :         }
    1001             : 
    1002             :         /* calculate maximum possible length of DN */
    1003   138801086 :         for (len = 0, i = 0; i < dn->comp_num; i++) {
    1004             :                 /* name len */
    1005   115845919 :                 len += strlen(dn->components[i].cf_name);
    1006             :                 /* max escaped data len */
    1007   115845919 :                 len += (dn->components[i].cf_value.length * 3);
    1008   115845919 :                 len += 2; /* '=' and ',' */
    1009             :         }
    1010    22955167 :         dn->casefold = talloc_array(dn, char, len);
    1011    22955167 :         if ( ! dn->casefold) return NULL;
    1012             : 
    1013    22955167 :         d = dn->casefold;
    1014             : 
    1015   138801086 :         for (i = 0; i < dn->comp_num; i++) {
    1016             : 
    1017             :                 /* copy the name */
    1018   115845919 :                 n = dn->components[i].cf_name;
    1019   141813473 :                 while (*n) *d++ = *n++;
    1020             : 
    1021   115845919 :                 *d++ = '=';
    1022             : 
    1023             :                 /* and the value */
    1024   231691838 :                 d += ldb_dn_escape_internal( d,
    1025   115845919 :                                 (char *)dn->components[i].cf_value.data,
    1026   115845919 :                                 dn->components[i].cf_value.length);
    1027   115845919 :                 *d++ = ',';
    1028             :         }
    1029    22955167 :         *(--d) = '\0';
    1030             : 
    1031             :         /* don't waste more memory than necessary */
    1032    22955167 :         dn->casefold = talloc_realloc(dn, dn->casefold,
    1033             :                                       char, strlen(dn->casefold) + 1);
    1034             : 
    1035    22955167 :         return dn->casefold;
    1036             : }
    1037             : 
    1038     1922209 : char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1039             : {
    1040     1922209 :         return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
    1041             : }
    1042             : 
    1043             : /* Determine if dn is below base, in the ldap tree.  Used for
    1044             :  * evaluating a subtree search.
    1045             :  * 0 if they match, otherwise non-zero
    1046             :  */
    1047             : 
    1048   394422189 : int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
    1049             : {
    1050             :         int ret;
    1051             :         unsigned int n_base, n_dn;
    1052             : 
    1053   394422189 :         if ( ! base || base->invalid) return 1;
    1054   394422189 :         if ( ! dn || dn->invalid) return -1;
    1055             : 
    1056   394422189 :         if (( ! base->valid_case) || ( ! dn->valid_case)) {
    1057   276784525 :                 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 casfolding */
    1060             :                         int dif;
    1061   270952568 :                         dif = strlen(dn->linearized) - strlen(base->linearized);
    1062   270952568 :                         if (dif < 0) {
    1063    87331305 :                                 return dif;
    1064             :                         }
    1065   323640115 :                         if (strcmp(base->linearized,
    1066   323640115 :                                    &dn->linearized[dif]) == 0) {
    1067   109483675 :                                 return 0;
    1068             :                         }
    1069             :                 }
    1070             : 
    1071    79969545 :                 if ( ! ldb_dn_casefold_internal(base)) {
    1072           0 :                         return 1;
    1073             :                 }
    1074             : 
    1075    79969545 :                 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   197607209 :         if (base->comp_num > dn->comp_num) {
    1084    35845878 :                 return (dn->comp_num - base->comp_num);
    1085             :         }
    1086             : 
    1087   161761331 :         if ((dn->comp_num == 0) || (base->comp_num == 0)) {
    1088           0 :                 if (dn->special && base->special) {
    1089           0 :                         return strcmp(base->linearized, dn->linearized);
    1090           0 :                 } else if (dn->special) {
    1091           0 :                         return -1;
    1092           0 :                 } else if (base->special) {
    1093           0 :                         return 1;
    1094             :                 } else {
    1095           0 :                         return 0;
    1096             :                 }
    1097             :         }
    1098             : 
    1099   161761331 :         n_base = base->comp_num - 1;
    1100   161761331 :         n_dn = dn->comp_num - 1;
    1101             : 
    1102   895661149 :         while (n_base != (unsigned int) -1) {
    1103   692946364 :                 char *b_name = base->components[n_base].cf_name;
    1104   692946364 :                 char *dn_name = dn->components[n_dn].cf_name;
    1105             : 
    1106   692946364 :                 char *b_vdata = (char *)base->components[n_base].cf_value.data;
    1107   692946364 :                 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
    1108             : 
    1109   692946364 :                 size_t b_vlen = base->components[n_base].cf_value.length;
    1110   692946364 :                 size_t dn_vlen = dn->components[n_dn].cf_value.length;
    1111             : 
    1112             :                 /* compare attr names */
    1113   692946364 :                 ret = strcmp(b_name, dn_name);
    1114   692946364 :                 if (ret != 0) return ret;
    1115             : 
    1116             :                 /* compare attr.cf_value. */
    1117   626570959 :                 if (b_vlen != dn_vlen) {
    1118    30404366 :                         return b_vlen - dn_vlen;
    1119             :                 }
    1120   596166593 :                 ret = strncmp(b_vdata, dn_vdata, b_vlen);
    1121   596166593 :                 if (ret != 0) return ret;
    1122             : 
    1123   594771567 :                 n_base--;
    1124   594771567 :                 n_dn--;
    1125             :         }
    1126             : 
    1127    63586534 :         return 0;
    1128             : }
    1129             : 
    1130             : /* compare DNs using casefolding compare functions.
    1131             : 
    1132             :    If they match, then return 0
    1133             :  */
    1134             : 
    1135    41977826 : int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
    1136             : {
    1137             :         unsigned int i;
    1138             :         int ret;
    1139             : 
    1140    41977826 :         if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
    1141           2 :                 return -1;
    1142             :         }
    1143             : 
    1144    41977824 :         if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
    1145     7829080 :                 if (dn0->linearized && dn1->linearized) {
    1146             :                         /* try with a normal compare first, if we are lucky
    1147             :                          * we will avoid exploding and casfolding */
    1148     6173856 :                         if (strcmp(dn0->linearized, dn1->linearized) == 0) {
    1149     1269450 :                                 return 0;
    1150             :                         }
    1151             :                 }
    1152             : 
    1153     6559630 :                 if ( ! ldb_dn_casefold_internal(dn0)) {
    1154           0 :                         return 1;
    1155             :                 }
    1156             : 
    1157     6559630 :                 if ( ! ldb_dn_casefold_internal(dn1)) {
    1158         630 :                         return -1;
    1159             :                 }
    1160             : 
    1161             :         }
    1162             : 
    1163    40707744 :         if (dn0->comp_num != dn1->comp_num) {
    1164    25349267 :                 return (dn1->comp_num - dn0->comp_num);
    1165             :         }
    1166             : 
    1167    15358477 :         if (dn0->comp_num == 0) {
    1168      892919 :                 if (dn0->special && dn1->special) {
    1169      892919 :                         return strcmp(dn0->linearized, dn1->linearized);
    1170           0 :                 } else if (dn0->special) {
    1171           0 :                         return 1;
    1172           0 :                 } else if (dn1->special) {
    1173           0 :                         return -1;
    1174             :                 } else {
    1175           0 :                         return 0;
    1176             :                 }
    1177             :         }
    1178             : 
    1179    45703269 :         for (i = 0; i < dn0->comp_num; i++) {
    1180    38968864 :                 char *dn0_name = dn0->components[i].cf_name;
    1181    38968864 :                 char *dn1_name = dn1->components[i].cf_name;
    1182             : 
    1183    38968864 :                 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
    1184    38968864 :                 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
    1185             : 
    1186    38968864 :                 size_t dn0_vlen = dn0->components[i].cf_value.length;
    1187    38968864 :                 size_t dn1_vlen = dn1->components[i].cf_value.length;
    1188             : 
    1189             :                 /* compare attr names */
    1190    38968864 :                 ret = strcmp(dn0_name, dn1_name);
    1191    38968864 :                 if (ret != 0) {
    1192     1893480 :                         return ret;
    1193             :                 }
    1194             : 
    1195             :                 /* compare attr.cf_value. */
    1196    37075384 :                 if (dn0_vlen != dn1_vlen) {
    1197     3055174 :                         return dn0_vlen - dn1_vlen;
    1198             :                 }
    1199    34020210 :                 ret = strncmp(dn0_vdata, dn1_vdata, dn0_vlen);
    1200    34020210 :                 if (ret != 0) {
    1201     2782499 :                         return ret;
    1202             :                 }
    1203             :         }
    1204             : 
    1205     6734405 :         return 0;
    1206             : }
    1207             : 
    1208   287833261 : static struct ldb_dn_component ldb_dn_copy_component(
    1209             :                                                 TALLOC_CTX *mem_ctx,
    1210             :                                                 struct ldb_dn_component *src)
    1211             : {
    1212             :         struct ldb_dn_component dst;
    1213             : 
    1214   287833261 :         memset(&dst, 0, sizeof(dst));
    1215             : 
    1216   287833261 :         if (src == NULL) {
    1217           0 :                 return dst;
    1218             :         }
    1219             : 
    1220   287833261 :         dst.value = ldb_val_dup(mem_ctx, &(src->value));
    1221   287833261 :         if (dst.value.data == NULL) {
    1222           0 :                 return dst;
    1223             :         }
    1224             : 
    1225   287833261 :         dst.name = talloc_strdup(mem_ctx, src->name);
    1226   287833261 :         if (dst.name == NULL) {
    1227           0 :                 LDB_FREE(dst.value.data);
    1228           0 :                 return dst;
    1229             :         }
    1230             : 
    1231   287833261 :         if (src->cf_value.data) {
    1232   232521371 :                 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
    1233   232521371 :                 if (dst.cf_value.data == NULL) {
    1234           0 :                         LDB_FREE(dst.value.data);
    1235           0 :                         LDB_FREE(dst.name);
    1236           0 :                         return dst;
    1237             :                 }
    1238             : 
    1239   232521371 :                 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
    1240   232521371 :                 if (dst.cf_name == NULL) {
    1241           0 :                         LDB_FREE(dst.cf_name);
    1242           0 :                         LDB_FREE(dst.value.data);
    1243           0 :                         LDB_FREE(dst.name);
    1244           0 :                         return dst;
    1245             :                 }
    1246             :         } else {
    1247    55311890 :                 dst.cf_value.data = NULL;
    1248    55311890 :                 dst.cf_name = NULL;
    1249             :         }
    1250             : 
    1251   287833261 :         return dst;
    1252             : }
    1253             : 
    1254    22254641 : static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
    1255             :                                                 TALLOC_CTX *mem_ctx,
    1256             :                                                 struct ldb_dn_ext_component *src)
    1257             : {
    1258             :         struct ldb_dn_ext_component dst;
    1259             : 
    1260    22254641 :         memset(&dst, 0, sizeof(dst));
    1261             : 
    1262    22254641 :         if (src == NULL) {
    1263           0 :                 return dst;
    1264             :         }
    1265             : 
    1266    22254641 :         dst.value = ldb_val_dup(mem_ctx, &(src->value));
    1267    22254641 :         if (dst.value.data == NULL) {
    1268           0 :                 return dst;
    1269             :         }
    1270             : 
    1271    22254641 :         dst.name = talloc_strdup(mem_ctx, src->name);
    1272    22254641 :         if (dst.name == NULL) {
    1273           0 :                 LDB_FREE(dst.value.data);
    1274           0 :                 return dst;
    1275             :         }
    1276             : 
    1277    22254641 :         return dst;
    1278             : }
    1279             : 
    1280    55529890 : struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1281             : {
    1282             :         struct ldb_dn *new_dn;
    1283             : 
    1284    55529890 :         if (!dn || dn->invalid) {
    1285           2 :                 return NULL;
    1286             :         }
    1287             : 
    1288    55529888 :         new_dn = talloc_zero(mem_ctx, struct ldb_dn);
    1289    55529888 :         if ( !new_dn) {
    1290           0 :                 return NULL;
    1291             :         }
    1292             : 
    1293    55529888 :         *new_dn = *dn;
    1294             : 
    1295    55529888 :         if (dn->components) {
    1296             :                 unsigned int i;
    1297             : 
    1298    48798911 :                 new_dn->components =
    1299    48798911 :                         talloc_zero_array(new_dn,
    1300             :                                           struct ldb_dn_component,
    1301             :                                           dn->comp_num);
    1302    48798911 :                 if ( ! new_dn->components) {
    1303           0 :                         talloc_free(new_dn);
    1304           0 :                         return NULL;
    1305             :                 }
    1306             : 
    1307   326287408 :                 for (i = 0; i < dn->comp_num; i++) {
    1308   277488497 :                         new_dn->components[i] =
    1309   277488497 :                                 ldb_dn_copy_component(new_dn->components,
    1310   277488497 :                                                       &dn->components[i]);
    1311   277488497 :                         if ( ! new_dn->components[i].value.data) {
    1312           0 :                                 talloc_free(new_dn);
    1313           0 :                                 return NULL;
    1314             :                         }
    1315             :                 }
    1316             :         }
    1317             : 
    1318    55529888 :         if (dn->ext_components) {
    1319             :                 unsigned int i;
    1320             : 
    1321    18047893 :                 new_dn->ext_components =
    1322    18047893 :                         talloc_zero_array(new_dn,
    1323             :                                           struct ldb_dn_ext_component,
    1324             :                                           dn->ext_comp_num);
    1325    18047893 :                 if ( ! new_dn->ext_components) {
    1326           0 :                         talloc_free(new_dn);
    1327           0 :                         return NULL;
    1328             :                 }
    1329             : 
    1330    40302534 :                 for (i = 0; i < dn->ext_comp_num; i++) {
    1331    22254641 :                         new_dn->ext_components[i] =
    1332    22254641 :                                  ldb_dn_ext_copy_component(
    1333    22254641 :                                                 new_dn->ext_components,
    1334    22254641 :                                                 &dn->ext_components[i]);
    1335    22254641 :                         if ( ! new_dn->ext_components[i].value.data) {
    1336           0 :                                 talloc_free(new_dn);
    1337           0 :                                 return NULL;
    1338             :                         }
    1339             :                 }
    1340             :         }
    1341             : 
    1342    55529888 :         if (dn->casefold) {
    1343    31063949 :                 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
    1344    31063949 :                 if ( ! new_dn->casefold) {
    1345           0 :                         talloc_free(new_dn);
    1346           0 :                         return NULL;
    1347             :                 }
    1348             :         }
    1349             : 
    1350    55529888 :         if (dn->linearized) {
    1351    55383173 :                 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
    1352    55383173 :                 if ( ! new_dn->linearized) {
    1353           0 :                         talloc_free(new_dn);
    1354           0 :                         return NULL;
    1355             :                 }
    1356             :         }
    1357             : 
    1358    55529888 :         if (dn->ext_linearized) {
    1359     1066548 :                 new_dn->ext_linearized = talloc_strdup(new_dn,
    1360      944215 :                                                         dn->ext_linearized);
    1361      944215 :                 if ( ! new_dn->ext_linearized) {
    1362           0 :                         talloc_free(new_dn);
    1363           0 :                         return NULL;
    1364             :                 }
    1365             :         }
    1366             : 
    1367    55529888 :         return new_dn;
    1368             : }
    1369             : 
    1370             : /* modify the given dn by adding a base.
    1371             :  *
    1372             :  * return true if successful and false if not
    1373             :  * if false is returned the dn may be marked invalid
    1374             :  */
    1375      471815 : bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
    1376             : {
    1377             :         const char *s;
    1378             :         char *t;
    1379             : 
    1380      471815 :         if ( !base || base->invalid || !dn || dn->invalid) {
    1381           0 :                 return false;
    1382             :         }
    1383             : 
    1384      471815 :         if (dn == base) {
    1385           0 :                 return false; /* or we will visit infinity */
    1386             :         }
    1387             : 
    1388      471815 :         if (dn->components) {
    1389             :                 unsigned int i;
    1390             : 
    1391      379315 :                 if ( ! ldb_dn_validate(base)) {
    1392           0 :                         return false;
    1393             :                 }
    1394             : 
    1395      379315 :                 s = NULL;
    1396      379315 :                 if (dn->valid_case) {
    1397           2 :                         if ( ! (s = ldb_dn_get_casefold(base))) {
    1398           0 :                                 return false;
    1399             :                         }
    1400             :                 }
    1401             : 
    1402      379315 :                 dn->components = talloc_realloc(dn,
    1403             :                                                 dn->components,
    1404             :                                                 struct ldb_dn_component,
    1405             :                                                 dn->comp_num + base->comp_num);
    1406      379315 :                 if ( ! dn->components) {
    1407           0 :                         ldb_dn_mark_invalid(dn);
    1408           0 :                         return false;
    1409             :                 }
    1410             : 
    1411     2524569 :                 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
    1412     2145254 :                         dn->components[dn->comp_num] =
    1413     2145254 :                                 ldb_dn_copy_component(dn->components,
    1414     2145254 :                                                         &base->components[i]);
    1415     2145254 :                         if (dn->components[dn->comp_num].value.data == NULL) {
    1416           0 :                                 ldb_dn_mark_invalid(dn);
    1417           0 :                                 return false;
    1418             :                         }
    1419             :                 }
    1420             : 
    1421      379315 :                 if (dn->casefold && s) {
    1422           0 :                         if (*dn->casefold) {
    1423           0 :                                 t = talloc_asprintf(dn, "%s,%s",
    1424             :                                                     dn->casefold, s);
    1425             :                         } else {
    1426           0 :                                 t = talloc_strdup(dn, s);
    1427             :                         }
    1428           0 :                         LDB_FREE(dn->casefold);
    1429           0 :                         dn->casefold = t;
    1430             :                 }
    1431             :         }
    1432             : 
    1433      471815 :         if (dn->linearized) {
    1434             : 
    1435       94103 :                 s = ldb_dn_get_linearized(base);
    1436       94103 :                 if ( ! s) {
    1437           0 :                         return false;
    1438             :                 }
    1439             : 
    1440       94103 :                 if (*dn->linearized) {
    1441        8078 :                         t = talloc_asprintf(dn, "%s,%s",
    1442             :                                             dn->linearized, s);
    1443             :                 } else {
    1444       86025 :                         t = talloc_strdup(dn, s);
    1445             :                 }
    1446       94103 :                 if ( ! t) {
    1447           0 :                         ldb_dn_mark_invalid(dn);
    1448           0 :                         return false;
    1449             :                 }
    1450       94103 :                 LDB_FREE(dn->linearized);
    1451       94103 :                 dn->linearized = t;
    1452             :         }
    1453             : 
    1454             :         /* Wipe the ext_linearized DN,
    1455             :          * the GUID and SID are almost certainly no longer valid */
    1456      471815 :         LDB_FREE(dn->ext_linearized);
    1457      471815 :         LDB_FREE(dn->ext_components);
    1458      471815 :         dn->ext_comp_num = 0;
    1459             : 
    1460      471815 :         return true;
    1461             : }
    1462             : 
    1463             : /* modify the given dn by adding a base.
    1464             :  *
    1465             :  * return true if successful and false if not
    1466             :  * if false is returned the dn may be marked invalid
    1467             :  */
    1468           0 : bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
    1469             : {
    1470             :         struct ldb_dn *base;
    1471             :         char *base_str;
    1472             :         va_list ap;
    1473             :         bool ret;
    1474             : 
    1475           0 :         if ( !dn || dn->invalid) {
    1476           0 :                 return false;
    1477             :         }
    1478             : 
    1479           0 :         va_start(ap, base_fmt);
    1480           0 :         base_str = talloc_vasprintf(dn, base_fmt, ap);
    1481           0 :         va_end(ap);
    1482             : 
    1483           0 :         if (base_str == NULL) {
    1484           0 :                 return false;
    1485             :         }
    1486             : 
    1487           0 :         base = ldb_dn_new(base_str, dn->ldb, base_str);
    1488             : 
    1489           0 :         ret = ldb_dn_add_base(dn, base);
    1490             : 
    1491           0 :         talloc_free(base_str);
    1492             : 
    1493           0 :         return ret;
    1494             : }
    1495             : 
    1496             : /* modify the given dn by adding children elements.
    1497             :  *
    1498             :  * return true if successful and false if not
    1499             :  * if false is returned the dn may be marked invalid
    1500             :  */
    1501     4385960 : bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
    1502             : {
    1503             :         const char *s;
    1504             :         char *t;
    1505             : 
    1506     4385960 :         if ( !child || child->invalid || !dn || dn->invalid) {
    1507           0 :                 return false;
    1508             :         }
    1509             : 
    1510     4385960 :         if (dn->components) {
    1511             :                 unsigned int n;
    1512             :                 unsigned int i, j;
    1513             : 
    1514     4197747 :                 if (dn->comp_num == 0) {
    1515           0 :                         return false;
    1516             :                 }
    1517             : 
    1518     4197747 :                 if ( ! ldb_dn_validate(child)) {
    1519           0 :                         return false;
    1520             :                 }
    1521             : 
    1522     4197747 :                 s = NULL;
    1523     4197747 :                 if (dn->valid_case) {
    1524     2764684 :                         if ( ! (s = ldb_dn_get_casefold(child))) {
    1525           0 :                                 return false;
    1526             :                         }
    1527             :                 }
    1528             : 
    1529     4197747 :                 n = dn->comp_num + child->comp_num;
    1530             : 
    1531     4197747 :                 dn->components = talloc_realloc(dn,
    1532             :                                                 dn->components,
    1533             :                                                 struct ldb_dn_component,
    1534             :                                                 n);
    1535     4197747 :                 if ( ! dn->components) {
    1536           0 :                         ldb_dn_mark_invalid(dn);
    1537           0 :                         return false;
    1538             :                 }
    1539             : 
    1540    25983928 :                 for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1;
    1541    18132270 :                      i--, j--) {
    1542    18132270 :                         dn->components[j] = dn->components[i];
    1543             :                 }
    1544             : 
    1545    11833720 :                 for (i = 0; i < child->comp_num; i++) {
    1546     7635973 :                         dn->components[i] =
    1547     7635973 :                                 ldb_dn_copy_component(dn->components,
    1548     7635973 :                                                         &child->components[i]);
    1549     7635973 :                         if (dn->components[i].value.data == NULL) {
    1550           0 :                                 ldb_dn_mark_invalid(dn);
    1551           0 :                                 return false;
    1552             :                         }
    1553             :                 }
    1554             : 
    1555     4197747 :                 dn->comp_num = n;
    1556             : 
    1557     4197747 :                 if (dn->casefold && s) {
    1558     2292421 :                         t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
    1559     2292421 :                         LDB_FREE(dn->casefold);
    1560     2292421 :                         dn->casefold = t;
    1561             :                 }
    1562             :         }
    1563             : 
    1564     4385960 :         if (dn->linearized) {
    1565     4379425 :                 if (dn->linearized[0] == '\0') {
    1566           0 :                         return false;
    1567             :                 }
    1568             : 
    1569     4379425 :                 s = ldb_dn_get_linearized(child);
    1570     4379425 :                 if ( ! s) {
    1571           0 :                         return false;
    1572             :                 }
    1573             : 
    1574     4379425 :                 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
    1575     4379425 :                 if ( ! t) {
    1576           0 :                         ldb_dn_mark_invalid(dn);
    1577           0 :                         return false;
    1578             :                 }
    1579     4379425 :                 LDB_FREE(dn->linearized);
    1580     4379425 :                 dn->linearized = t;
    1581             :         }
    1582             : 
    1583             :         /* Wipe the ext_linearized DN,
    1584             :          * the GUID and SID are almost certainly no longer valid */
    1585     4385960 :         LDB_FREE(dn->ext_linearized);
    1586     4385960 :         LDB_FREE(dn->ext_components);
    1587     4385960 :         dn->ext_comp_num = 0;
    1588             : 
    1589     4385960 :         return true;
    1590             : }
    1591             : 
    1592             : /* modify the given dn by adding children elements.
    1593             :  *
    1594             :  * return true if successful and false if not
    1595             :  * if false is returned the dn may be marked invalid
    1596             :  */
    1597     4235729 : bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
    1598             : {
    1599             :         struct ldb_dn *child;
    1600             :         char *child_str;
    1601             :         va_list ap;
    1602             :         bool ret;
    1603             : 
    1604     4235729 :         if ( !dn || dn->invalid) {
    1605           0 :                 return false;
    1606             :         }
    1607             : 
    1608     4235729 :         va_start(ap, child_fmt);
    1609     4235729 :         child_str = talloc_vasprintf(dn, child_fmt, ap);
    1610     4235729 :         va_end(ap);
    1611             : 
    1612     4235729 :         if (child_str == NULL) {
    1613           0 :                 return false;
    1614             :         }
    1615             : 
    1616     4235729 :         child = ldb_dn_new(child_str, dn->ldb, child_str);
    1617             : 
    1618     4235729 :         ret = ldb_dn_add_child(dn, child);
    1619             : 
    1620     4235729 :         talloc_free(child_str);
    1621             : 
    1622     4235729 :         return ret;
    1623             : }
    1624             : 
    1625             : /* modify the given dn by adding a single child element.
    1626             :  *
    1627             :  * return true if successful and false if not
    1628             :  * if false is returned the dn may be marked invalid
    1629             :  */
    1630       57743 : bool ldb_dn_add_child_val(struct ldb_dn *dn,
    1631             :                           const char *rdn,
    1632             :                           struct ldb_val value)
    1633             : {
    1634             :         bool ret;
    1635             :         int ldb_ret;
    1636       57743 :         struct ldb_dn *child = NULL;
    1637             : 
    1638       57743 :         if ( !dn || dn->invalid) {
    1639           0 :                 return false;
    1640             :         }
    1641             : 
    1642       57743 :         child = ldb_dn_new(dn, dn->ldb, "X=Y");
    1643       57743 :         ret = ldb_dn_add_child(dn, child);
    1644             : 
    1645       57743 :         if (ret == false) {
    1646           0 :                 return false;
    1647             :         }
    1648             : 
    1649       57743 :         ldb_ret = ldb_dn_set_component(dn,
    1650             :                                        0,
    1651             :                                        rdn,
    1652             :                                        value);
    1653       57743 :         if (ldb_ret != LDB_SUCCESS) {
    1654           0 :                 return false;
    1655             :         }
    1656             : 
    1657       57743 :         return true;
    1658             : }
    1659             : 
    1660      468009 : bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
    1661             : {
    1662             :         unsigned int i;
    1663             : 
    1664      468009 :         if ( ! ldb_dn_validate(dn)) {
    1665           0 :                 return false;
    1666             :         }
    1667             : 
    1668      468009 :         if (dn->comp_num < num) {
    1669           0 :                 return false;
    1670             :         }
    1671             : 
    1672             :         /* free components */
    1673     3049348 :         for (i = dn->comp_num - num; i < dn->comp_num; i++) {
    1674     2581339 :                 LDB_FREE(dn->components[i].name);
    1675     2581339 :                 LDB_FREE(dn->components[i].value.data);
    1676     2581339 :                 LDB_FREE(dn->components[i].cf_name);
    1677     2581339 :                 LDB_FREE(dn->components[i].cf_value.data);
    1678             :         }
    1679             : 
    1680      468009 :         dn->comp_num -= num;
    1681             : 
    1682      468009 :         if (dn->valid_case) {
    1683      180606 :                 for (i = 0; i < dn->comp_num; i++) {
    1684       90303 :                         LDB_FREE(dn->components[i].cf_name);
    1685       90303 :                         LDB_FREE(dn->components[i].cf_value.data);
    1686             :                 }
    1687       90303 :                 dn->valid_case = false;
    1688             :         }
    1689             : 
    1690      468009 :         LDB_FREE(dn->casefold);
    1691      468009 :         LDB_FREE(dn->linearized);
    1692             : 
    1693             :         /* Wipe the ext_linearized DN,
    1694             :          * the GUID and SID are almost certainly no longer valid */
    1695      468009 :         LDB_FREE(dn->ext_linearized);
    1696      468009 :         LDB_FREE(dn->ext_components);
    1697      468009 :         dn->ext_comp_num = 0;
    1698             : 
    1699      468009 :         return true;
    1700             : }
    1701             : 
    1702     9794722 : bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
    1703             : {
    1704             :         unsigned int i, j;
    1705             : 
    1706     9794722 :         if ( ! ldb_dn_validate(dn)) {
    1707           0 :                 return false;
    1708             :         }
    1709             : 
    1710     9794722 :         if (dn->comp_num < num) {
    1711           3 :                 return false;
    1712             :         }
    1713             : 
    1714    63427437 :         for (i = 0, j = num; j < dn->comp_num; i++, j++) {
    1715    53632718 :                 if (i < num) {
    1716     9793691 :                         LDB_FREE(dn->components[i].name);
    1717     9793691 :                         LDB_FREE(dn->components[i].value.data);
    1718     9793691 :                         LDB_FREE(dn->components[i].cf_name);
    1719     9793691 :                         LDB_FREE(dn->components[i].cf_value.data);
    1720             :                 }
    1721    53632718 :                 dn->components[i] = dn->components[j];
    1722             :         }
    1723             : 
    1724     9794719 :         dn->comp_num -= num;
    1725             : 
    1726     9794719 :         if (dn->valid_case) {
    1727    43132345 :                 for (i = 0; i < dn->comp_num; i++) {
    1728    36495647 :                         LDB_FREE(dn->components[i].cf_name);
    1729    36495647 :                         LDB_FREE(dn->components[i].cf_value.data);
    1730             :                 }
    1731     6636698 :                 dn->valid_case = false;
    1732             :         }
    1733             : 
    1734     9794719 :         LDB_FREE(dn->casefold);
    1735     9794719 :         LDB_FREE(dn->linearized);
    1736             : 
    1737             :         /* Wipe the ext_linearized DN,
    1738             :          * the GUID and SID are almost certainly no longer valid */
    1739     9794719 :         LDB_FREE(dn->ext_linearized);
    1740     9794719 :         LDB_FREE(dn->ext_components);
    1741     9794719 :         dn->ext_comp_num = 0;
    1742             : 
    1743     9794719 :         return true;
    1744             : }
    1745             : 
    1746             : 
    1747             : /* replace the components of a DN with those from another DN, without
    1748             :  * touching the extended components
    1749             :  *
    1750             :  * return true if successful and false if not
    1751             :  * if false is returned the dn may be marked invalid
    1752             :  */
    1753      115911 : bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn)
    1754             : {
    1755             :         unsigned int i;
    1756             : 
    1757      115911 :         if ( ! ldb_dn_validate(dn) || ! ldb_dn_validate(new_dn)) {
    1758           0 :                 return false;
    1759             :         }
    1760             : 
    1761             :         /* free components */
    1762      789010 :         for (i = 0; i < dn->comp_num; i++) {
    1763      673099 :                 LDB_FREE(dn->components[i].name);
    1764      673099 :                 LDB_FREE(dn->components[i].value.data);
    1765      673099 :                 LDB_FREE(dn->components[i].cf_name);
    1766      673099 :                 LDB_FREE(dn->components[i].cf_value.data);
    1767             :         }
    1768             : 
    1769      115911 :         dn->components = talloc_realloc(dn,
    1770             :                                         dn->components,
    1771             :                                         struct ldb_dn_component,
    1772             :                                         new_dn->comp_num);
    1773      115911 :         if (dn->components == NULL) {
    1774           0 :                 ldb_dn_mark_invalid(dn);
    1775           0 :                 return false;
    1776             :         }
    1777             : 
    1778      115911 :         dn->comp_num = new_dn->comp_num;
    1779      115911 :         dn->valid_case = new_dn->valid_case;
    1780             : 
    1781      679448 :         for (i = 0; i < dn->comp_num; i++) {
    1782      563537 :                 dn->components[i] = ldb_dn_copy_component(dn->components, &new_dn->components[i]);
    1783      563537 :                 if (dn->components[i].name == NULL) {
    1784           0 :                         ldb_dn_mark_invalid(dn);
    1785           0 :                         return false;
    1786             :                 }
    1787             :         }
    1788      115911 :         if (new_dn->linearized == NULL) {
    1789           0 :                 dn->linearized = NULL;
    1790             :         } else {
    1791      115911 :                 dn->linearized = talloc_strdup(dn, new_dn->linearized);
    1792      115911 :                 if (dn->linearized == NULL) {
    1793           0 :                         ldb_dn_mark_invalid(dn);
    1794           0 :                         return false;
    1795             :                 }
    1796             :         }
    1797             : 
    1798      115911 :         return true;
    1799             : }
    1800             : 
    1801             : 
    1802     9790695 : struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1803             : {
    1804             :         struct ldb_dn *new_dn;
    1805             : 
    1806     9790695 :         new_dn = ldb_dn_copy(mem_ctx, dn);
    1807     9790695 :         if ( !new_dn ) {
    1808           2 :                 return NULL;
    1809             :         }
    1810             : 
    1811     9790693 :         if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
    1812           3 :                 talloc_free(new_dn);
    1813           3 :                 return NULL;
    1814             :         }
    1815             : 
    1816     9790690 :         return new_dn;
    1817             : }
    1818             : 
    1819             : /* Create a 'canonical name' string from a DN:
    1820             : 
    1821             :    ie dc=samba,dc=org -> samba.org/
    1822             :       uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
    1823             : 
    1824             :    There are two formats,
    1825             :    the EX format has the last '/' replaced with a newline (\n).
    1826             : 
    1827             : */
    1828     1804241 : static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) {
    1829             :         unsigned int i;
    1830             :         TALLOC_CTX *tmpctx;
    1831     1804241 :         char *cracked = NULL;
    1832     1804241 :         const char *format = (ex_format ? "\n" : "/" );
    1833             : 
    1834     1804241 :         if ( ! ldb_dn_validate(dn)) {
    1835           0 :                 return NULL;
    1836             :         }
    1837             : 
    1838     1804241 :         tmpctx = talloc_new(mem_ctx);
    1839             : 
    1840             :         /* Walk backwards down the DN, grabbing 'dc' components at first */
    1841     7777513 :         for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) {
    1842     7590198 :                 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
    1843     1616926 :                         break;
    1844             :                 }
    1845     5973272 :                 if (cracked) {
    1846     4169098 :                         cracked = talloc_asprintf(tmpctx, "%s.%s",
    1847             :                                                   ldb_dn_escape_value(tmpctx,
    1848     4169098 :                                                         dn->components[i].value),
    1849             :                                                   cracked);
    1850             :                 } else {
    1851     1804174 :                         cracked = ldb_dn_escape_value(tmpctx,
    1852     1804174 :                                                         dn->components[i].value);
    1853             :                 }
    1854     5973272 :                 if (!cracked) {
    1855           0 :                         goto done;
    1856             :                 }
    1857             :         }
    1858             : 
    1859             :         /* Only domain components?  Finish here */
    1860     1804241 :         if (i == (unsigned int) -1) {
    1861      187315 :                 cracked = talloc_strdup_append_buffer(cracked, format);
    1862      187315 :                 talloc_steal(mem_ctx, cracked);
    1863      187315 :                 goto done;
    1864             :         }
    1865             : 
    1866             :         /* Now walk backwards appending remaining components */
    1867     4430394 :         for (; i > 0; i--) {
    1868     2813468 :                 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
    1869             :                                                         ldb_dn_escape_value(tmpctx,
    1870     2813468 :                                                         dn->components[i].value));
    1871     2813468 :                 if (!cracked) {
    1872           0 :                         goto done;
    1873             :                 }
    1874             :         }
    1875             : 
    1876             :         /* Last one, possibly a newline for the 'ex' format */
    1877     1616926 :         cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
    1878             :                                                 ldb_dn_escape_value(tmpctx,
    1879     1616926 :                                                         dn->components[i].value));
    1880             : 
    1881     1616926 :         talloc_steal(mem_ctx, cracked);
    1882     1804241 : done:
    1883     1804241 :         talloc_free(tmpctx);
    1884     1804241 :         return cracked;
    1885             : }
    1886             : 
    1887             : /* Wrapper functions for the above, for the two different string formats */
    1888     1804078 : char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
    1889     1804078 :         return ldb_dn_canonical(mem_ctx, dn, 0);
    1890             : 
    1891             : }
    1892             : 
    1893         163 : char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
    1894         163 :         return ldb_dn_canonical(mem_ctx, dn, 1);
    1895             : }
    1896             : 
    1897    14811148 : int ldb_dn_get_comp_num(struct ldb_dn *dn)
    1898             : {
    1899    14811148 :         if ( ! ldb_dn_validate(dn)) {
    1900           4 :                 return -1;
    1901             :         }
    1902    14811144 :         return dn->comp_num;
    1903             : }
    1904             : 
    1905     9352113 : int ldb_dn_get_extended_comp_num(struct ldb_dn *dn)
    1906             : {
    1907     9352113 :         if ( ! ldb_dn_validate(dn)) {
    1908           4 :                 return -1;
    1909             :         }
    1910     9352109 :         return dn->ext_comp_num;
    1911             : }
    1912             : 
    1913        6815 : const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
    1914             : {
    1915        6815 :         if ( ! ldb_dn_validate(dn)) {
    1916           0 :                 return NULL;
    1917             :         }
    1918        6815 :         if (num >= dn->comp_num) return NULL;
    1919        6807 :         return dn->components[num].name;
    1920             : }
    1921             : 
    1922      520371 : const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
    1923             :                                                 unsigned int num)
    1924             : {
    1925      520371 :         if ( ! ldb_dn_validate(dn)) {
    1926           0 :                 return NULL;
    1927             :         }
    1928      520371 :         if (num >= dn->comp_num) return NULL;
    1929      520371 :         return &dn->components[num].value;
    1930             : }
    1931             : 
    1932    45496535 : const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
    1933             : {
    1934    45496535 :         if ( ! ldb_dn_validate(dn)) {
    1935           0 :                 return NULL;
    1936             :         }
    1937    45496535 :         if (dn->comp_num == 0) return NULL;
    1938    36701265 :         return dn->components[0].name;
    1939             : }
    1940             : 
    1941    36442541 : const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
    1942             : {
    1943    36442541 :         if ( ! ldb_dn_validate(dn)) {
    1944           2 :                 return NULL;
    1945             :         }
    1946    36442539 :         if (dn->comp_num == 0) return NULL;
    1947    27647269 :         return &dn->components[0].value;
    1948             : }
    1949             : 
    1950      783320 : int ldb_dn_set_component(struct ldb_dn *dn, int num,
    1951             :                          const char *name, const struct ldb_val val)
    1952             : {
    1953             :         char *n;
    1954             :         struct ldb_val v;
    1955             : 
    1956      783320 :         if ( ! ldb_dn_validate(dn)) {
    1957           0 :                 return LDB_ERR_OTHER;
    1958             :         }
    1959             : 
    1960      783320 :         if (num < 0) {
    1961           0 :                 return LDB_ERR_OTHER;
    1962             :         }
    1963             : 
    1964      783320 :         if ((unsigned)num >= dn->comp_num) {
    1965           2 :                 return LDB_ERR_OTHER;
    1966             :         }
    1967             : 
    1968      783318 :         if (val.length > val.length + 1) {
    1969           0 :                 return LDB_ERR_OTHER;
    1970             :         }
    1971             : 
    1972      783318 :         n = talloc_strdup(dn, name);
    1973      783318 :         if ( ! n) {
    1974           0 :                 return LDB_ERR_OTHER;
    1975             :         }
    1976             : 
    1977      783318 :         v.length = val.length;
    1978             : 
    1979             :         /*
    1980             :          * This is like talloc_memdup(dn, v.data, v.length + 1), but
    1981             :          * avoids the over-read
    1982             :          */
    1983      783318 :         v.data = (uint8_t *)talloc_size(dn, v.length+1);
    1984      783318 :         if ( ! v.data) {
    1985           0 :                 talloc_free(n);
    1986           0 :                 return LDB_ERR_OTHER;
    1987             :         }
    1988      783318 :         memcpy(v.data, val.data, val.length);
    1989             : 
    1990             :         /*
    1991             :          * Enforce NUL termination outside the stated length, as is
    1992             :          * traditional in LDB
    1993             :          */
    1994      783318 :         v.data[v.length] = '\0';
    1995             : 
    1996      783318 :         talloc_free(dn->components[num].name);
    1997      783318 :         talloc_free(dn->components[num].value.data);
    1998      783318 :         dn->components[num].name = n;
    1999      783318 :         dn->components[num].value = v;
    2000             : 
    2001      783318 :         if (dn->valid_case) {
    2002             :                 unsigned int i;
    2003     3172045 :                 for (i = 0; i < dn->comp_num; i++) {
    2004     2736379 :                         LDB_FREE(dn->components[i].cf_name);
    2005     2736379 :                         LDB_FREE(dn->components[i].cf_value.data);
    2006             :                 }
    2007      435666 :                 dn->valid_case = false;
    2008             :         }
    2009      783318 :         LDB_FREE(dn->casefold);
    2010      783318 :         LDB_FREE(dn->linearized);
    2011             : 
    2012             :         /* Wipe the ext_linearized DN,
    2013             :          * the GUID and SID are almost certainly no longer valid */
    2014      783318 :         LDB_FREE(dn->ext_linearized);
    2015      783318 :         LDB_FREE(dn->ext_components);
    2016      783318 :         dn->ext_comp_num = 0;
    2017             : 
    2018      783318 :         return LDB_SUCCESS;
    2019             : }
    2020             : 
    2021   167776949 : const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
    2022             :                                                     const char *name)
    2023             : {
    2024             :         unsigned int i;
    2025   167776949 :         if ( ! ldb_dn_validate(dn)) {
    2026           6 :                 return NULL;
    2027             :         }
    2028   199291315 :         for (i=0; i < dn->ext_comp_num; i++) {
    2029    73782449 :                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
    2030    42268077 :                         return &dn->ext_components[i].value;
    2031             :                 }
    2032             :         }
    2033   125508866 :         return NULL;
    2034             : }
    2035             : 
    2036    97458405 : int ldb_dn_set_extended_component(struct ldb_dn *dn,
    2037             :                                   const char *name, const struct ldb_val *val)
    2038             : {
    2039             :         struct ldb_dn_ext_component *p;
    2040             :         unsigned int i;
    2041             :         struct ldb_val v2;
    2042             :         const struct ldb_dn_extended_syntax *ext_syntax;
    2043             :         
    2044    97458405 :         if ( ! ldb_dn_validate(dn)) {
    2045           0 :                 return LDB_ERR_OTHER;
    2046             :         }
    2047             : 
    2048    97458405 :         ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
    2049    97458405 :         if (ext_syntax == NULL) {
    2050             :                 /* We don't know how to handle this type of thing */
    2051           0 :                 return LDB_ERR_INVALID_DN_SYNTAX;
    2052             :         }
    2053             : 
    2054   115171191 :         for (i=0; i < dn->ext_comp_num; i++) {
    2055    17716772 :                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
    2056        3986 :                         if (val) {
    2057        3986 :                                 dn->ext_components[i].value =
    2058        3986 :                                         ldb_val_dup(dn->ext_components, val);
    2059             : 
    2060        3986 :                                 dn->ext_components[i].name = ext_syntax->name;
    2061        3986 :                                 if (!dn->ext_components[i].value.data) {
    2062           0 :                                         ldb_dn_mark_invalid(dn);
    2063           0 :                                         return LDB_ERR_OPERATIONS_ERROR;
    2064             :                                 }
    2065             :                         } else {
    2066           0 :                                 ARRAY_DEL_ELEMENT(
    2067             :                                         dn->ext_components,
    2068             :                                         i,
    2069             :                                         dn->ext_comp_num);
    2070           0 :                                 dn->ext_comp_num--;
    2071             : 
    2072           0 :                                 dn->ext_components = talloc_realloc(dn,
    2073             :                                                    dn->ext_components,
    2074             :                                                    struct ldb_dn_ext_component,
    2075             :                                                    dn->ext_comp_num);
    2076           0 :                                 if (!dn->ext_components) {
    2077           0 :                                         ldb_dn_mark_invalid(dn);
    2078           0 :                                         return LDB_ERR_OPERATIONS_ERROR;
    2079             :                                 }
    2080             :                         }
    2081        3986 :                         LDB_FREE(dn->ext_linearized);
    2082             : 
    2083        3986 :                         return LDB_SUCCESS;
    2084             :                 }
    2085             :         }
    2086             : 
    2087    97454419 :         if (val == NULL) {
    2088             :                 /* removing a value that doesn't exist is not an error */
    2089           0 :                 return LDB_SUCCESS;
    2090             :         }
    2091             : 
    2092    97454419 :         v2 = *val;
    2093             : 
    2094    97454419 :         p = dn->ext_components
    2095    97454419 :                 = talloc_realloc(dn,
    2096             :                                  dn->ext_components,
    2097             :                                  struct ldb_dn_ext_component,
    2098             :                                  dn->ext_comp_num + 1);
    2099    97454419 :         if (!dn->ext_components) {
    2100           0 :                 ldb_dn_mark_invalid(dn);
    2101           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2102             :         }
    2103             : 
    2104    97454419 :         p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2);
    2105    97454419 :         p[dn->ext_comp_num].name = talloc_strdup(p, name);
    2106             : 
    2107    97454419 :         if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
    2108           0 :                 ldb_dn_mark_invalid(dn);
    2109           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2110             :         }
    2111    97454419 :         dn->ext_components = p;
    2112    97454419 :         dn->ext_comp_num++;
    2113             : 
    2114    97454419 :         LDB_FREE(dn->ext_linearized);
    2115             : 
    2116    97454419 :         return LDB_SUCCESS;
    2117             : }
    2118             : 
    2119    33058800 : void ldb_dn_remove_extended_components(struct ldb_dn *dn)
    2120             : {
    2121    33058800 :         LDB_FREE(dn->ext_linearized);
    2122    33058800 :         LDB_FREE(dn->ext_components);
    2123    33058800 :         dn->ext_comp_num = 0;
    2124    33058800 : }
    2125             : 
    2126        4608 : bool ldb_dn_is_valid(struct ldb_dn *dn)
    2127             : {
    2128        4608 :         if ( ! dn) return false;
    2129        4608 :         return ! dn->invalid;
    2130             : }
    2131             : 
    2132  1261383264 : bool ldb_dn_is_special(struct ldb_dn *dn)
    2133             : {
    2134  1261383264 :         if ( ! dn || dn->invalid) return false;
    2135  1261383263 :         return dn->special;
    2136             : }
    2137             : 
    2138   308780718 : bool ldb_dn_has_extended(struct ldb_dn *dn)
    2139             : {
    2140   308780718 :         if ( ! dn || dn->invalid) return false;
    2141   308780718 :         if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
    2142   297496603 :         return dn->ext_comp_num != 0;
    2143             : }
    2144             : 
    2145    11205193 : bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
    2146             : {
    2147    11205193 :         if ( ! dn || dn->invalid) return false;
    2148    11205193 :         return ! strcmp(dn->linearized, check);
    2149             : }
    2150             : 
    2151   268888868 : bool ldb_dn_is_null(struct ldb_dn *dn)
    2152             : {
    2153   268888868 :         if ( ! dn || dn->invalid) return false;
    2154   268888868 :         if (ldb_dn_has_extended(dn)) return false;
    2155   233337584 :         if (dn->linearized && (dn->linearized[0] == '\0')) return true;
    2156   213990063 :         return false;
    2157             : }
    2158             : 
    2159             : /*
    2160             :   this updates dn->components, taking the components from ref_dn.
    2161             :   This is used by code that wants to update the DN path of a DN
    2162             :   while not impacting on the extended DN components
    2163             :  */
    2164        9316 : int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn)
    2165             : {
    2166        9316 :         dn->components = talloc_realloc(dn, dn->components,
    2167             :                                         struct ldb_dn_component, ref_dn->comp_num);
    2168        9316 :         if (!dn->components) {
    2169           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2170             :         }
    2171        9316 :         memcpy(dn->components, ref_dn->components,
    2172        9316 :                sizeof(struct ldb_dn_component)*ref_dn->comp_num);
    2173        9316 :         dn->comp_num = ref_dn->comp_num;
    2174             : 
    2175        9316 :         LDB_FREE(dn->casefold);
    2176        9316 :         LDB_FREE(dn->linearized);
    2177        9316 :         LDB_FREE(dn->ext_linearized);
    2178             : 
    2179        9316 :         return LDB_SUCCESS;
    2180             : }
    2181             : 
    2182             : /*
    2183             :   minimise a DN. The caller must pass in a validated DN.
    2184             : 
    2185             :   If the DN has an extended component then only the first extended
    2186             :   component is kept, the DN string is stripped.
    2187             : 
    2188             :   The existing dn is modified
    2189             :  */
    2190     5122828 : bool ldb_dn_minimise(struct ldb_dn *dn)
    2191             : {
    2192             :         unsigned int i;
    2193             : 
    2194     5122828 :         if (!ldb_dn_validate(dn)) {
    2195           0 :                 return false;
    2196             :         }
    2197     5122828 :         if (dn->ext_comp_num == 0) {
    2198           0 :                 return true;
    2199             :         }
    2200             : 
    2201             :         /* free components */
    2202    26832403 :         for (i = 0; i < dn->comp_num; i++) {
    2203    21709575 :                 LDB_FREE(dn->components[i].name);
    2204    21709575 :                 LDB_FREE(dn->components[i].value.data);
    2205    21709575 :                 LDB_FREE(dn->components[i].cf_name);
    2206    21709575 :                 LDB_FREE(dn->components[i].cf_value.data);
    2207             :         }
    2208     5122828 :         dn->comp_num = 0;
    2209     5122828 :         dn->valid_case = false;
    2210             : 
    2211     5122828 :         LDB_FREE(dn->casefold);
    2212     5122828 :         LDB_FREE(dn->linearized);
    2213             : 
    2214             :         /* note that we don't free dn->components as this there are
    2215             :          * several places in ldb_dn.c that rely on it being non-NULL
    2216             :          * for an exploded DN
    2217             :          */
    2218             : 
    2219     7452070 :         for (i = 1; i < dn->ext_comp_num; i++) {
    2220     2329242 :                 LDB_FREE(dn->ext_components[i].value.data);
    2221             :         }
    2222     5122828 :         dn->ext_comp_num = 1;
    2223             : 
    2224     5122828 :         dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1);
    2225     5122828 :         if (dn->ext_components == NULL) {
    2226           0 :                 ldb_dn_mark_invalid(dn);
    2227           0 :                 return false;
    2228             :         }
    2229             : 
    2230     5122828 :         LDB_FREE(dn->ext_linearized);
    2231             : 
    2232     5122828 :         return true;
    2233             : }
    2234             : 
    2235      580941 : struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn)
    2236             : {
    2237      580941 :         return dn->ldb;
    2238             : }

Generated by: LCOV version 1.13