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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 572 void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif) 573 { 574 talloc_free(ldif); 575 } 576 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 */ 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 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 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 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 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 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 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 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 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 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 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 */ 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 */ 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