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-test 1498b464 Lines: 857 1067 80.3 %
Date: 2024-06-13 04:01:37 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       17903 : static void ldb_dn_mark_invalid(struct ldb_dn *dn)
      84             : {
      85       17903 :         dn->invalid = true;
      86       17903 : }
      87             : 
      88             : /* strdn may be NULL */
      89   603239385 : 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   603239385 :         if (ldb == NULL || strdn == NULL) {
      96           0 :                 return NULL;
      97             :         }
      98   603239385 :         if (strdn->data
      99   583534215 :             && (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   603239385 :         dn = talloc_zero(mem_ctx, struct ldb_dn);
     105   603239385 :         LDB_DN_NULL_FAILED(dn);
     106             : 
     107   603239385 :         dn->ldb = talloc_get_type(ldb, struct ldb_context);
     108   603239385 :         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  1186065709 :         if (strdn->data && strdn->length) {
     116   582826324 :                 const char *data = (const char *)strdn->data;
     117   582826324 :                 size_t length = strdn->length;
     118             : 
     119   582826324 :                 if (data[0] == '@') {
     120   257852129 :                         dn->special = true;
     121             :                 }
     122   582826324 :                 dn->ext_linearized = talloc_strndup(dn, data, length);
     123   582826324 :                 LDB_DN_NULL_FAILED(dn->ext_linearized);
     124             : 
     125   582826324 :                 if (data[0] == '<') {
     126    27763344 :                         const char *p_save, *p = dn->ext_linearized;
     127             :                         do {
     128    64134712 :                                 p_save = p;
     129    64134712 :                                 p = strstr(p, ">;");
     130    64134712 :                                 if (p) {
     131    36371368 :                                         p = p + 2;
     132             :                                 }
     133    64134712 :                         } while (p);
     134             : 
     135    27763344 :                         if (p_save == dn->ext_linearized) {
     136     6131469 :                                 dn->linearized = talloc_strdup(dn, "");
     137             :                         } else {
     138    21631875 :                                 dn->linearized = talloc_strdup(dn, p_save);
     139             :                         }
     140    27763344 :                         LDB_DN_NULL_FAILED(dn->linearized);
     141             :                 } else {
     142   555062980 :                         dn->linearized = dn->ext_linearized;
     143   555062980 :                         dn->ext_linearized = NULL;
     144             :                 }
     145             :         } else {
     146    20413061 :                 dn->linearized = talloc_strdup(dn, "");
     147    20413061 :                 LDB_DN_NULL_FAILED(dn->linearized);
     148             :         }
     149             : 
     150   603239385 :         return dn;
     151             : 
     152           0 : failed:
     153           0 :         talloc_free(dn);
     154           0 :         return NULL;
     155             : }
     156             : 
     157             : /* strdn may be NULL */
     158   221681172 : 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   221681172 :         blob.data = discard_const_p(uint8_t, strdn);
     164   221681172 :         blob.length = strdn ? strlen(strdn) : 0;
     165   221681172 :         return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
     166             : }
     167             : 
     168   136020119 : 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   136020119 :         if (! ldb) return NULL;
     176             : 
     177   136020119 :         va_start(ap, new_fmt);
     178   136020119 :         strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
     179   136020119 :         va_end(ap);
     180             : 
     181   136020119 :         if (strdn) {
     182   136020119 :                 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
     183   136020119 :                 talloc_free(strdn);
     184   136020119 :                 return dn;
     185             :         }
     186             : 
     187           0 :         return NULL;
     188             : }
     189             : 
     190             : /* see RFC2253 section 2.4 */
     191   167119821 : static int ldb_dn_escape_internal(char *dst, const char *src, int len)
     192             : {
     193             :         char c;
     194             :         char *d;
     195             :         int i;
     196   167119821 :         d = dst;
     197             : 
     198  1600631557 :         for (i = 0; i < len; i++){
     199  1433511736 :                 c = src[i];
     200  1433511736 :                 switch (c) {
     201     8322032 :                 case ' ':
     202     8322032 :                         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     8322032 :                                 *d++ = c;
     210             :                         }
     211     8322032 :                         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     1092714 :                 case ';':
     229             :                 case '\r':
     230             :                 case '\n':
     231             :                 case '=':
     232             :                 case '\0': {
     233             :                         /* any others get \XX form */
     234             :                         unsigned char v;
     235     1092714 :                         const char *hexbytes = "0123456789ABCDEF";
     236     1092714 :                         v = (const unsigned char)c;
     237     1092714 :                         *d++ = '\\';
     238     1092714 :                         *d++ = hexbytes[v>>4];
     239     1092714 :                         *d++ = hexbytes[v&0xF];
     240     1092714 :                         break;
     241             :                 }
     242  1424078765 :                 default:
     243  1424078765 :                         *d++ = c;
     244             :                 }
     245             :         }
     246             : 
     247             :         /* return the length of the resulting string */
     248   167119821 :         return (d - dst);
     249             : }
     250             : 
     251    10471742 : char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value)
     252             : {
     253             :         char *dst;
     254             :         size_t len;
     255    10471742 :         if (!value.length)
     256           2 :                 return NULL;
     257             : 
     258             :         /* allocate destination string, it will be at most 3 times the source */
     259    10471740 :         dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
     260    10471740 :         if ( ! dst) {
     261           0 :                 talloc_free(dst);
     262           0 :                 return NULL;
     263             :         }
     264             : 
     265    10471740 :         len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
     266             : 
     267    10471740 :         dst = talloc_realloc(mem_ctx, dst, char, len + 1);
     268    10471740 :         if ( ! dst) {
     269           0 :                 talloc_free(dst);
     270           0 :                 return NULL;
     271             :         }
     272    10471740 :         dst[len] = '\0';
     273    10471740 :         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   791731977 : static bool ldb_dn_explode(struct ldb_dn *dn)
     284             : {
     285   791731977 :         char *p, *ex_name = NULL, *ex_value = NULL, *data, *d, *dt, *t;
     286   791731977 :         bool trim = true;
     287   791731977 :         bool in_extended = true;
     288   791731977 :         bool in_ex_name = false;
     289   791731977 :         bool in_ex_value = false;
     290   791731977 :         bool in_attr = false;
     291   791731977 :         bool in_value = false;
     292   791731977 :         bool in_quote = false;
     293   791731977 :         bool is_oid = false;
     294   791731977 :         bool escape = false;
     295             :         unsigned int x;
     296   791731977 :         size_t l = 0;
     297             :         int ret;
     298             :         char *parse_dn;
     299             :         bool is_index;
     300             : 
     301   791731977 :         if (dn == NULL || dn->invalid) {
     302          11 :                 return false;
     303             :         }
     304             : 
     305   791731966 :         if (dn->components != NULL) {
     306   421024354 :                 return true;
     307             :         }
     308             : 
     309   370707612 :         if (dn->ext_linearized != NULL) {
     310    25582492 :                 parse_dn = dn->ext_linearized;
     311             :         } else {
     312   345125120 :                 parse_dn = dn->linearized;
     313             :         }
     314             : 
     315   370707612 :         if (parse_dn == NULL) {
     316           0 :                 return false;
     317             :         }
     318             : 
     319   370707612 :         is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
     320             : 
     321             :         /* Empty DNs */
     322   370707612 :         if (parse_dn[0] == '\0') {
     323    20269993 :                 return true;
     324             :         }
     325             : 
     326             :         /* Special DNs case */
     327   350437619 :         if (dn->special) {
     328   165761715 :                 return true;
     329             :         }
     330             : 
     331   184675904 :         LDB_FREE(dn->ext_components);
     332   184675904 :         dn->ext_comp_num = 0;
     333   184675904 :         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   184675904 :         dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
     338   184675904 :         if (dn->components == NULL) {
     339           0 :                 return false;
     340             :         }
     341             : 
     342             :         /* Components data space is allocated here once */
     343   184675904 :         data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
     344   184675904 :         if (data == NULL) {
     345           0 :                 goto failed;
     346             :         }
     347             : 
     348   184675904 :         p = parse_dn;
     349   184675904 :         t = NULL;
     350   184675904 :         d = dt = data;
     351             : 
     352 17622610509 :         while (*p) {
     353 17303663555 :                 if (in_extended) {
     354             : 
     355  1755868709 :                         if (!in_ex_name && !in_ex_value) {
     356             : 
     357   217835433 :                                 if (p[0] == '<') {
     358    39291010 :                                         p++;
     359    39291010 :                                         ex_name = d;
     360    39291010 :                                         in_ex_name = true;
     361    39291010 :                                         continue;
     362             :                                 } else {
     363   178544423 :                                         in_extended = false;
     364   178544423 :                                         in_attr = true;
     365   178544423 :                                         dt = d;
     366             : 
     367   178544423 :                                         continue;
     368             :                                 }
     369             :                         }
     370             : 
     371  1538033276 :                         if (in_ex_name && *p == '=') {
     372    39291006 :                                 *d++ = '\0';
     373    39291006 :                                 p++;
     374    39291006 :                                 ex_value = d;
     375    39291006 :                                 in_ex_name = false;
     376    39291006 :                                 in_ex_value = true;
     377    39291006 :                                 continue;
     378             :                         }
     379             : 
     380  1498742270 :                         if (in_ex_value && *p == '>') {
     381    39291006 :                                 struct ldb_dn_ext_component *ext_comp = NULL;
     382             :                                 const struct ldb_dn_extended_syntax *ext_syntax;
     383    74950394 :                                 struct ldb_val ex_val = {
     384             :                                         .data = (uint8_t *)ex_value,
     385    39291006 :                                         .length = d - ex_value
     386             :                                 };
     387             : 
     388    39291006 :                                 *d++ = '\0';
     389    39291006 :                                 p++;
     390    39291006 :                                 in_ex_value = false;
     391             : 
     392             :                                 /* Process name and ex_value */
     393             : 
     394    39291006 :                                 ext_comp = talloc_realloc(
     395             :                                         dn,
     396             :                                         dn->ext_components,
     397             :                                         struct ldb_dn_ext_component,
     398             :                                         dn->ext_comp_num + 1);
     399             : 
     400    39291006 :                                 if (ext_comp == NULL) {
     401             :                                         /* ouch ! */
     402          10 :                                         goto failed;
     403             :                                 }
     404             : 
     405    39291006 :                                 dn->ext_components = ext_comp;
     406             : 
     407    39291006 :                                 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
     408    39291006 :                                 if (ext_syntax == NULL) {
     409             :                                         /* We don't know about this type of extended DN */
     410           8 :                                         goto failed;
     411             :                                 }
     412             : 
     413    39290998 :                                 dn->ext_components[dn->ext_comp_num].name = ext_syntax->name;
     414    74950378 :                                 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
     415    39290998 :                                                           &ex_val, &dn->ext_components[dn->ext_comp_num].value);
     416    39290998 :                                 if (ret != LDB_SUCCESS) {
     417           2 :                                         ldb_dn_mark_invalid(dn);
     418           2 :                                         goto failed;
     419             :                                 }
     420             : 
     421    39290996 :                                 dn->ext_comp_num++;
     422             : 
     423    39290996 :                                 if (*p == '\0') {
     424             :                                         /* We have reached the end (extended component only)! */
     425     6131467 :                                         talloc_free(data);
     426     6131467 :                                         return true;
     427             : 
     428    33159529 :                                 } else if (*p == ';') {
     429    33159529 :                                         p++;
     430    33159529 :                                         continue;
     431             :                                 } else {
     432           0 :                                         ldb_dn_mark_invalid(dn);
     433           0 :                                         goto failed;
     434             :                                 }
     435             :                         }
     436             : 
     437  1459451264 :                         *d++ = *p++;
     438  1459451264 :                         continue;
     439             :                 }
     440 15547794846 :                 if (in_attr) {
     441  3065597695 :                         if (trim) {
     442  1021221093 :                                 if (*p == ' ') {
     443         219 :                                         p++;
     444         219 :                                         continue;
     445             :                                 }
     446             : 
     447             :                                 /* first char */
     448  1021220874 :                                 trim = false;
     449             : 
     450  1021220874 :                                 if (!isascii(*p)) {
     451             :                                         /* attr names must be ascii only */
     452           0 :                                         ldb_dn_mark_invalid(dn);
     453           0 :                                         goto failed;
     454             :                                 }
     455             : 
     456  1021220874 :                                 if (isdigit(*p)) {
     457           0 :                                         is_oid = true;
     458             :                                 } else
     459  1021220874 :                                 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  1021220867 :                                 *d++ = *p++;
     469  1021220867 :                                 continue;
     470             :                         }
     471             : 
     472  2044376602 :                         if (*p == ' ') {
     473          48 :                                 p++;
     474             :                                 /* valid only if we are at the end */
     475          48 :                                 trim = true;
     476          48 :                                 continue;
     477             :                         }
     478             : 
     479  2044376554 :                         if (*p == '=') {
     480             :                                 /* attribute terminated */
     481  1021202926 :                                 in_attr = false;
     482  1021202926 :                                 in_value = true;
     483  1021202926 :                                 trim = true;
     484  1021202926 :                                 l = 0;
     485             : 
     486             :                                 /* Terminate this string in d
     487             :                                  * (which is a copy of parse_dn
     488             :                                  *  with spaces trimmed) */
     489  1021202926 :                                 *d++ = '\0';
     490  1021202926 :                                 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
     491  1021202926 :                                 if (dn->components[dn->comp_num].name == NULL) {
     492             :                                         /* ouch */
     493           0 :                                         goto failed;
     494             :                                 }
     495             : 
     496  1021202926 :                                 dt = d;
     497             : 
     498  1021202926 :                                 p++;
     499  1021202926 :                                 continue;
     500             :                         }
     501             : 
     502  1023173628 :                         if (!isascii(*p)) {
     503             :                                 /* attr names must be ascii only */
     504           0 :                                 ldb_dn_mark_invalid(dn);
     505           0 :                                 goto failed;
     506             :                         }
     507             : 
     508  1023173628 :                         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  1023173628 :                         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  1023173219 :                         *d++ = *p++;
     521  1023173219 :                         continue;
     522             :                 }
     523             : 
     524 12482197151 :                 if (in_value) {
     525 12482197151 :                         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 12482197151 :                         if (trim) {
     539  1021202949 :                                 if (*p == ' ') {
     540          31 :                                         p++;
     541          31 :                                         continue;
     542             :                                 }
     543             : 
     544             :                                 /* first char */
     545  1021202918 :                                 trim = false;
     546             : 
     547  1021202918 :                                 if (*p == '\"') {
     548           0 :                                         in_quote = true;
     549           0 :                                         p++;
     550           0 :                                         continue;
     551             :                                 }
     552             :                         }
     553             : 
     554 12482197120 :                         switch (*p) {
     555             : 
     556             :                         /* TODO: support ber encoded values
     557             :                         case '#':
     558             :                         */
     559             : 
     560   842693913 :                         case ',':
     561   842693913 :                                 if (escape) {
     562       17509 :                                         *d++ = *p++;
     563       17509 :                                         l++;
     564       17509 :                                         escape = false;
     565       17509 :                                         continue;
     566             :                                 }
     567             :                                 /* ok found value terminator */
     568             : 
     569   842676404 :                                 if (t != NULL) {
     570             :                                         /* trim back */
     571          22 :                                         d -= (p - t);
     572          22 :                                         l -= (p - t);
     573          22 :                                         t = NULL;
     574             :                                 }
     575             : 
     576   842676404 :                                 in_attr = true;
     577   842676404 :                                 in_value = false;
     578   842676404 :                                 trim = true;
     579             : 
     580   842676404 :                                 p++;
     581   842676404 :                                 *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  1685352808 :                                 dn->components[dn->comp_num].value.data = \
     589  1488104917 :                                         (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
     590   842676404 :                                 dn->components[dn->comp_num].value.length = l;
     591   842676404 :                                 if (dn->components[dn->comp_num].value.data == NULL) {
     592             :                                         /* ouch ! */
     593           0 :                                         goto failed;
     594             :                                 }
     595   842676404 :                                 talloc_set_name_const(dn->components[dn->comp_num].value.data,
     596   842676404 :                                                       (const char *)dn->components[dn->comp_num].value.data);
     597             : 
     598   842676404 :                                 dt = d;
     599             : 
     600   842676404 :                                 dn->comp_num++;
     601   842676404 :                                 if (dn->comp_num > 2) {
     602   491368762 :                                         dn->components = talloc_realloc(dn,
     603             :                                                                         dn->components,
     604             :                                                                         struct ldb_dn_component,
     605             :                                                                         dn->comp_num + 1);
     606   491368762 :                                         if (dn->components == NULL) {
     607             :                                                 /* ouch ! */
     608           0 :                                                 goto failed;
     609             :                                         }
     610             :                                         /* make sure all components are zeroed, other functions depend on this */
     611   491368762 :                                         memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
     612             :                                 }
     613             : 
     614   842676404 :                                 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           0 :                                 if (!escape) {
     639           0 :                                         ldb_dn_mark_invalid(dn);
     640           0 :                                         goto failed;
     641             :                                 }
     642           0 :                                 escape = false;
     643             : 
     644           0 :                                 *d++ = *p++;
     645           0 :                                 l++;
     646             : 
     647           0 :                                 if (t != NULL) {
     648           0 :                                         t = NULL;
     649             :                                 }
     650           0 :                                 break;
     651             : 
     652    58338698 :                         case '\\':
     653    58338698 :                                 if (!escape) {
     654    58333418 :                                         escape = true;
     655    58333418 :                                         p++;
     656    58333418 :                                         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 11581164509 :                         default:
     669 11581164509 :                                 if (escape) {
     670    58310629 :                                         if (isxdigit(p[0]) && isxdigit(p[1])) {
     671    58310629 :                                                 if (sscanf(p, "%02x", &x) != 1) {
     672             :                                                         /* invalid escaping sequence */
     673           0 :                                                         ldb_dn_mark_invalid(dn);
     674           0 :                                                         goto failed;
     675             :                                                 }
     676    58310629 :                                                 p += 2;
     677    58310629 :                                                 *d++ = (unsigned char)x;
     678             :                                         } else {
     679           0 :                                                 *d++ = *p++;
     680             :                                         }
     681             : 
     682    58310629 :                                         escape = false;
     683    58310629 :                                         l++;
     684    58310629 :                                         if (t != NULL) {
     685           0 :                                                 t = NULL;
     686             :                                         }
     687    58310629 :                                         break;
     688             :                                 }
     689             : 
     690 11522853880 :                                 if (*p == ' ') {
     691    82721389 :                                         if (t == NULL) {
     692    82717722 :                                                 t = p;
     693             :                                         }
     694             :                                 } else {
     695 11440132491 :                                         if (t != NULL) {
     696    82717550 :                                                 t = NULL;
     697             :                                         }
     698             :                                 }
     699             : 
     700 11522853880 :                                 *d++ = *p++;
     701 11522853880 :                                 l++;
     702             : 
     703 11522853880 :                                 break;
     704             :                         }
     705             : 
     706           0 :                 }
     707             :         }
     708             : 
     709   178544011 :         if (in_attr || in_quote) {
     710             :                 /* invalid dn */
     711       17485 :                 ldb_dn_mark_invalid(dn);
     712       17485 :                 goto failed;
     713             :         }
     714             : 
     715   178526526 :         if (in_value) {
     716             :                 /* save last element */
     717   178526522 :                 if (t != NULL) {
     718             :                         /* trim back */
     719         150 :                         d -= (p - t);
     720         150 :                         l -= (p - t);
     721             :                 }
     722             : 
     723   178526522 :                 *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   178526522 :                 dn->components[dn->comp_num].value.length = l;
     730   357053044 :                 dn->components[dn->comp_num].value.data =
     731   313221250 :                         (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
     732   178526522 :                 if (dn->components[dn->comp_num].value.data == NULL) {
     733             :                         /* ouch */
     734           0 :                         goto failed;
     735             :                 }
     736   178526522 :                 talloc_set_name_const(dn->components[dn->comp_num].value.data,
     737   178526522 :                         (const char *)dn->components[dn->comp_num].value.data);
     738             : 
     739   178526522 :                 dn->comp_num++;
     740             :         }
     741   178526526 :         talloc_free(data);
     742   178526526 :         return true;
     743             : 
     744       17911 : failed:
     745       17911 :         LDB_FREE(dn->components); /* "data" is implicitly free'd */
     746       17911 :         dn->comp_num = 0;
     747       17911 :         LDB_FREE(dn->ext_components);
     748       17911 :         dn->ext_comp_num = 0;
     749             : 
     750       17911 :         return false;
     751             : }
     752             : 
     753   722787919 : bool ldb_dn_validate(struct ldb_dn *dn)
     754             : {
     755   722787919 :         return ldb_dn_explode(dn);
     756             : }
     757             : 
     758   520948851 : 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   520948851 :         if ( ! dn || ( dn->invalid)) return NULL;
     765             : 
     766   520948573 :         if (dn->linearized) return dn->linearized;
     767             : 
     768     7639271 :         if ( ! dn->components) {
     769           0 :                 ldb_dn_mark_invalid(dn);
     770           0 :                 return NULL;
     771             :         }
     772             : 
     773     7639271 :         if (dn->comp_num == 0) {
     774      200101 :                 dn->linearized = talloc_strdup(dn, "");
     775      200101 :                 if ( ! dn->linearized) return NULL;
     776      200101 :                 return dn->linearized;
     777             :         }
     778             : 
     779             :         /* calculate maximum possible length of DN */
     780    48750778 :         for (len = 0, i = 0; i < dn->comp_num; i++) {
     781             :                 /* name len */
     782    41311608 :                 len += strlen(dn->components[i].name);
     783             :                 /* max escaped data len */
     784    41311608 :                 len += (dn->components[i].value.length * 3);
     785    41311608 :                 len += 2; /* '=' and ',' */
     786             :         }
     787     7439170 :         dn->linearized = talloc_array(dn, char, len);
     788     7439170 :         if ( ! dn->linearized) return NULL;
     789             : 
     790     7439170 :         d = dn->linearized;
     791             : 
     792    48750778 :         for (i = 0; i < dn->comp_num; i++) {
     793             : 
     794             :                 /* copy the name */
     795    41311608 :                 n = dn->components[i].name;
     796    49243160 :                 while (*n) *d++ = *n++;
     797             : 
     798    41311608 :                 *d++ = '=';
     799             : 
     800             :                 /* and the value */
     801    82623216 :                 d += ldb_dn_escape_internal( d,
     802    41311608 :                                 (char *)dn->components[i].value.data,
     803    41311608 :                                 dn->components[i].value.length);
     804    41311608 :                 *d++ = ',';
     805             :         }
     806             : 
     807     7439170 :         *(--d) = '\0';
     808             : 
     809             :         /* don't waste more memory than necessary */
     810     7439170 :         dn->linearized = talloc_realloc(dn, dn->linearized,
     811             :                                         char, (d - dn->linearized + 1));
     812             : 
     813     7439170 :         return dn->linearized;
     814             : }
     815             : 
     816    12519999 : static int ldb_dn_extended_component_compare(const void *p1, const void *p2)
     817             : {
     818    12519999 :         const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1;
     819    12519999 :         const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2;
     820    12519999 :         return strcmp(ec1->name, ec2->name);
     821             : }
     822             : 
     823    16981786 : char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode)
     824             : {
     825    16981786 :         const char *linearized = ldb_dn_get_linearized(dn);
     826    16981786 :         char *p = NULL;
     827             :         unsigned int i;
     828             : 
     829    16981786 :         if (!linearized) {
     830          96 :                 return NULL;
     831             :         }
     832             : 
     833    16981690 :         if (!ldb_dn_has_extended(dn)) {
     834     1195915 :                 return talloc_strdup(mem_ctx, linearized);
     835             :         }
     836             : 
     837    15785775 :         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    15785772 :         TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num,
     846             :                        ldb_dn_extended_component_compare);
     847             : 
     848    70103924 :         for (i = 0; i < dn->ext_comp_num; i++) {
     849             :                 const struct ldb_dn_extended_syntax *ext_syntax;
     850    21518975 :                 const char *name = dn->ext_components[i].name;
     851    21518975 :                 struct ldb_val ec_val = dn->ext_components[i].value;
     852             :                 struct ldb_val val;
     853             :                 int ret;
     854             : 
     855    21518975 :                 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
     856    21518975 :                 if (!ext_syntax) {
     857           0 :                         return NULL;
     858             :                 }
     859             : 
     860    21518975 :                 if (mode == 1) {
     861    13416173 :                         ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
     862             :                                                         &ec_val, &val);
     863     8102802 :                 } else if (mode == 0) {
     864     8102802 :                         ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
     865             :                                                         &ec_val, &val);
     866             :                 } else {
     867           0 :                         ret = -1;
     868             :                 }
     869             : 
     870    21518975 :                 if (ret != LDB_SUCCESS) {
     871           0 :                         return NULL;
     872             :                 }
     873             : 
     874    21518975 :                 if (i == 0) {
     875    29613275 :                         p = talloc_asprintf(mem_ctx, "<%s=%.*s>",
     876             :                                             name,
     877    15785768 :                                             (int)val.length,
     878             :                                             val.data);
     879             :                 } else {
     880    10877366 :                         p = talloc_asprintf_append_buffer(p, ";<%s=%.*s>",
     881             :                                                           name,
     882     5733207 :                                                           (int)val.length,
     883             :                                                           val.data);
     884             :                 }
     885             : 
     886    21518975 :                 talloc_free(val.data);
     887             : 
     888    21518975 :                 if (!p) {
     889           0 :                         return NULL;
     890             :                 }
     891             :         }
     892             : 
     893    15785772 :         if (dn->ext_comp_num && *linearized) {
     894    15103665 :                 p = talloc_asprintf_append_buffer(p, ";%s", linearized);
     895             :         }
     896             : 
     897    15785772 :         if (!p) {
     898           4 :                 return NULL;
     899             :         }
     900             : 
     901    15785768 :         return p;
     902             : }
     903             : 
     904             : /*
     905             :   filter out all but an acceptable list of extended DN components
     906             :  */
     907     9889953 : void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list)
     908             : {
     909             :         unsigned int i;
     910    25098383 :         for (i=0; i<dn->ext_comp_num; i++) {
     911    15208430 :                 if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) {
     912     2849848 :                         ARRAY_DEL_ELEMENT(
     913             :                                 dn->ext_components, i, dn->ext_comp_num);
     914     2849848 :                         dn->ext_comp_num--;
     915     2849848 :                         i--;
     916             :                 }
     917             :         }
     918     9889953 :         LDB_FREE(dn->ext_linearized);
     919     9889953 : }
     920             : 
     921             : 
     922   120201524 : char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
     923             : {
     924   120201524 :         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   195394689 : static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
     933             : {
     934             :         unsigned int i;
     935             :         int ret;
     936             : 
     937   195394689 :         if ( ! dn || dn->invalid) return false;
     938             : 
     939   195394689 :         if (dn->valid_case) return true;
     940             : 
     941    97472445 :         if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
     942         630 :                 return false;
     943             :         }
     944             : 
     945   626077330 :         for (i = 0; i < dn->comp_num; i++) {
     946             :                 const struct ldb_schema_attribute *a;
     947             : 
     948  1057211030 :                 dn->components[i].cf_name =
     949   932456773 :                         ldb_attr_casefold(dn->components,
     950   528605515 :                                           dn->components[i].name);
     951   528605515 :                 if (!dn->components[i].cf_name) {
     952           0 :                         goto failed;
     953             :                 }
     954             : 
     955   528605515 :                 a = ldb_schema_attribute_by_name(dn->ldb,
     956   528605515 :                                                  dn->components[i].cf_name);
     957             : 
     958  1336308031 :                 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
     959   528605515 :                                                  &(dn->components[i].value),
     960   528605515 :                                                  &(dn->components[i].cf_value));
     961   528605515 :                 if (ret != 0) {
     962           0 :                         goto failed;
     963             :                 }
     964             :         }
     965             : 
     966    97471815 :         dn->valid_case = true;
     967             : 
     968    97471815 :         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   314886277 : 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   314886277 :         if (dn->casefold) return dn->casefold;
     985             : 
     986   200529438 :         if (dn->special) {
     987   177670709 :                 dn->casefold = talloc_strdup(dn, dn->linearized);
     988   177670709 :                 if (!dn->casefold) return NULL;
     989   177670709 :                 dn->valid_case = true;
     990   177670709 :                 return dn->casefold;
     991             :         }
     992             : 
     993    22858729 :         if ( ! ldb_dn_casefold_internal(dn)) {
     994           0 :                 return NULL;
     995             :         }
     996             : 
     997    22858729 :         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   138194172 :         for (len = 0, i = 0; i < dn->comp_num; i++) {
    1004             :                 /* name len */
    1005   115336473 :                 len += strlen(dn->components[i].cf_name);
    1006             :                 /* max escaped data len */
    1007   115336473 :                 len += (dn->components[i].cf_value.length * 3);
    1008   115336473 :                 len += 2; /* '=' and ',' */
    1009             :         }
    1010    22857699 :         dn->casefold = talloc_array(dn, char, len);
    1011    22857699 :         if ( ! dn->casefold) return NULL;
    1012             : 
    1013    22857699 :         d = dn->casefold;
    1014             : 
    1015   138194172 :         for (i = 0; i < dn->comp_num; i++) {
    1016             : 
    1017             :                 /* copy the name */
    1018   115336473 :                 n = dn->components[i].cf_name;
    1019   141253489 :                 while (*n) *d++ = *n++;
    1020             : 
    1021   115336473 :                 *d++ = '=';
    1022             : 
    1023             :                 /* and the value */
    1024   230672946 :                 d += ldb_dn_escape_internal( d,
    1025   115336473 :                                 (char *)dn->components[i].cf_value.data,
    1026   115336473 :                                 dn->components[i].cf_value.length);
    1027   115336473 :                 *d++ = ',';
    1028             :         }
    1029    22857699 :         *(--d) = '\0';
    1030             : 
    1031             :         /* don't waste more memory than necessary */
    1032    22857699 :         dn->casefold = talloc_realloc(dn, dn->casefold,
    1033             :                                       char, strlen(dn->casefold) + 1);
    1034             : 
    1035    22857699 :         return dn->casefold;
    1036             : }
    1037             : 
    1038     1919107 : char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1039             : {
    1040     1919107 :         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   390431177 : 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   390431177 :         if ( ! base || base->invalid) return 1;
    1054   390431177 :         if ( ! dn || dn->invalid) return -1;
    1055             : 
    1056   390431177 :         if (( ! base->valid_case) || ( ! dn->valid_case)) {
    1057   273441009 :                 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   267685315 :                         dif = strlen(dn->linearized) - strlen(base->linearized);
    1062   267685315 :                         if (dif < 0) {
    1063    85568561 :                                 return dif;
    1064             :                         }
    1065   320644605 :                         if (strcmp(base->linearized,
    1066   320644605 :                                    &dn->linearized[dif]) == 0) {
    1067   108161858 :                                 return 0;
    1068             :                         }
    1069             :                 }
    1070             : 
    1071    79710590 :                 if ( ! ldb_dn_casefold_internal(base)) {
    1072           0 :                         return 1;
    1073             :                 }
    1074             : 
    1075    79710590 :                 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   196700758 :         if (base->comp_num > dn->comp_num) {
    1084    35734752 :                 return (dn->comp_num - base->comp_num);
    1085             :         }
    1086             : 
    1087   160966006 :         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   160966006 :         n_base = base->comp_num - 1;
    1100   160966006 :         n_dn = dn->comp_num - 1;
    1101             : 
    1102   891300906 :         while (n_base != (unsigned int) -1) {
    1103   689741977 :                 char *b_name = base->components[n_base].cf_name;
    1104   689741977 :                 char *dn_name = dn->components[n_dn].cf_name;
    1105             : 
    1106   689741977 :                 char *b_vdata = (char *)base->components[n_base].cf_value.data;
    1107   689741977 :                 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
    1108             : 
    1109   689741977 :                 size_t b_vlen = base->components[n_base].cf_value.length;
    1110   689741977 :                 size_t dn_vlen = dn->components[n_dn].cf_value.length;
    1111             : 
    1112             :                 /* compare attr names */
    1113   689741977 :                 ret = strcmp(b_name, dn_name);
    1114   689741977 :                 if (ret != 0) return ret;
    1115             : 
    1116             :                 /* compare attr.cf_value. */
    1117   623545515 :                 if (b_vlen != dn_vlen) {
    1118    30159749 :                         return b_vlen - dn_vlen;
    1119             :                 }
    1120   593385766 :                 ret = strncmp(b_vdata, dn_vdata, b_vlen);
    1121   593385766 :                 if (ret != 0) return ret;
    1122             : 
    1123   591994425 :                 n_base--;
    1124   591994425 :                 n_dn--;
    1125             :         }
    1126             : 
    1127    63218454 :         return 0;
    1128             : }
    1129             : 
    1130             : /* compare DNs using casefolding compare functions.
    1131             : 
    1132             :    If they match, then return 0
    1133             :  */
    1134             : 
    1135    41892114 : int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
    1136             : {
    1137             :         unsigned int i;
    1138             :         int ret;
    1139             : 
    1140    41892114 :         if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
    1141           2 :                 return -1;
    1142             :         }
    1143             : 
    1144    41892112 :         if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
    1145     7822691 :                 if (dn0->linearized && dn1->linearized) {
    1146             :                         /* try with a normal compare first, if we are lucky
    1147             :                          * we will avoid exploding and casfolding */
    1148     6167559 :                         if (strcmp(dn0->linearized, dn1->linearized) == 0) {
    1149     1265301 :                                 return 0;
    1150             :                         }
    1151             :                 }
    1152             : 
    1153     6557390 :                 if ( ! ldb_dn_casefold_internal(dn0)) {
    1154           0 :                         return 1;
    1155             :                 }
    1156             : 
    1157     6557390 :                 if ( ! ldb_dn_casefold_internal(dn1)) {
    1158         630 :                         return -1;
    1159             :                 }
    1160             : 
    1161             :         }
    1162             : 
    1163    40626181 :         if (dn0->comp_num != dn1->comp_num) {
    1164    25325658 :                 return (dn1->comp_num - dn0->comp_num);
    1165             :         }
    1166             : 
    1167    15300523 :         if (dn0->comp_num == 0) {
    1168      892598 :                 if (dn0->special && dn1->special) {
    1169      892598 :                         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    45560116 :         for (i = 0; i < dn0->comp_num; i++) {
    1180    38848642 :                 char *dn0_name = dn0->components[i].cf_name;
    1181    38848642 :                 char *dn1_name = dn1->components[i].cf_name;
    1182             : 
    1183    38848642 :                 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
    1184    38848642 :                 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
    1185             : 
    1186    38848642 :                 size_t dn0_vlen = dn0->components[i].cf_value.length;
    1187    38848642 :                 size_t dn1_vlen = dn1->components[i].cf_value.length;
    1188             : 
    1189             :                 /* compare attr names */
    1190    38848642 :                 ret = strcmp(dn0_name, dn1_name);
    1191    38848642 :                 if (ret != 0) {
    1192     1894901 :                         return ret;
    1193             :                 }
    1194             : 
    1195             :                 /* compare attr.cf_value. */
    1196    36953741 :                 if (dn0_vlen != dn1_vlen) {
    1197     3036516 :                         return dn0_vlen - dn1_vlen;
    1198             :                 }
    1199    33917225 :                 ret = strncmp(dn0_vdata, dn1_vdata, dn0_vlen);
    1200    33917225 :                 if (ret != 0) {
    1201     2765034 :                         return ret;
    1202             :                 }
    1203             :         }
    1204             : 
    1205     6711474 :         return 0;
    1206             : }
    1207             : 
    1208   286338018 : 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   286338018 :         memset(&dst, 0, sizeof(dst));
    1215             : 
    1216   286338018 :         if (src == NULL) {
    1217           0 :                 return dst;
    1218             :         }
    1219             : 
    1220   286338018 :         dst.value = ldb_val_dup(mem_ctx, &(src->value));
    1221   286338018 :         if (dst.value.data == NULL) {
    1222           0 :                 return dst;
    1223             :         }
    1224             : 
    1225   286338018 :         dst.name = talloc_strdup(mem_ctx, src->name);
    1226   286338018 :         if (dst.name == NULL) {
    1227           0 :                 LDB_FREE(dst.value.data);
    1228           0 :                 return dst;
    1229             :         }
    1230             : 
    1231   286338018 :         if (src->cf_value.data) {
    1232   231187881 :                 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
    1233   231187881 :                 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   231187881 :                 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
    1240   231187881 :                 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    55150137 :                 dst.cf_value.data = NULL;
    1248    55150137 :                 dst.cf_name = NULL;
    1249             :         }
    1250             : 
    1251   286338018 :         return dst;
    1252             : }
    1253             : 
    1254    22149140 : 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    22149140 :         memset(&dst, 0, sizeof(dst));
    1261             : 
    1262    22149140 :         if (src == NULL) {
    1263           0 :                 return dst;
    1264             :         }
    1265             : 
    1266    22149140 :         dst.value = ldb_val_dup(mem_ctx, &(src->value));
    1267    22149140 :         if (dst.value.data == NULL) {
    1268           0 :                 return dst;
    1269             :         }
    1270             : 
    1271    22149140 :         dst.name = talloc_strdup(mem_ctx, src->name);
    1272    22149140 :         if (dst.name == NULL) {
    1273           0 :                 LDB_FREE(dst.value.data);
    1274           0 :                 return dst;
    1275             :         }
    1276             : 
    1277    22149140 :         return dst;
    1278             : }
    1279             : 
    1280    55275903 : struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1281             : {
    1282             :         struct ldb_dn *new_dn;
    1283             : 
    1284    55275903 :         if (!dn || dn->invalid) {
    1285           2 :                 return NULL;
    1286             :         }
    1287             : 
    1288    55275901 :         new_dn = talloc_zero(mem_ctx, struct ldb_dn);
    1289    55275901 :         if ( !new_dn) {
    1290           0 :                 return NULL;
    1291             :         }
    1292             : 
    1293    55275901 :         *new_dn = *dn;
    1294             : 
    1295    55275901 :         if (dn->components) {
    1296             :                 unsigned int i;
    1297             : 
    1298    48549866 :                 new_dn->components =
    1299    48549866 :                         talloc_zero_array(new_dn,
    1300             :                                           struct ldb_dn_component,
    1301             :                                           dn->comp_num);
    1302    48549866 :                 if ( ! new_dn->components) {
    1303           0 :                         talloc_free(new_dn);
    1304           0 :                         return NULL;
    1305             :                 }
    1306             : 
    1307   324663196 :                 for (i = 0; i < dn->comp_num; i++) {
    1308   276113330 :                         new_dn->components[i] =
    1309   276113330 :                                 ldb_dn_copy_component(new_dn->components,
    1310   276113330 :                                                       &dn->components[i]);
    1311   276113330 :                         if ( ! new_dn->components[i].value.data) {
    1312           0 :                                 talloc_free(new_dn);
    1313           0 :                                 return NULL;
    1314             :                         }
    1315             :                 }
    1316             :         }
    1317             : 
    1318    55275901 :         if (dn->ext_components) {
    1319             :                 unsigned int i;
    1320             : 
    1321    17970412 :                 new_dn->ext_components =
    1322    17970412 :                         talloc_zero_array(new_dn,
    1323             :                                           struct ldb_dn_ext_component,
    1324             :                                           dn->ext_comp_num);
    1325    17970412 :                 if ( ! new_dn->ext_components) {
    1326           0 :                         talloc_free(new_dn);
    1327           0 :                         return NULL;
    1328             :                 }
    1329             : 
    1330    40119552 :                 for (i = 0; i < dn->ext_comp_num; i++) {
    1331    22149140 :                         new_dn->ext_components[i] =
    1332    22149140 :                                  ldb_dn_ext_copy_component(
    1333    22149140 :                                                 new_dn->ext_components,
    1334    22149140 :                                                 &dn->ext_components[i]);
    1335    22149140 :                         if ( ! new_dn->ext_components[i].value.data) {
    1336           0 :                                 talloc_free(new_dn);
    1337           0 :                                 return NULL;
    1338             :                         }
    1339             :                 }
    1340             :         }
    1341             : 
    1342    55275901 :         if (dn->casefold) {
    1343    30882261 :                 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
    1344    30882261 :                 if ( ! new_dn->casefold) {
    1345           0 :                         talloc_free(new_dn);
    1346           0 :                         return NULL;
    1347             :                 }
    1348             :         }
    1349             : 
    1350    55275901 :         if (dn->linearized) {
    1351    55129479 :                 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
    1352    55129479 :                 if ( ! new_dn->linearized) {
    1353           0 :                         talloc_free(new_dn);
    1354           0 :                         return NULL;
    1355             :                 }
    1356             :         }
    1357             : 
    1358    55275901 :         if (dn->ext_linearized) {
    1359     1054033 :                 new_dn->ext_linearized = talloc_strdup(new_dn,
    1360      931744 :                                                         dn->ext_linearized);
    1361      931744 :                 if ( ! new_dn->ext_linearized) {
    1362           0 :                         talloc_free(new_dn);
    1363           0 :                         return NULL;
    1364             :                 }
    1365             :         }
    1366             : 
    1367    55275901 :         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      466336 : bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
    1376             : {
    1377             :         const char *s;
    1378             :         char *t;
    1379             : 
    1380      466336 :         if ( !base || base->invalid || !dn || dn->invalid) {
    1381           0 :                 return false;
    1382             :         }
    1383             : 
    1384      466336 :         if (dn == base) {
    1385           0 :                 return false; /* or we will visit infinity */
    1386             :         }
    1387             : 
    1388      466336 :         if (dn->components) {
    1389             :                 unsigned int i;
    1390             : 
    1391      373836 :                 if ( ! ldb_dn_validate(base)) {
    1392           0 :                         return false;
    1393             :                 }
    1394             : 
    1395      373836 :                 s = NULL;
    1396      373836 :                 if (dn->valid_case) {
    1397           2 :                         if ( ! (s = ldb_dn_get_casefold(base))) {
    1398           0 :                                 return false;
    1399             :                         }
    1400             :                 }
    1401             : 
    1402      373836 :                 dn->components = talloc_realloc(dn,
    1403             :                                                 dn->components,
    1404             :                                                 struct ldb_dn_component,
    1405             :                                                 dn->comp_num + base->comp_num);
    1406      373836 :                 if ( ! dn->components) {
    1407           0 :                         ldb_dn_mark_invalid(dn);
    1408           0 :                         return false;
    1409             :                 }
    1410             : 
    1411     2495313 :                 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
    1412     2121477 :                         dn->components[dn->comp_num] =
    1413     2121477 :                                 ldb_dn_copy_component(dn->components,
    1414     2121477 :                                                         &base->components[i]);
    1415     2121477 :                         if (dn->components[dn->comp_num].value.data == NULL) {
    1416           0 :                                 ldb_dn_mark_invalid(dn);
    1417           0 :                                 return false;
    1418             :                         }
    1419             :                 }
    1420             : 
    1421      373836 :                 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      466336 :         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      466336 :         LDB_FREE(dn->ext_linearized);
    1457      466336 :         LDB_FREE(dn->ext_components);
    1458      466336 :         dn->ext_comp_num = 0;
    1459             : 
    1460      466336 :         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     4376367 : bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
    1502             : {
    1503             :         const char *s;
    1504             :         char *t;
    1505             : 
    1506     4376367 :         if ( !child || child->invalid || !dn || dn->invalid) {
    1507           0 :                 return false;
    1508             :         }
    1509             : 
    1510     4376367 :         if (dn->components) {
    1511             :                 unsigned int n;
    1512             :                 unsigned int i, j;
    1513             : 
    1514     4189560 :                 if (dn->comp_num == 0) {
    1515           0 :                         return false;
    1516             :                 }
    1517             : 
    1518     4189560 :                 if ( ! ldb_dn_validate(child)) {
    1519           0 :                         return false;
    1520             :                 }
    1521             : 
    1522     4189560 :                 s = NULL;
    1523     4189560 :                 if (dn->valid_case) {
    1524     2756548 :                         if ( ! (s = ldb_dn_get_casefold(child))) {
    1525           0 :                                 return false;
    1526             :                         }
    1527             :                 }
    1528             : 
    1529     4189560 :                 n = dn->comp_num + child->comp_num;
    1530             : 
    1531     4189560 :                 dn->components = talloc_realloc(dn,
    1532             :                                                 dn->components,
    1533             :                                                 struct ldb_dn_component,
    1534             :                                                 n);
    1535     4189560 :                 if ( ! dn->components) {
    1536           0 :                         ldb_dn_mark_invalid(dn);
    1537           0 :                         return false;
    1538             :                 }
    1539             : 
    1540    25932912 :                 for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1;
    1541    18097647 :                      i--, j--) {
    1542    18097647 :                         dn->components[j] = dn->components[i];
    1543             :                 }
    1544             : 
    1545    11811334 :                 for (i = 0; i < child->comp_num; i++) {
    1546     7621774 :                         dn->components[i] =
    1547     7621774 :                                 ldb_dn_copy_component(dn->components,
    1548     7621774 :                                                         &child->components[i]);
    1549     7621774 :                         if (dn->components[i].value.data == NULL) {
    1550           0 :                                 ldb_dn_mark_invalid(dn);
    1551           0 :                                 return false;
    1552             :                         }
    1553             :                 }
    1554             : 
    1555     4189560 :                 dn->comp_num = n;
    1556             : 
    1557     4189560 :                 if (dn->casefold && s) {
    1558     2288999 :                         t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
    1559     2288999 :                         LDB_FREE(dn->casefold);
    1560     2288999 :                         dn->casefold = t;
    1561             :                 }
    1562             :         }
    1563             : 
    1564     4376367 :         if (dn->linearized) {
    1565     4369830 :                 if (dn->linearized[0] == '\0') {
    1566           0 :                         return false;
    1567             :                 }
    1568             : 
    1569     4369830 :                 s = ldb_dn_get_linearized(child);
    1570     4369830 :                 if ( ! s) {
    1571           0 :                         return false;
    1572             :                 }
    1573             : 
    1574     4369830 :                 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
    1575     4369830 :                 if ( ! t) {
    1576           0 :                         ldb_dn_mark_invalid(dn);
    1577           0 :                         return false;
    1578             :                 }
    1579     4369830 :                 LDB_FREE(dn->linearized);
    1580     4369830 :                 dn->linearized = t;
    1581             :         }
    1582             : 
    1583             :         /* Wipe the ext_linearized DN,
    1584             :          * the GUID and SID are almost certainly no longer valid */
    1585     4376367 :         LDB_FREE(dn->ext_linearized);
    1586     4376367 :         LDB_FREE(dn->ext_components);
    1587     4376367 :         dn->ext_comp_num = 0;
    1588             : 
    1589     4376367 :         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     4231493 : 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     4231493 :         if ( !dn || dn->invalid) {
    1605           0 :                 return false;
    1606             :         }
    1607             : 
    1608     4231493 :         va_start(ap, child_fmt);
    1609     4231493 :         child_str = talloc_vasprintf(dn, child_fmt, ap);
    1610     4231493 :         va_end(ap);
    1611             : 
    1612     4231493 :         if (child_str == NULL) {
    1613           0 :                 return false;
    1614             :         }
    1615             : 
    1616     4231493 :         child = ldb_dn_new(child_str, dn->ldb, child_str);
    1617             : 
    1618     4231493 :         ret = ldb_dn_add_child(dn, child);
    1619             : 
    1620     4231493 :         talloc_free(child_str);
    1621             : 
    1622     4231493 :         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       57094 : 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       57094 :         struct ldb_dn *child = NULL;
    1637             : 
    1638       57094 :         if ( !dn || dn->invalid) {
    1639           0 :                 return false;
    1640             :         }
    1641             : 
    1642       57094 :         child = ldb_dn_new(dn, dn->ldb, "X=Y");
    1643       57094 :         ret = ldb_dn_add_child(dn, child);
    1644             : 
    1645       57094 :         if (ret == false) {
    1646           0 :                 return false;
    1647             :         }
    1648             : 
    1649       57094 :         ldb_ret = ldb_dn_set_component(dn,
    1650             :                                        0,
    1651             :                                        rdn,
    1652             :                                        value);
    1653       57094 :         if (ldb_ret != LDB_SUCCESS) {
    1654           0 :                 return false;
    1655             :         }
    1656             : 
    1657       57094 :         return true;
    1658             : }
    1659             : 
    1660      457822 : bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
    1661             : {
    1662             :         unsigned int i;
    1663             : 
    1664      457822 :         if ( ! ldb_dn_validate(dn)) {
    1665           0 :                 return false;
    1666             :         }
    1667             : 
    1668      457822 :         if (dn->comp_num < num) {
    1669           0 :                 return false;
    1670             :         }
    1671             : 
    1672             :         /* free components */
    1673     2996602 :         for (i = dn->comp_num - num; i < dn->comp_num; i++) {
    1674     2538780 :                 LDB_FREE(dn->components[i].name);
    1675     2538780 :                 LDB_FREE(dn->components[i].value.data);
    1676     2538780 :                 LDB_FREE(dn->components[i].cf_name);
    1677     2538780 :                 LDB_FREE(dn->components[i].cf_value.data);
    1678             :         }
    1679             : 
    1680      457822 :         dn->comp_num -= num;
    1681             : 
    1682      457822 :         if (dn->valid_case) {
    1683      171190 :                 for (i = 0; i < dn->comp_num; i++) {
    1684       85595 :                         LDB_FREE(dn->components[i].cf_name);
    1685       85595 :                         LDB_FREE(dn->components[i].cf_value.data);
    1686             :                 }
    1687       85595 :                 dn->valid_case = false;
    1688             :         }
    1689             : 
    1690      457822 :         LDB_FREE(dn->casefold);
    1691      457822 :         LDB_FREE(dn->linearized);
    1692             : 
    1693             :         /* Wipe the ext_linearized DN,
    1694             :          * the GUID and SID are almost certainly no longer valid */
    1695      457822 :         LDB_FREE(dn->ext_linearized);
    1696      457822 :         LDB_FREE(dn->ext_components);
    1697      457822 :         dn->ext_comp_num = 0;
    1698             : 
    1699      457822 :         return true;
    1700             : }
    1701             : 
    1702     9722400 : bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
    1703             : {
    1704             :         unsigned int i, j;
    1705             : 
    1706     9722400 :         if ( ! ldb_dn_validate(dn)) {
    1707           0 :                 return false;
    1708             :         }
    1709             : 
    1710     9722400 :         if (dn->comp_num < num) {
    1711           3 :                 return false;
    1712             :         }
    1713             : 
    1714    62974514 :         for (i = 0, j = num; j < dn->comp_num; i++, j++) {
    1715    53252117 :                 if (i < num) {
    1716     9721369 :                         LDB_FREE(dn->components[i].name);
    1717     9721369 :                         LDB_FREE(dn->components[i].value.data);
    1718     9721369 :                         LDB_FREE(dn->components[i].cf_name);
    1719     9721369 :                         LDB_FREE(dn->components[i].cf_value.data);
    1720             :                 }
    1721    53252117 :                 dn->components[i] = dn->components[j];
    1722             :         }
    1723             : 
    1724     9722397 :         dn->comp_num -= num;
    1725             : 
    1726     9722397 :         if (dn->valid_case) {
    1727    42686746 :                 for (i = 0; i < dn->comp_num; i++) {
    1728    36121221 :                         LDB_FREE(dn->components[i].cf_name);
    1729    36121221 :                         LDB_FREE(dn->components[i].cf_value.data);
    1730             :                 }
    1731     6565525 :                 dn->valid_case = false;
    1732             :         }
    1733             : 
    1734     9722397 :         LDB_FREE(dn->casefold);
    1735     9722397 :         LDB_FREE(dn->linearized);
    1736             : 
    1737             :         /* Wipe the ext_linearized DN,
    1738             :          * the GUID and SID are almost certainly no longer valid */
    1739     9722397 :         LDB_FREE(dn->ext_linearized);
    1740     9722397 :         LDB_FREE(dn->ext_components);
    1741     9722397 :         dn->ext_comp_num = 0;
    1742             : 
    1743     9722397 :         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      106555 : bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn)
    1754             : {
    1755             :         unsigned int i;
    1756             : 
    1757      106555 :         if ( ! ldb_dn_validate(dn) || ! ldb_dn_validate(new_dn)) {
    1758           0 :                 return false;
    1759             :         }
    1760             : 
    1761             :         /* free components */
    1762      689676 :         for (i = 0; i < dn->comp_num; i++) {
    1763      583121 :                 LDB_FREE(dn->components[i].name);
    1764      583121 :                 LDB_FREE(dn->components[i].value.data);
    1765      583121 :                 LDB_FREE(dn->components[i].cf_name);
    1766      583121 :                 LDB_FREE(dn->components[i].cf_value.data);
    1767             :         }
    1768             : 
    1769      106555 :         dn->components = talloc_realloc(dn,
    1770             :                                         dn->components,
    1771             :                                         struct ldb_dn_component,
    1772             :                                         new_dn->comp_num);
    1773      106555 :         if (dn->components == NULL) {
    1774           0 :                 ldb_dn_mark_invalid(dn);
    1775           0 :                 return false;
    1776             :         }
    1777             : 
    1778      106555 :         dn->comp_num = new_dn->comp_num;
    1779      106555 :         dn->valid_case = new_dn->valid_case;
    1780             : 
    1781      587992 :         for (i = 0; i < dn->comp_num; i++) {
    1782      481437 :                 dn->components[i] = ldb_dn_copy_component(dn->components, &new_dn->components[i]);
    1783      481437 :                 if (dn->components[i].name == NULL) {
    1784           0 :                         ldb_dn_mark_invalid(dn);
    1785           0 :                         return false;
    1786             :                 }
    1787             :         }
    1788      106555 :         if (new_dn->linearized == NULL) {
    1789           0 :                 dn->linearized = NULL;
    1790             :         } else {
    1791      106555 :                 dn->linearized = talloc_strdup(dn, new_dn->linearized);
    1792      106555 :                 if (dn->linearized == NULL) {
    1793           0 :                         ldb_dn_mark_invalid(dn);
    1794           0 :                         return false;
    1795             :                 }
    1796             :         }
    1797             : 
    1798      106555 :         return true;
    1799             : }
    1800             : 
    1801             : 
    1802     9718437 : struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    1803             : {
    1804             :         struct ldb_dn *new_dn;
    1805             : 
    1806     9718437 :         new_dn = ldb_dn_copy(mem_ctx, dn);
    1807     9718437 :         if ( !new_dn ) {
    1808           2 :                 return NULL;
    1809             :         }
    1810             : 
    1811     9718435 :         if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
    1812           3 :                 talloc_free(new_dn);
    1813           3 :                 return NULL;
    1814             :         }
    1815             : 
    1816     9718432 :         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     1793601 : 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     1793601 :         char *cracked = NULL;
    1832     1793601 :         const char *format = (ex_format ? "\n" : "/" );
    1833             : 
    1834     1793601 :         if ( ! ldb_dn_validate(dn)) {
    1835           0 :                 return NULL;
    1836             :         }
    1837             : 
    1838     1793601 :         tmpctx = talloc_new(mem_ctx);
    1839             : 
    1840             :         /* Walk backwards down the DN, grabbing 'dc' components at first */
    1841     7732614 :         for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) {
    1842     7545567 :                 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
    1843     1606554 :                         break;
    1844             :                 }
    1845     5939013 :                 if (cracked) {
    1846     4145479 :                         cracked = talloc_asprintf(tmpctx, "%s.%s",
    1847             :                                                   ldb_dn_escape_value(tmpctx,
    1848     4145479 :                                                         dn->components[i].value),
    1849             :                                                   cracked);
    1850             :                 } else {
    1851     1793534 :                         cracked = ldb_dn_escape_value(tmpctx,
    1852     1793534 :                                                         dn->components[i].value);
    1853             :                 }
    1854     5939013 :                 if (!cracked) {
    1855           0 :                         goto done;
    1856             :                 }
    1857             :         }
    1858             : 
    1859             :         /* Only domain components?  Finish here */
    1860     1793601 :         if (i == (unsigned int) -1) {
    1861      187047 :                 cracked = talloc_strdup_append_buffer(cracked, format);
    1862      187047 :                 talloc_steal(mem_ctx, cracked);
    1863      187047 :                 goto done;
    1864             :         }
    1865             : 
    1866             :         /* Now walk backwards appending remaining components */
    1867     4406537 :         for (; i > 0; i--) {
    1868     2799983 :                 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
    1869             :                                                         ldb_dn_escape_value(tmpctx,
    1870     2799983 :                                                         dn->components[i].value));
    1871     2799983 :                 if (!cracked) {
    1872           0 :                         goto done;
    1873             :                 }
    1874             :         }
    1875             : 
    1876             :         /* Last one, possibly a newline for the 'ex' format */
    1877     1606554 :         cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
    1878             :                                                 ldb_dn_escape_value(tmpctx,
    1879     1606554 :                                                         dn->components[i].value));
    1880             : 
    1881     1606554 :         talloc_steal(mem_ctx, cracked);
    1882     1793601 : done:
    1883     1793601 :         talloc_free(tmpctx);
    1884     1793601 :         return cracked;
    1885             : }
    1886             : 
    1887             : /* Wrapper functions for the above, for the two different string formats */
    1888     1793438 : char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
    1889     1793438 :         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    14756292 : int ldb_dn_get_comp_num(struct ldb_dn *dn)
    1898             : {
    1899    14756292 :         if ( ! ldb_dn_validate(dn)) {
    1900           4 :                 return -1;
    1901             :         }
    1902    14756288 :         return dn->comp_num;
    1903             : }
    1904             : 
    1905     9324842 : int ldb_dn_get_extended_comp_num(struct ldb_dn *dn)
    1906             : {
    1907     9324842 :         if ( ! ldb_dn_validate(dn)) {
    1908           4 :                 return -1;
    1909             :         }
    1910     9324838 :         return dn->ext_comp_num;
    1911             : }
    1912             : 
    1913        6725 : const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
    1914             : {
    1915        6725 :         if ( ! ldb_dn_validate(dn)) {
    1916           0 :                 return NULL;
    1917             :         }
    1918        6725 :         if (num >= dn->comp_num) return NULL;
    1919        6717 :         return dn->components[num].name;
    1920             : }
    1921             : 
    1922      519941 : const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
    1923             :                                                 unsigned int num)
    1924             : {
    1925      519941 :         if ( ! ldb_dn_validate(dn)) {
    1926           0 :                 return NULL;
    1927             :         }
    1928      519941 :         if (num >= dn->comp_num) return NULL;
    1929      519941 :         return &dn->components[num].value;
    1930             : }
    1931             : 
    1932    45353658 : const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
    1933             : {
    1934    45353658 :         if ( ! ldb_dn_validate(dn)) {
    1935           0 :                 return NULL;
    1936             :         }
    1937    45353658 :         if (dn->comp_num == 0) return NULL;
    1938    36576262 :         return dn->components[0].name;
    1939             : }
    1940             : 
    1941    36284883 : const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
    1942             : {
    1943    36284883 :         if ( ! ldb_dn_validate(dn)) {
    1944           2 :                 return NULL;
    1945             :         }
    1946    36284881 :         if (dn->comp_num == 0) return NULL;
    1947    27507485 :         return &dn->components[0].value;
    1948             : }
    1949             : 
    1950      782658 : 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      782658 :         if ( ! ldb_dn_validate(dn)) {
    1957           0 :                 return LDB_ERR_OTHER;
    1958             :         }
    1959             : 
    1960      782658 :         if (num < 0) {
    1961           0 :                 return LDB_ERR_OTHER;
    1962             :         }
    1963             : 
    1964      782658 :         if ((unsigned)num >= dn->comp_num) {
    1965           2 :                 return LDB_ERR_OTHER;
    1966             :         }
    1967             : 
    1968      782656 :         if (val.length > val.length + 1) {
    1969           0 :                 return LDB_ERR_OTHER;
    1970             :         }
    1971             : 
    1972      782656 :         n = talloc_strdup(dn, name);
    1973      782656 :         if ( ! n) {
    1974           0 :                 return LDB_ERR_OTHER;
    1975             :         }
    1976             : 
    1977      782656 :         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      782656 :         v.data = (uint8_t *)talloc_size(dn, v.length+1);
    1984      782656 :         if ( ! v.data) {
    1985           0 :                 talloc_free(n);
    1986           0 :                 return LDB_ERR_OTHER;
    1987             :         }
    1988      782656 :         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      782656 :         v.data[v.length] = '\0';
    1995             : 
    1996      782656 :         talloc_free(dn->components[num].name);
    1997      782656 :         talloc_free(dn->components[num].value.data);
    1998      782656 :         dn->components[num].name = n;
    1999      782656 :         dn->components[num].value = v;
    2000             : 
    2001      782656 :         if (dn->valid_case) {
    2002             :                 unsigned int i;
    2003     3172009 :                 for (i = 0; i < dn->comp_num; i++) {
    2004     2736349 :                         LDB_FREE(dn->components[i].cf_name);
    2005     2736349 :                         LDB_FREE(dn->components[i].cf_value.data);
    2006             :                 }
    2007      435660 :                 dn->valid_case = false;
    2008             :         }
    2009      782656 :         LDB_FREE(dn->casefold);
    2010      782656 :         LDB_FREE(dn->linearized);
    2011             : 
    2012             :         /* Wipe the ext_linearized DN,
    2013             :          * the GUID and SID are almost certainly no longer valid */
    2014      782656 :         LDB_FREE(dn->ext_linearized);
    2015      782656 :         LDB_FREE(dn->ext_components);
    2016      782656 :         dn->ext_comp_num = 0;
    2017             : 
    2018      782656 :         return LDB_SUCCESS;
    2019             : }
    2020             : 
    2021   165431409 : const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
    2022             :                                                     const char *name)
    2023             : {
    2024             :         unsigned int i;
    2025   165431409 :         if ( ! ldb_dn_validate(dn)) {
    2026           6 :                 return NULL;
    2027             :         }
    2028   196831467 :         for (i=0; i < dn->ext_comp_num; i++) {
    2029    73202121 :                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
    2030    41802057 :                         return &dn->ext_components[i].value;
    2031             :                 }
    2032             :         }
    2033   123629346 :         return NULL;
    2034             : }
    2035             : 
    2036    96453488 : 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    96453488 :         if ( ! ldb_dn_validate(dn)) {
    2045           0 :                 return LDB_ERR_OTHER;
    2046             :         }
    2047             : 
    2048    96453488 :         ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
    2049    96453488 :         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   114130444 :         for (i=0; i < dn->ext_comp_num; i++) {
    2055    17680942 :                 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    96449502 :         if (val == NULL) {
    2088             :                 /* removing a value that doesn't exist is not an error */
    2089           0 :                 return LDB_SUCCESS;
    2090             :         }
    2091             : 
    2092    96449502 :         v2 = *val;
    2093             : 
    2094    96449502 :         p = dn->ext_components
    2095    96449502 :                 = talloc_realloc(dn,
    2096             :                                  dn->ext_components,
    2097             :                                  struct ldb_dn_ext_component,
    2098             :                                  dn->ext_comp_num + 1);
    2099    96449502 :         if (!dn->ext_components) {
    2100           0 :                 ldb_dn_mark_invalid(dn);
    2101           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2102             :         }
    2103             : 
    2104    96449502 :         p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2);
    2105    96449502 :         p[dn->ext_comp_num].name = talloc_strdup(p, name);
    2106             : 
    2107    96449502 :         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    96449502 :         dn->ext_components = p;
    2112    96449502 :         dn->ext_comp_num++;
    2113             : 
    2114    96449502 :         LDB_FREE(dn->ext_linearized);
    2115             : 
    2116    96449502 :         return LDB_SUCCESS;
    2117             : }
    2118             : 
    2119    32910605 : void ldb_dn_remove_extended_components(struct ldb_dn *dn)
    2120             : {
    2121    32910605 :         LDB_FREE(dn->ext_linearized);
    2122    32910605 :         LDB_FREE(dn->ext_components);
    2123    32910605 :         dn->ext_comp_num = 0;
    2124    32910605 : }
    2125             : 
    2126        4472 : bool ldb_dn_is_valid(struct ldb_dn *dn)
    2127             : {
    2128        4472 :         if ( ! dn) return false;
    2129        4472 :         return ! dn->invalid;
    2130             : }
    2131             : 
    2132  1247999221 : bool ldb_dn_is_special(struct ldb_dn *dn)
    2133             : {
    2134  1247999221 :         if ( ! dn || dn->invalid) return false;
    2135  1247999220 :         return dn->special;
    2136             : }
    2137             : 
    2138   304147193 : bool ldb_dn_has_extended(struct ldb_dn *dn)
    2139             : {
    2140   304147193 :         if ( ! dn || dn->invalid) return false;
    2141   304147193 :         if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
    2142   292948338 :         return dn->ext_comp_num != 0;
    2143             : }
    2144             : 
    2145    11153398 : bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
    2146             : {
    2147    11153398 :         if ( ! dn || dn->invalid) return false;
    2148    11153398 :         return ! strcmp(dn->linearized, check);
    2149             : }
    2150             : 
    2151   264677453 : bool ldb_dn_is_null(struct ldb_dn *dn)
    2152             : {
    2153   264677453 :         if ( ! dn || dn->invalid) return false;
    2154   264677453 :         if (ldb_dn_has_extended(dn)) return false;
    2155   229287765 :         if (dn->linearized && (dn->linearized[0] == '\0')) return true;
    2156   210298139 :         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        8669 : int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn)
    2165             : {
    2166        8669 :         dn->components = talloc_realloc(dn, dn->components,
    2167             :                                         struct ldb_dn_component, ref_dn->comp_num);
    2168        8669 :         if (!dn->components) {
    2169           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    2170             :         }
    2171        8669 :         memcpy(dn->components, ref_dn->components,
    2172        8669 :                sizeof(struct ldb_dn_component)*ref_dn->comp_num);
    2173        8669 :         dn->comp_num = ref_dn->comp_num;
    2174             : 
    2175        8669 :         LDB_FREE(dn->casefold);
    2176        8669 :         LDB_FREE(dn->linearized);
    2177        8669 :         LDB_FREE(dn->ext_linearized);
    2178             : 
    2179        8669 :         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     5116794 : bool ldb_dn_minimise(struct ldb_dn *dn)
    2191             : {
    2192             :         unsigned int i;
    2193             : 
    2194     5116794 :         if (!ldb_dn_validate(dn)) {
    2195           0 :                 return false;
    2196             :         }
    2197     5116794 :         if (dn->ext_comp_num == 0) {
    2198           0 :                 return true;
    2199             :         }
    2200             : 
    2201             :         /* free components */
    2202    26791700 :         for (i = 0; i < dn->comp_num; i++) {
    2203    21674906 :                 LDB_FREE(dn->components[i].name);
    2204    21674906 :                 LDB_FREE(dn->components[i].value.data);
    2205    21674906 :                 LDB_FREE(dn->components[i].cf_name);
    2206    21674906 :                 LDB_FREE(dn->components[i].cf_value.data);
    2207             :         }
    2208     5116794 :         dn->comp_num = 0;
    2209     5116794 :         dn->valid_case = false;
    2210             : 
    2211     5116794 :         LDB_FREE(dn->casefold);
    2212     5116794 :         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     7445188 :         for (i = 1; i < dn->ext_comp_num; i++) {
    2220     2328394 :                 LDB_FREE(dn->ext_components[i].value.data);
    2221             :         }
    2222     5116794 :         dn->ext_comp_num = 1;
    2223             : 
    2224     5116794 :         dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1);
    2225     5116794 :         if (dn->ext_components == NULL) {
    2226           0 :                 ldb_dn_mark_invalid(dn);
    2227           0 :                 return false;
    2228             :         }
    2229             : 
    2230     5116794 :         LDB_FREE(dn->ext_linearized);
    2231             : 
    2232     5116794 :         return true;
    2233             : }
    2234             : 
    2235      580926 : struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn)
    2236             : {
    2237      580926 :         return dn->ldb;
    2238             : }

Generated by: LCOV version 1.13