Coverage Report

Created: 2026-01-16 06:47

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