1 /*
2 ldb database library
3
4 Copyright (C) Andrew Tridgell 2004
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: ldif routines
28 *
29 * Description: ldif pack/unpack routines
30 *
31 * Author: Andrew Tridgell
32 */
33
34 /*
35 see RFC2849 for the LDIF format definition
36 */
37
38 #include "ldb_private.h"
39 #include "system/locale.h"
40
41 /*
42
43 */
ldb_read_data_file(TALLOC_CTX * mem_ctx,struct ldb_val * value)44 static int ldb_read_data_file(TALLOC_CTX *mem_ctx, struct ldb_val *value)
45 {
46 struct stat statbuf;
47 char *buf;
48 int count, size, bytes;
49 int ret;
50 int f;
51 const char *fname = (const char *)value->data;
52
53 if (strncmp(fname, "file://", 7) != 0) {
54 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
55 }
56 fname += 7;
57
58 f = open(fname, O_RDONLY);
59 if (f == -1) {
60 return -1;
61 }
62
63 if (fstat(f, &statbuf) != 0) {
64 ret = -1;
65 goto done;
66 }
67
68 if (statbuf.st_size == 0) {
69 ret = -1;
70 goto done;
71 }
72
73 value->data = (uint8_t *)talloc_size(mem_ctx, statbuf.st_size + 1);
74 if (value->data == NULL) {
75 ret = -1;
76 goto done;
77 }
78 value->data[statbuf.st_size] = 0;
79
80 count = 0;
81 size = statbuf.st_size;
82 buf = (char *)value->data;
83 while (count < statbuf.st_size) {
84 bytes = read(f, buf, size);
85 if (bytes == -1) {
86 talloc_free(value->data);
87 ret = -1;
88 goto done;
89 }
90 count += bytes;
91 buf += bytes;
92 size -= bytes;
93 }
94
95 value->length = statbuf.st_size;
96 ret = statbuf.st_size;
97
98 done:
99 close(f);
100 return ret;
101 }
102
103 /*
104 this base64 decoder was taken from jitterbug (written by tridge).
105 we might need to replace it with a new version
106 */
ldb_base64_decode(char * s)107 int ldb_base64_decode(char *s)
108 {
109 const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
110 int bit_offset=0, byte_offset, idx, i, n;
111 uint8_t *d = (uint8_t *)s;
112 char *p=NULL;
113
114 n=i=0;
115
116 while (*s && (p=strchr(b64,*s))) {
117 idx = (int)(p - b64);
118 byte_offset = (i*6)/8;
119 bit_offset = (i*6)%8;
120 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
121 if (bit_offset < 3) {
122 d[byte_offset] |= (idx << (2-bit_offset));
123 n = byte_offset+1;
124 } else {
125 d[byte_offset] |= (idx >> (bit_offset-2));
126 d[byte_offset+1] = 0;
127 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
128 n = byte_offset+2;
129 }
130 s++; i++;
131 }
132 if (bit_offset >= 3) {
133 n--;
134 }
135
136 if (*s && !p) {
137 /* the only termination allowed */
138 if (*s != '=') {
139 return -1;
140 }
141 }
142
143 /* null terminate */
144 d[n] = 0;
145 return n;
146 }
147
148
149 /*
150 encode as base64
151 caller frees
152 */
ldb_base64_encode(TALLOC_CTX * mem_ctx,const char * buf,int len)153 char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len)
154 {
155 const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
156 int bit_offset, byte_offset, idx, i;
157 const uint8_t *d = (const uint8_t *)buf;
158 int bytes = (len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0;
159 char *out;
160
161 out = talloc_array(mem_ctx, char, bytes+pad_bytes+1);
162 if (!out) return NULL;
163
164 for (i=0;i<bytes;i++) {
165 byte_offset = (i*6)/8;
166 bit_offset = (i*6)%8;
167 if (bit_offset < 3) {
168 idx = (d[byte_offset] >> (2-bit_offset)) & 0x3F;
169 } else {
170 idx = (d[byte_offset] << (bit_offset-2)) & 0x3F;
171 if (byte_offset+1 < len) {
172 idx |= (d[byte_offset+1] >> (8-(bit_offset-2)));
173 }
174 }
175 out[i] = b64[idx];
176 }
177
178 for (;i<bytes+pad_bytes;i++)
179 out[i] = '=';
180 out[i] = 0;
181
182 return out;
183 }
184
185 /*
186 see if a buffer should be base64 encoded
187 */
ldb_should_b64_encode(struct ldb_context * ldb,const struct ldb_val * val)188 int ldb_should_b64_encode(struct ldb_context *ldb, const struct ldb_val *val)
189 {
190 unsigned int i;
191 uint8_t *p = val->data;
192
193 if (val->length == 0) {
194 return 0;
195 }
196
197 if (p[0] == ' ' || p[0] == ':') {
198 return 1;
199 }
200
201 for (i=0; i<val->length; i++) {
202 if (!isprint(p[i]) || p[i] == '\n') {
203 return 1;
204 }
205 }
206 return 0;
207 }
208
209 /* this macro is used to handle the return checking on fprintf_fn() */
210 #define CHECK_RET do { if (ret < 0) return ret; total += ret; } while (0)
211
212 /*
213 write a line folded string onto a file
214 */
fold_string(int (* fprintf_fn)(void *,const char *,...),void * private_data,const char * buf,size_t length,int start_pos)215 static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *private_data,
216 const char *buf, size_t length, int start_pos)
217 {
218 size_t i;
219 size_t total = 0;
220 int ret;
221
222 for (i=0;i<length;i++) {
223 ret = fprintf_fn(private_data, "%c", buf[i]);
224 CHECK_RET;
225 if (i != (length-1) && (i + start_pos) % 77 == 0) {
226 ret = fprintf_fn(private_data, "\n ");
227 CHECK_RET;
228 }
229 }
230
231 return total;
232 }
233
234 #undef CHECK_RET
235
236 /*
237 encode as base64 to a file
238 */
base64_encode_f(struct ldb_context * ldb,int (* fprintf_fn)(void *,const char *,...),void * private_data,const char * buf,int len,int start_pos)239 static int base64_encode_f(struct ldb_context *ldb,
240 int (*fprintf_fn)(void *, const char *, ...),
241 void *private_data,
242 const char *buf, int len, int start_pos)
243 {
244 char *b = ldb_base64_encode(ldb, buf, len);
245 int ret;
246
247 if (!b) {
248 return -1;
249 }
250
251 ret = fold_string(fprintf_fn, private_data, b, strlen(b), start_pos);
252
253 talloc_free(b);
254 return ret;
255 }
256
257
258 static const struct {
259 const char *name;
260 enum ldb_changetype changetype;
261 } ldb_changetypes[] = {
262 {"add", LDB_CHANGETYPE_ADD},
263 {"delete", LDB_CHANGETYPE_DELETE},
264 {"modify", LDB_CHANGETYPE_MODIFY},
265 {"modrdn", LDB_CHANGETYPE_MODRDN},
266 {"moddn", LDB_CHANGETYPE_MODRDN},
267 {NULL, 0}
268 };
269
270 /* this macro is used to handle the return checking on fprintf_fn() */
271 #define CHECK_RET do { if (ret < 0) { talloc_free(mem_ctx); return ret; } total += ret; } while (0)
272
273 /*
274 write to ldif, using a caller supplied write method, and only printing secrets if we are not in a trace
275 */
ldb_ldif_write_trace(struct ldb_context * ldb,int (* fprintf_fn)(void *,const char *,...),void * private_data,const struct ldb_ldif * ldif,bool in_trace)276 static int ldb_ldif_write_trace(struct ldb_context *ldb,
277 int (*fprintf_fn)(void *, const char *, ...),
278 void *private_data,
279 const struct ldb_ldif *ldif,
280 bool in_trace)
281 {
282 TALLOC_CTX *mem_ctx;
283 unsigned int i, j;
284 size_t total = 0;
285 int ret;
286 char *p;
287 const struct ldb_message *msg;
288 const char * const * secret_attributes = ldb_get_opaque(ldb, LDB_SECRET_ATTRIBUTE_LIST_OPAQUE);
289
290 mem_ctx = talloc_named_const(NULL, 0, "ldb_ldif_write");
291
292 msg = ldif->msg;
293 p = ldb_dn_get_extended_linearized(mem_ctx, msg->dn, 1);
294 ret = fprintf_fn(private_data, "dn: %s\n", p);
295 talloc_free(p);
296 CHECK_RET;
297
298 if (ldif->changetype != LDB_CHANGETYPE_NONE) {
299 for (i=0;ldb_changetypes[i].name;i++) {
300 if (ldb_changetypes[i].changetype == ldif->changetype) {
301 break;
302 }
303 }
304 if (!ldb_changetypes[i].name) {
305 ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d",
306 ldif->changetype);
307 talloc_free(mem_ctx);
308 return -1;
309 }
310 ret = fprintf_fn(private_data, "changetype: %s\n", ldb_changetypes[i].name);
311 CHECK_RET;
312 }
313
314 for (i=0;i<msg->num_elements;i++) {
315 const struct ldb_schema_attribute *a;
316 size_t namelen;
317
318 if (msg->elements[i].name == NULL) {
319 ldb_debug(ldb, LDB_DEBUG_ERROR,
320 "Error: Invalid element name (NULL) at position %d", i);
321 talloc_free(mem_ctx);
322 return -1;
323 }
324
325 namelen = strlen(msg->elements[i].name);
326 a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name);
327
328 if (ldif->changetype == LDB_CHANGETYPE_MODIFY) {
329 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
330 case LDB_FLAG_MOD_ADD:
331 fprintf_fn(private_data, "add: %s\n",
332 msg->elements[i].name);
333 break;
334 case LDB_FLAG_MOD_DELETE:
335 fprintf_fn(private_data, "delete: %s\n",
336 msg->elements[i].name);
337 break;
338 case LDB_FLAG_MOD_REPLACE:
339 fprintf_fn(private_data, "replace: %s\n",
340 msg->elements[i].name);
341 break;
342 }
343 }
344
345 if (in_trace && secret_attributes && ldb_attr_in_list(secret_attributes, msg->elements[i].name)) {
346 /* Deliberatly skip printing this password */
347 ret = fprintf_fn(private_data, "# %s::: REDACTED SECRET ATTRIBUTE\n",
348 msg->elements[i].name);
349 CHECK_RET;
350 continue;
351 }
352 for (j=0;j<msg->elements[i].num_values;j++) {
353 struct ldb_val v;
354 bool use_b64_encode = false;
355 bool copy_raw_bytes = false;
356
357 ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v);
358 if (ret != LDB_SUCCESS) {
359 v = msg->elements[i].values[j];
360 }
361
362 if (ldb->flags & LDB_FLG_SHOW_BINARY) {
363 use_b64_encode = false;
364 copy_raw_bytes = true;
365 } else if (a->flags & LDB_ATTR_FLAG_FORCE_BASE64_LDIF) {
366 use_b64_encode = true;
367 } else if (msg->elements[i].flags &
368 LDB_FLAG_FORCE_NO_BASE64_LDIF) {
369 use_b64_encode = false;
370 copy_raw_bytes = true;
371 } else {
372 use_b64_encode = ldb_should_b64_encode(ldb, &v);
373 }
374
375 if (ret != LDB_SUCCESS || use_b64_encode) {
376 ret = fprintf_fn(private_data, "%s:: ",
377 msg->elements[i].name);
378 CHECK_RET;
379 ret = base64_encode_f(ldb, fprintf_fn, private_data,
380 (char *)v.data, v.length,
381 namelen + 3);
382 CHECK_RET;
383 ret = fprintf_fn(private_data, "\n");
384 CHECK_RET;
385 } else {
386 ret = fprintf_fn(private_data, "%s: ", msg->elements[i].name);
387 CHECK_RET;
388 if (copy_raw_bytes) {
389 ret = fprintf_fn(private_data, "%*.*s",
390 v.length, v.length, (char *)v.data);
391 } else {
392 ret = fold_string(fprintf_fn, private_data,
393 (char *)v.data, v.length,
394 namelen + 2);
395 }
396 CHECK_RET;
397 ret = fprintf_fn(private_data, "\n");
398 CHECK_RET;
399 }
400 if (v.data != msg->elements[i].values[j].data) {
401 talloc_free(v.data);
402 }
403 }
404 if (ldif->changetype == LDB_CHANGETYPE_MODIFY) {
405 fprintf_fn(private_data, "-\n");
406 }
407 }
408 ret = fprintf_fn(private_data,"\n");
409 CHECK_RET;
410
411 talloc_free(mem_ctx);
412
413 return total;
414 }
415
416 #undef CHECK_RET
417
418
419 /*
420 write to ldif, using a caller supplied write method
421 */
ldb_ldif_write(struct ldb_context * ldb,int (* fprintf_fn)(void *,const char *,...),void * private_data,const struct ldb_ldif * ldif)422 int ldb_ldif_write(struct ldb_context *ldb,
423 int (*fprintf_fn)(void *, const char *, ...),
424 void *private_data,
425 const struct ldb_ldif *ldif)
426 {
427 return ldb_ldif_write_trace(ldb, fprintf_fn, private_data, ldif, false);
428 }
429
430
431 /*
432 pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF
433 this routine removes any RFC2849 continuations and comments
434
435 caller frees
436 */
next_chunk(struct ldb_context * ldb,TALLOC_CTX * mem_ctx,int (* fgetc_fn)(void *),void * private_data)437 static char *next_chunk(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
438 int (*fgetc_fn)(void *), void *private_data)
439 {
440 size_t alloc_size=0, chunk_size = 0;
441 char *chunk = NULL;
442 int c;
443 int in_comment = 0;
444
445 while ((c = fgetc_fn(private_data)) != EOF) {
446 if (chunk_size+1 >= alloc_size) {
447 char *c2;
448 alloc_size += 1024;
449 c2 = talloc_realloc(mem_ctx, chunk, char, alloc_size);
450 if (!c2) {
451 talloc_free(chunk);
452 errno = ENOMEM;
453 return NULL;
454 }
455 chunk = c2;
456 }
457
458 if (in_comment) {
459 if (c == '\n') {
460 in_comment = 0;
461 }
462 continue;
463 }
464
465 /* handle continuation lines - see RFC2849 */
466 if (c == ' ' && chunk_size > 1 && chunk[chunk_size-1] == '\n') {
467 chunk_size--;
468 continue;
469 }
470
471 /* chunks are terminated by a double line-feed */
472 if (c == '\n' && chunk_size > 0 && chunk[chunk_size-1] == '\n') {
473 chunk[chunk_size-1] = 0;
474 return chunk;
475 }
476
477 if (c == '#' && (chunk_size == 0 || chunk[chunk_size-1] == '\n')) {
478 in_comment = 1;
479 continue;
480 }
481
482 /* ignore leading blank lines */
483 if (chunk_size == 0 && c == '\n') {
484 continue;
485 }
486
487 chunk[chunk_size++] = c;
488 }
489
490 if (chunk) {
491 chunk[chunk_size] = 0;
492 }
493
494 return chunk;
495 }
496
497
498 /* simple ldif attribute parser */
next_attr(TALLOC_CTX * mem_ctx,char ** s,const char ** attr,struct ldb_val * value)499 static int next_attr(TALLOC_CTX *mem_ctx, char **s, const char **attr, struct ldb_val *value)
500 {
501 char *p;
502 int base64_encoded = 0;
503 int binary_file = 0;
504
505 if (strncmp(*s, "-\n", 2) == 0) {
506 value->length = 0;
507 *attr = "-";
508 *s += 2;
509 return 0;
510 }
511
512 p = strchr(*s, ':');
513 if (!p) {
514 return -1;
515 }
516
517 *p++ = 0;
518
519 if (*p == ':') {
520 base64_encoded = 1;
521 p++;
522 }
523
524 if (*p == '<') {
525 binary_file = 1;
526 p++;
527 }
528
529 *attr = *s;
530
531 while (*p == ' ' || *p == '\t') {
532 p++;
533 }
534
535 value->data = (uint8_t *)p;
536
537 p = strchr(p, '\n');
538
539 if (!p) {
540 value->length = strlen((char *)value->data);
541 *s = ((char *)value->data) + value->length;
542 } else {
543 value->length = p - (char *)value->data;
544 *s = p+1;
545 *p = 0;
546 }
547
548 if (base64_encoded) {
549 int len = ldb_base64_decode((char *)value->data);
550 if (len == -1) {
551 /* it wasn't valid base64 data */
552 return -1;
553 }
554 value->length = len;
555 }
556
557 if (binary_file) {
558 int len = ldb_read_data_file(mem_ctx, value);
559 if (len == -1) {
560 /* an error occurred while trying to retrieve the file */
561 return -1;
562 }
563 }
564
565 return 0;
566 }
567
568
569 /*
570 free a message from a ldif_read
571 */
ldb_ldif_read_free(struct ldb_context * ldb,struct ldb_ldif * ldif)572 void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif)
573 {
574 talloc_free(ldif);
575 }
576
ldb_ldif_parse_modrdn(struct ldb_context * ldb,const struct ldb_ldif * ldif,TALLOC_CTX * mem_ctx,struct ldb_dn ** _olddn,struct ldb_dn ** _newrdn,bool * _deleteoldrdn,struct ldb_dn ** _newsuperior,struct ldb_dn ** _newdn)577 int ldb_ldif_parse_modrdn(struct ldb_context *ldb,
578 const struct ldb_ldif *ldif,
579 TALLOC_CTX *mem_ctx,
580 struct ldb_dn **_olddn,
581 struct ldb_dn **_newrdn,
582 bool *_deleteoldrdn,
583 struct ldb_dn **_newsuperior,
584 struct ldb_dn **_newdn)
585 {
586 struct ldb_message *msg = ldif->msg;
587 struct ldb_val *newrdn_val = NULL;
588 struct ldb_val *deleteoldrdn_val = NULL;
589 struct ldb_val *newsuperior_val = NULL;
590 struct ldb_dn *olddn = NULL;
591 struct ldb_dn *newrdn = NULL;
592 bool deleteoldrdn = true;
593 struct ldb_dn *newsuperior = NULL;
594 struct ldb_dn *newdn = NULL;
595 struct ldb_val tmp_false;
596 struct ldb_val tmp_true;
597 bool ok;
598 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
599
600 if (tmp_ctx == NULL) {
601 ldb_debug(ldb, LDB_DEBUG_FATAL,
602 "Error: talloc_new() failed");
603 goto err_op;
604 }
605
606 if (ldif->changetype != LDB_CHANGETYPE_MODRDN) {
607 ldb_debug(ldb, LDB_DEBUG_ERROR,
608 "Error: invalid changetype '%d'",
609 ldif->changetype);
610 goto err_other;
611 }
612
613 if (msg->num_elements < 2) {
614 ldb_debug(ldb, LDB_DEBUG_ERROR,
615 "Error: num_elements[%u] < 2",
616 msg->num_elements);
617 goto err_other;
618 }
619
620 if (msg->num_elements > 3) {
621 ldb_debug(ldb, LDB_DEBUG_ERROR,
622 "Error: num_elements[%u] > 3",
623 msg->num_elements);
624 goto err_other;
625 }
626
627 #define CHECK_ELEMENT(i, _name, v, needed) do { \
628 v = NULL; \
629 if (msg->num_elements < (i + 1)) { \
630 if (needed) { \
631 ldb_debug(ldb, LDB_DEBUG_ERROR, \
632 "Error: num_elements[%u] < (%u + 1)", \
633 msg->num_elements, i); \
634 goto err_other; \
635 } \
636 } else if (ldb_attr_cmp(msg->elements[i].name, _name) != 0) { \
637 ldb_debug(ldb, LDB_DEBUG_ERROR, \
638 "Error: elements[%u].name[%s] != [%s]", \
639 i, msg->elements[i].name, _name); \
640 goto err_other; \
641 } else if (msg->elements[i].flags != 0) { \
642 ldb_debug(ldb, LDB_DEBUG_ERROR, \
643 "Error: elements[%u].flags[0x%X} != [0x0]", \
644 i, msg->elements[i].flags); \
645 goto err_other; \
646 } else if (msg->elements[i].num_values != 1) { \
647 ldb_debug(ldb, LDB_DEBUG_ERROR, \
648 "Error: elements[%u].num_values[%u] != 1", \
649 i, msg->elements[i].num_values); \
650 goto err_other; \
651 } else { \
652 v = &msg->elements[i].values[0]; \
653 } \
654 } while (0)
655
656 CHECK_ELEMENT(0, "newrdn", newrdn_val, true);
657 CHECK_ELEMENT(1, "deleteoldrdn", deleteoldrdn_val, true);
658 CHECK_ELEMENT(2, "newsuperior", newsuperior_val, false);
659
660 #undef CHECK_ELEMENT
661
662 olddn = ldb_dn_copy(tmp_ctx, msg->dn);
663 if (olddn == NULL) {
664 ldb_debug(ldb, LDB_DEBUG_ERROR,
665 "Error: failed to copy olddn '%s'",
666 ldb_dn_get_linearized(msg->dn));
667 goto err_op;
668 }
669
670 newrdn = ldb_dn_from_ldb_val(tmp_ctx, ldb, newrdn_val);
671 if (!ldb_dn_validate(newrdn)) {
672 ldb_debug(ldb, LDB_DEBUG_ERROR,
673 "Error: Unable to parse dn '%s'",
674 (char *)newrdn_val->data);
675 goto err_dn;
676 }
677
678 tmp_false.length = 1;
679 tmp_false.data = discard_const_p(uint8_t, "0");
680 tmp_true.length = 1;
681 tmp_true.data = discard_const_p(uint8_t, "1");
682 if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_false) == 1) {
683 deleteoldrdn = false;
684 } else if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_true) == 1) {
685 deleteoldrdn = true;
686 } else {
687 ldb_debug(ldb, LDB_DEBUG_ERROR,
688 "Error: deleteoldrdn value invalid '%s' not '0'/'1'",
689 (char *)deleteoldrdn_val->data);
690 goto err_attr;
691 }
692
693 if (newsuperior_val) {
694 newsuperior = ldb_dn_from_ldb_val(tmp_ctx, ldb, newsuperior_val);
695 if (!ldb_dn_validate(newsuperior)) {
696 ldb_debug(ldb, LDB_DEBUG_ERROR,
697 "Error: Unable to parse dn '%s'",
698 (char *)newsuperior_val->data);
699 goto err_dn;
700 }
701 } else {
702 newsuperior = ldb_dn_get_parent(tmp_ctx, msg->dn);
703 if (newsuperior == NULL) {
704 ldb_debug(ldb, LDB_DEBUG_ERROR,
705 "Error: Unable to get parent dn '%s'",
706 ldb_dn_get_linearized(msg->dn));
707 goto err_dn;
708 }
709 }
710
711 newdn = ldb_dn_copy(tmp_ctx, newrdn);
712 if (newdn == NULL) {
713 ldb_debug(ldb, LDB_DEBUG_ERROR,
714 "Error: failed to copy newrdn '%s'",
715 ldb_dn_get_linearized(newrdn));
716 goto err_op;
717 }
718
719 ok = ldb_dn_add_base(newdn, newsuperior);
720 if (!ok) {
721 ldb_debug(ldb, LDB_DEBUG_ERROR,
722 "Error: failed to base '%s' to newdn '%s'",
723 ldb_dn_get_linearized(newsuperior),
724 ldb_dn_get_linearized(newdn));
725 goto err_op;
726 }
727
728 if (_olddn) {
729 *_olddn = talloc_move(mem_ctx, &olddn);
730 }
731 if (_newrdn) {
732 *_newrdn = talloc_move(mem_ctx, &newrdn);
733 }
734 if (_deleteoldrdn) {
735 *_deleteoldrdn = deleteoldrdn;
736 }
737 if (_newsuperior != NULL && _newrdn != NULL) {
738 if (newsuperior_val) {
739 *_newrdn = talloc_move(mem_ctx, &newrdn);
740 } else {
741 *_newrdn = NULL;
742 }
743 }
744 if (_newdn) {
745 *_newdn = talloc_move(mem_ctx, &newdn);
746 }
747
748 talloc_free(tmp_ctx);
749 return LDB_SUCCESS;
750 err_other:
751 talloc_free(tmp_ctx);
752 return LDB_ERR_OTHER;
753 err_op:
754 talloc_free(tmp_ctx);
755 return LDB_ERR_OPERATIONS_ERROR;
756 err_attr:
757 talloc_free(tmp_ctx);
758 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
759 err_dn:
760 talloc_free(tmp_ctx);
761 return LDB_ERR_INVALID_DN_SYNTAX;
762 }
763
764 /*
765 read from a LDIF source, creating a ldb_message
766 */
ldb_ldif_read(struct ldb_context * ldb,int (* fgetc_fn)(void *),void * private_data)767 struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
768 int (*fgetc_fn)(void *), void *private_data)
769 {
770 struct ldb_ldif *ldif;
771 struct ldb_message *msg;
772 const char *attr=NULL;
773 char *chunk=NULL, *s;
774 struct ldb_val value;
775 unsigned flags = 0;
776 value.data = NULL;
777
778 ldif = talloc(ldb, struct ldb_ldif);
779 if (!ldif) return NULL;
780
781 ldif->msg = ldb_msg_new(ldif);
782 if (ldif->msg == NULL) {
783 talloc_free(ldif);
784 return NULL;
785 }
786
787 ldif->changetype = LDB_CHANGETYPE_NONE;
788 msg = ldif->msg;
789
790 chunk = next_chunk(ldb, ldif, fgetc_fn, private_data);
791 if (!chunk) {
792 goto failed;
793 }
794
795 s = chunk;
796
797 if (next_attr(ldif, &s, &attr, &value) != 0) {
798 goto failed;
799 }
800
801 /* first line must be a dn */
802 if (ldb_attr_cmp(attr, "dn") != 0) {
803 ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'",
804 attr);
805 goto failed;
806 }
807
808 msg->dn = ldb_dn_from_ldb_val(msg, ldb, &value);
809
810 if ( ! ldb_dn_validate(msg->dn)) {
811 ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'",
812 (char *)value.data);
813 goto failed;
814 }
815
816 while (next_attr(ldif, &s, &attr, &value) == 0) {
817 const struct ldb_schema_attribute *a;
818 struct ldb_message_element *el;
819 int ret, empty = 0;
820
821 if (ldb_attr_cmp(attr, "changetype") == 0) {
822 int i;
823 for (i=0;ldb_changetypes[i].name;i++) {
824 if (ldb_attr_cmp((char *)value.data, ldb_changetypes[i].name) == 0) {
825 ldif->changetype = ldb_changetypes[i].changetype;
826 break;
827 }
828 }
829 if (!ldb_changetypes[i].name) {
830 ldb_debug(ldb, LDB_DEBUG_ERROR,
831 "Error: Bad ldif changetype '%s'",(char *)value.data);
832 }
833 flags = 0;
834 continue;
835 }
836
837 if (ldb_attr_cmp(attr, "add") == 0) {
838 flags = LDB_FLAG_MOD_ADD;
839 empty = 1;
840 }
841 if (ldb_attr_cmp(attr, "delete") == 0) {
842 flags = LDB_FLAG_MOD_DELETE;
843 empty = 1;
844 }
845 if (ldb_attr_cmp(attr, "replace") == 0) {
846 flags = LDB_FLAG_MOD_REPLACE;
847 empty = 1;
848 }
849 if (ldb_attr_cmp(attr, "-") == 0) {
850 flags = 0;
851 continue;
852 }
853
854 if (empty) {
855 if (ldb_msg_add_empty(msg, (char *)value.data, flags, NULL) != 0) {
856 goto failed;
857 }
858 continue;
859 }
860
861 el = &msg->elements[msg->num_elements-1];
862
863 a = ldb_schema_attribute_by_name(ldb, attr);
864
865 if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 &&
866 flags == el->flags) {
867 /* its a continuation */
868 el->values =
869 talloc_realloc(msg->elements, el->values,
870 struct ldb_val, el->num_values+1);
871 if (!el->values) {
872 goto failed;
873 }
874 ret = a->syntax->ldif_read_fn(ldb, el->values, &value, &el->values[el->num_values]);
875 if (ret != 0) {
876 goto failed;
877 }
878 if (value.length == 0) {
879 ldb_debug(ldb, LDB_DEBUG_ERROR,
880 "Error: Attribute value cannot be empty for attribute '%s'", el->name);
881 goto failed;
882 }
883 if (value.data != el->values[el->num_values].data) {
884 talloc_steal(el->values, el->values[el->num_values].data);
885 }
886 el->num_values++;
887 } else {
888 /* its a new attribute */
889 msg->elements = talloc_realloc(msg, msg->elements,
890 struct ldb_message_element,
891 msg->num_elements+1);
892 if (!msg->elements) {
893 goto failed;
894 }
895 el = &msg->elements[msg->num_elements];
896 el->flags = flags;
897 el->name = talloc_strdup(msg->elements, attr);
898 el->values = talloc(msg->elements, struct ldb_val);
899 if (!el->values || !el->name) {
900 goto failed;
901 }
902 el->num_values = 1;
903 ret = a->syntax->ldif_read_fn(ldb, el->values, &value, &el->values[0]);
904 if (ret != 0) {
905 goto failed;
906 }
907 if (value.data != el->values[0].data) {
908 talloc_steal(el->values, el->values[0].data);
909 }
910 msg->num_elements++;
911 }
912 }
913
914 if (ldif->changetype == LDB_CHANGETYPE_MODRDN) {
915 int ret;
916
917 ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif,
918 NULL, NULL, NULL, NULL, NULL);
919 if (ret != LDB_SUCCESS) {
920 goto failed;
921 }
922 }
923
924 return ldif;
925
926 failed:
927 talloc_free(ldif);
928 return NULL;
929 }
930
931
932
933 /*
934 a wrapper around ldif_read() for reading from FILE*
935 */
936
fgetc_file(void * private_data)937 static int fgetc_file(void *private_data)
938 {
939 int c;
940 struct ldif_read_file_state *state =
941 (struct ldif_read_file_state *)private_data;
942 c = fgetc(state->f);
943 if (c == '\n') {
944 state->line_no++;
945 }
946 return c;
947 }
948
ldb_ldif_read_file_state(struct ldb_context * ldb,struct ldif_read_file_state * state)949 struct ldb_ldif *ldb_ldif_read_file_state(struct ldb_context *ldb,
950 struct ldif_read_file_state *state)
951 {
952 return ldb_ldif_read(ldb, fgetc_file, state);
953 }
954
ldb_ldif_read_file(struct ldb_context * ldb,FILE * f)955 struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f)
956 {
957 struct ldif_read_file_state state;
958 state.f = f;
959 return ldb_ldif_read_file_state(ldb, &state);
960 }
961
962 /*
963 a wrapper around ldif_read() for reading from const char*
964 */
965 struct ldif_read_string_state {
966 const char *s;
967 };
968
fgetc_string(void * private_data)969 static int fgetc_string(void *private_data)
970 {
971 struct ldif_read_string_state *state =
972 (struct ldif_read_string_state *)private_data;
973 if (state->s[0] != 0) {
974 return *state->s++;
975 }
976 return EOF;
977 }
978
ldb_ldif_read_string(struct ldb_context * ldb,const char ** s)979 struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s)
980 {
981 struct ldif_read_string_state state;
982 struct ldb_ldif *ldif;
983 state.s = *s;
984 ldif = ldb_ldif_read(ldb, fgetc_string, &state);
985 *s = state.s;
986 return ldif;
987 }
988
989
990 /*
991 wrapper around ldif_write() for a file
992 */
993 struct ldif_write_file_state {
994 FILE *f;
995 };
996
997 static int fprintf_file(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
998
fprintf_file(void * private_data,const char * fmt,...)999 static int fprintf_file(void *private_data, const char *fmt, ...)
1000 {
1001 struct ldif_write_file_state *state =
1002 (struct ldif_write_file_state *)private_data;
1003 int ret;
1004 va_list ap;
1005
1006 va_start(ap, fmt);
1007 ret = vfprintf(state->f, fmt, ap);
1008 va_end(ap);
1009 return ret;
1010 }
1011
ldb_ldif_write_file(struct ldb_context * ldb,FILE * f,const struct ldb_ldif * ldif)1012 int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *ldif)
1013 {
1014 struct ldif_write_file_state state;
1015 state.f = f;
1016 return ldb_ldif_write(ldb, fprintf_file, &state, ldif);
1017 }
1018
1019 /*
1020 wrapper around ldif_write() for a string
1021 */
1022 struct ldif_write_string_state {
1023 char *string;
1024 };
1025
1026 static int ldif_printf_string(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
1027
ldif_printf_string(void * private_data,const char * fmt,...)1028 static int ldif_printf_string(void *private_data, const char *fmt, ...)
1029 {
1030 struct ldif_write_string_state *state =
1031 (struct ldif_write_string_state *)private_data;
1032 va_list ap;
1033 size_t oldlen = talloc_get_size(state->string);
1034 va_start(ap, fmt);
1035
1036 state->string = talloc_vasprintf_append(state->string, fmt, ap);
1037 va_end(ap);
1038 if (!state->string) {
1039 return -1;
1040 }
1041
1042 return talloc_get_size(state->string) - oldlen;
1043 }
1044
ldb_ldif_write_redacted_trace_string(struct ldb_context * ldb,TALLOC_CTX * mem_ctx,const struct ldb_ldif * ldif)1045 char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
1046 const struct ldb_ldif *ldif)
1047 {
1048 struct ldif_write_string_state state;
1049 state.string = talloc_strdup(mem_ctx, "");
1050 if (!state.string) {
1051 return NULL;
1052 }
1053 if (ldb_ldif_write_trace(ldb, ldif_printf_string, &state, ldif, true) == -1) {
1054 return NULL;
1055 }
1056 return state.string;
1057 }
1058
ldb_ldif_write_string(struct ldb_context * ldb,TALLOC_CTX * mem_ctx,const struct ldb_ldif * ldif)1059 char *ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
1060 const struct ldb_ldif *ldif)
1061 {
1062 struct ldif_write_string_state state;
1063 state.string = talloc_strdup(mem_ctx, "");
1064 if (!state.string) {
1065 return NULL;
1066 }
1067 if (ldb_ldif_write(ldb, ldif_printf_string, &state, ldif) == -1) {
1068 return NULL;
1069 }
1070 return state.string;
1071 }
1072
1073 /*
1074 convenient function to turn a ldb_message into a string. Useful for
1075 debugging
1076 */
ldb_ldif_message_string(struct ldb_context * ldb,TALLOC_CTX * mem_ctx,enum ldb_changetype changetype,const struct ldb_message * msg)1077 char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
1078 enum ldb_changetype changetype,
1079 const struct ldb_message *msg)
1080 {
1081 struct ldb_ldif ldif;
1082
1083 ldif.changetype = changetype;
1084 ldif.msg = discard_const_p(struct ldb_message, msg);
1085
1086 return ldb_ldif_write_string(ldb, mem_ctx, &ldif);
1087 }
1088
1089 /*
1090 * convenient function to turn a ldb_message into a string. Useful for
1091 * debugging but also safer if some of the LDIF could be sensitive.
1092 *
1093 * The secret attributes are specified in a 'const char * const *' within
1094 * the LDB_SECRET_ATTRIBUTE_LIST opaque set on the ldb
1095 *
1096 */
ldb_ldif_message_redacted_string(struct ldb_context * ldb,TALLOC_CTX * mem_ctx,enum ldb_changetype changetype,const struct ldb_message * msg)1097 char *ldb_ldif_message_redacted_string(struct ldb_context *ldb,
1098 TALLOC_CTX *mem_ctx,
1099 enum ldb_changetype changetype,
1100 const struct ldb_message *msg)
1101 {
1102 struct ldb_ldif ldif;
1103
1104 ldif.changetype = changetype;
1105 ldif.msg = discard_const_p(struct ldb_message, msg);
1106
1107 return ldb_ldif_write_redacted_trace_string(ldb, mem_ctx, &ldif);
1108 }
1109