Coverage Report

Created: 2025-11-16 06:57

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