1/* 2 ldb database library 3 4 Copyright (C) Andrew Tridgell 2004 5 Copyright (C) Stefan Metzmacher 2004 6 Copyright (C) Simo Sorce 2006 7 8 9 ** NOTE! The following LGPL license applies to the ldb 10 ** library. This does NOT imply that all of Samba is released 11 ** under the LGPL 12 13 This library is free software; you can redistribute it and/or 14 modify it under the terms of the GNU Lesser General Public 15 License as published by the Free Software Foundation; either 16 version 3 of the License, or (at your option) any later version. 17 18 This library is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 Lesser General Public License for more details. 22 23 You should have received a copy of the GNU Lesser General Public 24 License along with this library; if not, see <http://www.gnu.org/licenses/>. 25*/ 26 27/* 28 * Name: ldb_tdb 29 * 30 * Component: ldb tdb backend 31 * 32 * Description: core functions for tdb backend 33 * 34 * Author: Andrew Tridgell 35 * Author: Stefan Metzmacher 36 * 37 * Modifications: 38 * 39 * - description: make the module use asyncronous calls 40 * date: Feb 2006 41 * Author: Simo Sorce 42 */ 43 44#include "includes.h" 45#include "ldb/include/includes.h" 46 47#include "ldb/ldb_tdb/ldb_tdb.h" 48 49int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg); 50 51/* 52 map a tdb error code to a ldb error code 53*/ 54static int ltdb_err_map(enum TDB_ERROR tdb_code) 55{ 56 switch (tdb_code) { 57 case TDB_SUCCESS: 58 return LDB_SUCCESS; 59 case TDB_ERR_CORRUPT: 60 case TDB_ERR_OOM: 61 case TDB_ERR_EINVAL: 62 return LDB_ERR_OPERATIONS_ERROR; 63 case TDB_ERR_IO: 64 return LDB_ERR_PROTOCOL_ERROR; 65 case TDB_ERR_LOCK: 66 case TDB_ERR_NOLOCK: 67 return LDB_ERR_BUSY; 68 case TDB_ERR_LOCK_TIMEOUT: 69 return LDB_ERR_TIME_LIMIT_EXCEEDED; 70 case TDB_ERR_EXISTS: 71 return LDB_ERR_ENTRY_ALREADY_EXISTS; 72 case TDB_ERR_NOEXIST: 73 return LDB_ERR_NO_SUCH_OBJECT; 74 case TDB_ERR_RDONLY: 75 return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; 76 } 77 return LDB_ERR_OTHER; 78} 79 80 81struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module, 82 struct ldb_request *req) 83{ 84 struct ltdb_context *ac; 85 struct ldb_handle *h; 86 87 h = talloc_zero(req, struct ldb_handle); 88 if (h == NULL) { 89 ldb_set_errstring(module->ldb, "Out of Memory"); 90 return NULL; 91 } 92 93 h->module = module; 94 95 ac = talloc_zero(h, struct ltdb_context); 96 if (ac == NULL) { 97 ldb_set_errstring(module->ldb, "Out of Memory"); 98 talloc_free(h); 99 return NULL; 100 } 101 102 h->private_data = (void *)ac; 103 104 h->state = LDB_ASYNC_INIT; 105 h->status = LDB_SUCCESS; 106 107 ac->module = module; 108 ac->context = req->context; 109 ac->callback = req->callback; 110 111 return h; 112} 113 114/* 115 form a TDB_DATA for a record key 116 caller frees 117 118 note that the key for a record can depend on whether the 119 dn refers to a case sensitive index record or not 120*/ 121struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn) 122{ 123 struct ldb_context *ldb = module->ldb; 124 TDB_DATA key; 125 char *key_str = NULL; 126 char *dn_folded = NULL; 127 128 /* 129 most DNs are case insensitive. The exception is index DNs for 130 case sensitive attributes 131 132 there are 3 cases dealt with in this code: 133 134 1) if the dn doesn't start with @ then uppercase the attribute 135 names and the attributes values of case insensitive attributes 136 2) if the dn starts with @ then leave it alone - the indexing code handles 137 the rest 138 */ 139 140 dn_folded = ldb_dn_linearize_casefold(ldb, ldb, dn); 141 if (!dn_folded) { 142 goto failed; 143 } 144 145 key_str = talloc_asprintf(ldb, "DN=%s", dn_folded); 146 147 talloc_free(dn_folded); 148 149 if (!key_str) { 150 goto failed; 151 } 152 153 key.dptr = (uint8_t *)key_str; 154 key.dsize = strlen(key_str) + 1; 155 156 return key; 157 158failed: 159 errno = ENOMEM; 160 key.dptr = NULL; 161 key.dsize = 0; 162 return key; 163} 164 165/* 166 check special dn's have valid attributes 167 currently only @ATTRIBUTES is checked 168*/ 169int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg) 170{ 171 int i, j; 172 173 if (! ldb_dn_is_special(msg->dn) || 174 ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) { 175 return 0; 176 } 177 178 /* we have @ATTRIBUTES, let's check attributes are fine */ 179 /* should we check that we deny multivalued attributes ? */ 180 for (i = 0; i < msg->num_elements; i++) { 181 for (j = 0; j < msg->elements[i].num_values; j++) { 182 if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) { 183 ldb_set_errstring(module->ldb, "Invalid attribute value in an @ATTRIBUTES entry"); 184 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 185 } 186 } 187 } 188 189 return 0; 190} 191 192 193/* 194 we've made a modification to a dn - possibly reindex and 195 update sequence number 196*/ 197static int ltdb_modified(struct ldb_module *module, const struct ldb_dn *dn) 198{ 199 int ret = 0; 200 201 if (ldb_dn_is_special(dn) && 202 (ldb_dn_check_special(dn, LTDB_INDEXLIST) || 203 ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) { 204 ret = ltdb_reindex(module); 205 } 206 207 if (ret == 0 && 208 !(ldb_dn_is_special(dn) && 209 ldb_dn_check_special(dn, LTDB_BASEINFO)) ) { 210 ret = ltdb_increase_sequence_number(module); 211 } 212 213 return ret; 214} 215 216/* 217 store a record into the db 218*/ 219int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs) 220{ 221 struct ltdb_private *ltdb = 222 talloc_get_type(module->private_data, struct ltdb_private); 223 TDB_DATA tdb_key, tdb_data; 224 int ret; 225 226 tdb_key = ltdb_key(module, msg->dn); 227 if (!tdb_key.dptr) { 228 return LDB_ERR_OTHER; 229 } 230 231 ret = ltdb_pack_data(module, msg, &tdb_data); 232 if (ret == -1) { 233 talloc_free(tdb_key.dptr); 234 return LDB_ERR_OTHER; 235 } 236 237 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs); 238 if (ret == -1) { 239 ret = ltdb_err_map(tdb_error(ltdb->tdb)); 240 goto done; 241 } 242 243 ret = ltdb_index_add(module, msg); 244 if (ret == -1) { 245 tdb_delete(ltdb->tdb, tdb_key); 246 } 247 248done: 249 talloc_free(tdb_key.dptr); 250 talloc_free(tdb_data.dptr); 251 252 return ret; 253} 254 255 256static int ltdb_add_internal(struct ldb_module *module, const struct ldb_message *msg) 257{ 258 int ret; 259 260 ret = ltdb_check_special_dn(module, msg); 261 if (ret != LDB_SUCCESS) { 262 return ret; 263 } 264 265 if (ltdb_cache_load(module) != 0) { 266 return LDB_ERR_OPERATIONS_ERROR; 267 } 268 269 ret = ltdb_store(module, msg, TDB_INSERT); 270 271 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { 272 char *dn; 273 274 dn = ldb_dn_linearize(module, msg->dn); 275 if (!dn) { 276 return ret; 277 } 278 ldb_asprintf_errstring(module->ldb, "Entry %s already exists", dn); 279 talloc_free(dn); 280 return ret; 281 } 282 283 if (ret == LDB_SUCCESS) { 284 ret = ltdb_modified(module, msg->dn); 285 if (ret != LDB_SUCCESS) { 286 return LDB_ERR_OPERATIONS_ERROR; 287 } 288 } 289 290 return ret; 291} 292 293/* 294 add a record to the database 295*/ 296static int ltdb_add(struct ldb_module *module, struct ldb_request *req) 297{ 298 struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); 299 struct ltdb_context *ltdb_ac; 300 int tret, ret = LDB_SUCCESS; 301 302 if (req->controls != NULL) { 303 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); 304 if (check_critical_controls(req->controls)) { 305 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; 306 } 307 } 308 309 req->handle = init_ltdb_handle(ltdb, module, req); 310 if (req->handle == NULL) { 311 return LDB_ERR_OPERATIONS_ERROR; 312 } 313 ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); 314 315 tret = ltdb_add_internal(module, req->op.add.message); 316 if (tret != LDB_SUCCESS) { 317 req->handle->status = tret; 318 goto done; 319 } 320 321 if (ltdb_ac->callback) { 322 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); 323 } 324done: 325 req->handle->state = LDB_ASYNC_DONE; 326 return ret; 327} 328 329/* 330 delete a record from the database, not updating indexes (used for deleting 331 index records) 332*/ 333int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn) 334{ 335 struct ltdb_private *ltdb = 336 talloc_get_type(module->private_data, struct ltdb_private); 337 TDB_DATA tdb_key; 338 int ret; 339 340 tdb_key = ltdb_key(module, dn); 341 if (!tdb_key.dptr) { 342 return LDB_ERR_OTHER; 343 } 344 345 ret = tdb_delete(ltdb->tdb, tdb_key); 346 talloc_free(tdb_key.dptr); 347 348 if (ret != 0) { 349 ret = ltdb_err_map(tdb_error(ltdb->tdb)); 350 } 351 352 return ret; 353} 354 355static int ltdb_delete_internal(struct ldb_module *module, const struct ldb_dn *dn) 356{ 357 struct ldb_message *msg; 358 int ret; 359 360 msg = talloc(module, struct ldb_message); 361 if (msg == NULL) { 362 return LDB_ERR_OPERATIONS_ERROR; 363 } 364 365 /* in case any attribute of the message was indexed, we need 366 to fetch the old record */ 367 ret = ltdb_search_dn1(module, dn, msg); 368 if (ret != 1) { 369 /* not finding the old record is an error */ 370 talloc_free(msg); 371 return LDB_ERR_NO_SUCH_OBJECT; 372 } 373 374 ret = ltdb_delete_noindex(module, dn); 375 if (ret != LDB_SUCCESS) { 376 talloc_free(msg); 377 return LDB_ERR_NO_SUCH_OBJECT; 378 } 379 380 /* remove any indexed attributes */ 381 ret = ltdb_index_del(module, msg); 382 if (ret != LDB_SUCCESS) { 383 talloc_free(msg); 384 return LDB_ERR_OPERATIONS_ERROR; 385 } 386 387 ret = ltdb_modified(module, dn); 388 if (ret != LDB_SUCCESS) { 389 talloc_free(msg); 390 return LDB_ERR_OPERATIONS_ERROR; 391 } 392 393 talloc_free(msg); 394 return LDB_SUCCESS; 395} 396 397/* 398 delete a record from the database 399*/ 400static int ltdb_delete(struct ldb_module *module, struct ldb_request *req) 401{ 402 struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); 403 struct ltdb_context *ltdb_ac; 404 int tret, ret = LDB_SUCCESS; 405 406 if (req->controls != NULL) { 407 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); 408 if (check_critical_controls(req->controls)) { 409 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; 410 } 411 } 412 413 req->handle = NULL; 414 415 if (ltdb_cache_load(module) != 0) { 416 return LDB_ERR_OPERATIONS_ERROR; 417 } 418 419 req->handle = init_ltdb_handle(ltdb, module, req); 420 if (req->handle == NULL) { 421 return LDB_ERR_OPERATIONS_ERROR; 422 } 423 ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); 424 425 tret = ltdb_delete_internal(module, req->op.del.dn); 426 if (tret != LDB_SUCCESS) { 427 req->handle->status = tret; 428 goto done; 429 } 430 431 if (ltdb_ac->callback) { 432 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); 433 } 434done: 435 req->handle->state = LDB_ASYNC_DONE; 436 return ret; 437} 438 439/* 440 find an element by attribute name. At the moment this does a linear search, it should 441 be re-coded to use a binary search once all places that modify records guarantee 442 sorted order 443 444 return the index of the first matching element if found, otherwise -1 445*/ 446static int find_element(const struct ldb_message *msg, const char *name) 447{ 448 unsigned int i; 449 for (i=0;i<msg->num_elements;i++) { 450 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { 451 return i; 452 } 453 } 454 return -1; 455} 456 457 458/* 459 add an element to an existing record. Assumes a elements array that we 460 can call re-alloc on, and assumed that we can re-use the data pointers from the 461 passed in additional values. Use with care! 462 463 returns 0 on success, -1 on failure (and sets errno) 464*/ 465static int msg_add_element(struct ldb_context *ldb, 466 struct ldb_message *msg, struct ldb_message_element *el) 467{ 468 struct ldb_message_element *e2; 469 unsigned int i; 470 471 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, 472 msg->num_elements+1); 473 if (!e2) { 474 errno = ENOMEM; 475 return -1; 476 } 477 478 msg->elements = e2; 479 480 e2 = &msg->elements[msg->num_elements]; 481 482 e2->name = el->name; 483 e2->flags = el->flags; 484 e2->values = NULL; 485 if (el->num_values != 0) { 486 e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values); 487 if (!e2->values) { 488 errno = ENOMEM; 489 return -1; 490 } 491 } 492 for (i=0;i<el->num_values;i++) { 493 e2->values[i] = el->values[i]; 494 } 495 e2->num_values = el->num_values; 496 497 msg->num_elements++; 498 499 return 0; 500} 501 502/* 503 delete all elements having a specified attribute name 504*/ 505static int msg_delete_attribute(struct ldb_module *module, 506 struct ldb_context *ldb, 507 struct ldb_message *msg, const char *name) 508{ 509 char *dn; 510 unsigned int i, j; 511 512 dn = ldb_dn_linearize(ldb, msg->dn); 513 if (dn == NULL) { 514 return -1; 515 } 516 517 for (i=0;i<msg->num_elements;i++) { 518 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { 519 for (j=0;j<msg->elements[i].num_values;j++) { 520 ltdb_index_del_value(module, dn, &msg->elements[i], j); 521 } 522 talloc_free(msg->elements[i].values); 523 if (msg->num_elements > (i+1)) { 524 memmove(&msg->elements[i], 525 &msg->elements[i+1], 526 sizeof(struct ldb_message_element)* 527 (msg->num_elements - (i+1))); 528 } 529 msg->num_elements--; 530 i--; 531 msg->elements = talloc_realloc(msg, msg->elements, 532 struct ldb_message_element, 533 msg->num_elements); 534 } 535 } 536 537 talloc_free(dn); 538 return 0; 539} 540 541/* 542 delete all elements matching an attribute name/value 543 544 return 0 on success, -1 on failure 545*/ 546static int msg_delete_element(struct ldb_module *module, 547 struct ldb_message *msg, 548 const char *name, 549 const struct ldb_val *val) 550{ 551 struct ldb_context *ldb = module->ldb; 552 unsigned int i; 553 int found; 554 struct ldb_message_element *el; 555 const struct ldb_attrib_handler *h; 556 557 found = find_element(msg, name); 558 if (found == -1) { 559 return -1; 560 } 561 562 el = &msg->elements[found]; 563 564 h = ldb_attrib_handler(ldb, el->name); 565 566 for (i=0;i<el->num_values;i++) { 567 if (h->comparison_fn(ldb, ldb, &el->values[i], val) == 0) { 568 if (i<el->num_values-1) { 569 memmove(&el->values[i], &el->values[i+1], 570 sizeof(el->values[i])*(el->num_values-(i+1))); 571 } 572 el->num_values--; 573 if (el->num_values == 0) { 574 return msg_delete_attribute(module, ldb, msg, name); 575 } 576 return 0; 577 } 578 } 579 580 return -1; 581} 582 583 584/* 585 modify a record - internal interface 586 587 yuck - this is O(n^2). Luckily n is usually small so we probably 588 get away with it, but if we ever have really large attribute lists 589 then we'll need to look at this again 590*/ 591int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg) 592{ 593 struct ldb_context *ldb = module->ldb; 594 struct ltdb_private *ltdb = 595 talloc_get_type(module->private_data, struct ltdb_private); 596 TDB_DATA tdb_key, tdb_data; 597 struct ldb_message *msg2; 598 unsigned i, j; 599 int ret; 600 601 tdb_key = ltdb_key(module, msg->dn); 602 if (!tdb_key.dptr) { 603 return LDB_ERR_OTHER; 604 } 605 606 tdb_data = tdb_fetch(ltdb->tdb, tdb_key); 607 if (!tdb_data.dptr) { 608 talloc_free(tdb_key.dptr); 609 return ltdb_err_map(tdb_error(ltdb->tdb)); 610 } 611 612 msg2 = talloc(tdb_key.dptr, struct ldb_message); 613 if (msg2 == NULL) { 614 talloc_free(tdb_key.dptr); 615 return LDB_ERR_OTHER; 616 } 617 618 ret = ltdb_unpack_data(module, &tdb_data, msg2); 619 if (ret == -1) { 620 ret = LDB_ERR_OTHER; 621 goto failed; 622 } 623 624 if (!msg2->dn) { 625 msg2->dn = msg->dn; 626 } 627 628 for (i=0;i<msg->num_elements;i++) { 629 struct ldb_message_element *el = &msg->elements[i]; 630 struct ldb_message_element *el2; 631 struct ldb_val *vals; 632 char *dn; 633 634 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { 635 636 case LDB_FLAG_MOD_ADD: 637 /* add this element to the message. fail if it 638 already exists */ 639 ret = find_element(msg2, el->name); 640 641 if (ret == -1) { 642 if (msg_add_element(ldb, msg2, el) != 0) { 643 ret = LDB_ERR_OTHER; 644 goto failed; 645 } 646 continue; 647 } 648 649 el2 = &msg2->elements[ret]; 650 651 /* An attribute with this name already exists, add all 652 * values if they don't already exist. */ 653 654 for (j=0;j<el->num_values;j++) { 655 if (ldb_msg_find_val(el2, &el->values[j])) { 656 ldb_set_errstring(module->ldb, "Type or value exists"); 657 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 658 goto failed; 659 } 660 } 661 662 vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val, 663 el2->num_values + el->num_values); 664 665 if (vals == NULL) { 666 ret = LDB_ERR_OTHER; 667 goto failed; 668 } 669 670 for (j=0;j<el->num_values;j++) { 671 vals[el2->num_values + j] = 672 ldb_val_dup(vals, &el->values[j]); 673 } 674 675 el2->values = vals; 676 el2->num_values += el->num_values; 677 678 break; 679 680 case LDB_FLAG_MOD_REPLACE: 681 /* replace all elements of this attribute name with the elements 682 listed. The attribute not existing is not an error */ 683 msg_delete_attribute(module, ldb, msg2, msg->elements[i].name); 684 685 /* add the replacement element, if not empty */ 686 if (msg->elements[i].num_values != 0 && 687 msg_add_element(ldb, msg2, &msg->elements[i]) != 0) { 688 ret = LDB_ERR_OTHER; 689 goto failed; 690 } 691 break; 692 693 case LDB_FLAG_MOD_DELETE: 694 695 dn = ldb_dn_linearize(msg2, msg->dn); 696 if (dn == NULL) { 697 ret = LDB_ERR_OTHER; 698 goto failed; 699 } 700 701 /* we could be being asked to delete all 702 values or just some values */ 703 if (msg->elements[i].num_values == 0) { 704 if (msg_delete_attribute(module, ldb, msg2, 705 msg->elements[i].name) != 0) { 706 ldb_asprintf_errstring(module->ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn); 707 ret = LDB_ERR_NO_SUCH_ATTRIBUTE; 708 goto failed; 709 } 710 break; 711 } 712 for (j=0;j<msg->elements[i].num_values;j++) { 713 if (msg_delete_element(module, 714 msg2, 715 msg->elements[i].name, 716 &msg->elements[i].values[j]) != 0) { 717 ldb_asprintf_errstring(module->ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn); 718 ret = LDB_ERR_NO_SUCH_ATTRIBUTE; 719 goto failed; 720 } 721 if (ltdb_index_del_value(module, dn, &msg->elements[i], j) != 0) { 722 ret = LDB_ERR_OTHER; 723 goto failed; 724 } 725 } 726 break; 727 default: 728 ldb_asprintf_errstring(module->ldb, "Invalid ldb_modify flags on %s: 0x%x", 729 msg->elements[i].name, 730 msg->elements[i].flags & LDB_FLAG_MOD_MASK); 731 ret = LDB_ERR_PROTOCOL_ERROR; 732 goto failed; 733 } 734 } 735 736 /* we've made all the mods - save the modified record back into the database */ 737 ret = ltdb_store(module, msg2, TDB_MODIFY); 738 if (ret != LDB_SUCCESS) { 739 goto failed; 740 } 741 742 if (ltdb_modified(module, msg->dn) != LDB_SUCCESS) { 743 ret = LDB_ERR_OPERATIONS_ERROR; 744 goto failed; 745 } 746 747 talloc_free(tdb_key.dptr); 748 free(tdb_data.dptr); 749 return ret; 750 751failed: 752 talloc_free(tdb_key.dptr); 753 free(tdb_data.dptr); 754 return ret; 755} 756 757/* 758 modify a record 759*/ 760static int ltdb_modify(struct ldb_module *module, struct ldb_request *req) 761{ 762 struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); 763 struct ltdb_context *ltdb_ac; 764 int tret, ret = LDB_SUCCESS; 765 766 if (req->controls != NULL) { 767 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); 768 if (check_critical_controls(req->controls)) { 769 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; 770 } 771 } 772 773 req->handle = NULL; 774 775 req->handle = init_ltdb_handle(ltdb, module, req); 776 if (req->handle == NULL) { 777 return LDB_ERR_OPERATIONS_ERROR; 778 } 779 ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); 780 781 tret = ltdb_check_special_dn(module, req->op.mod.message); 782 if (tret != LDB_SUCCESS) { 783 req->handle->status = tret; 784 goto done; 785 } 786 787 if (ltdb_cache_load(module) != 0) { 788 ret = LDB_ERR_OPERATIONS_ERROR; 789 goto done; 790 } 791 792 tret = ltdb_modify_internal(module, req->op.mod.message); 793 if (tret != LDB_SUCCESS) { 794 req->handle->status = tret; 795 goto done; 796 } 797 798 if (ltdb_ac->callback) { 799 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); 800 } 801done: 802 req->handle->state = LDB_ASYNC_DONE; 803 return ret; 804} 805 806/* 807 rename a record 808*/ 809static int ltdb_rename(struct ldb_module *module, struct ldb_request *req) 810{ 811 struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); 812 struct ltdb_context *ltdb_ac; 813 struct ldb_message *msg; 814 int tret, ret = LDB_SUCCESS; 815 816 if (req->controls != NULL) { 817 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); 818 if (check_critical_controls(req->controls)) { 819 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; 820 } 821 } 822 823 req->handle = NULL; 824 825 if (ltdb_cache_load(module) != 0) { 826 return LDB_ERR_OPERATIONS_ERROR; 827 } 828 829 req->handle = init_ltdb_handle(ltdb, module, req); 830 if (req->handle == NULL) { 831 return LDB_ERR_OPERATIONS_ERROR; 832 } 833 ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); 834 835 msg = talloc(ltdb_ac, struct ldb_message); 836 if (msg == NULL) { 837 ret = LDB_ERR_OPERATIONS_ERROR; 838 goto done; 839 } 840 841 /* in case any attribute of the message was indexed, we need 842 to fetch the old record */ 843 tret = ltdb_search_dn1(module, req->op.rename.olddn, msg); 844 if (tret != 1) { 845 /* not finding the old record is an error */ 846 req->handle->status = LDB_ERR_NO_SUCH_OBJECT; 847 goto done; 848 } 849 850 msg->dn = ldb_dn_copy(msg, req->op.rename.newdn); 851 if (!msg->dn) { 852 ret = LDB_ERR_OPERATIONS_ERROR; 853 goto done; 854 } 855 856 tret = ltdb_add_internal(module, msg); 857 if (tret != LDB_SUCCESS) { 858 ret = LDB_ERR_OPERATIONS_ERROR; 859 goto done; 860 } 861 862 tret = ltdb_delete_internal(module, req->op.rename.olddn); 863 if (tret != LDB_SUCCESS) { 864 ltdb_delete_internal(module, req->op.rename.newdn); 865 ret = LDB_ERR_OPERATIONS_ERROR; 866 goto done; 867 } 868 869 if (ltdb_ac->callback) { 870 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); 871 } 872done: 873 req->handle->state = LDB_ASYNC_DONE; 874 return ret; 875} 876 877static int ltdb_start_trans(struct ldb_module *module) 878{ 879 struct ltdb_private *ltdb = 880 talloc_get_type(module->private_data, struct ltdb_private); 881 882 if (tdb_transaction_start(ltdb->tdb) != 0) { 883 return ltdb_err_map(tdb_error(ltdb->tdb)); 884 } 885 886 return LDB_SUCCESS; 887} 888 889static int ltdb_end_trans(struct ldb_module *module) 890{ 891 struct ltdb_private *ltdb = 892 talloc_get_type(module->private_data, struct ltdb_private); 893 894 if (tdb_transaction_commit(ltdb->tdb) != 0) { 895 return ltdb_err_map(tdb_error(ltdb->tdb)); 896 } 897 898 return LDB_SUCCESS; 899} 900 901static int ltdb_del_trans(struct ldb_module *module) 902{ 903 struct ltdb_private *ltdb = 904 talloc_get_type(module->private_data, struct ltdb_private); 905 906 if (tdb_transaction_cancel(ltdb->tdb) != 0) { 907 return ltdb_err_map(tdb_error(ltdb->tdb)); 908 } 909 910 return LDB_SUCCESS; 911} 912 913static int ltdb_wait(struct ldb_handle *handle, enum ldb_wait_type type) 914{ 915 return handle->status; 916} 917 918static int ltdb_request(struct ldb_module *module, struct ldb_request *req) 919{ 920 /* check for oustanding critical controls and return an error if found */ 921 if (req->controls != NULL) { 922 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); 923 if (check_critical_controls(req->controls)) { 924 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; 925 } 926 } 927 928 /* search, add, modify, delete, rename are handled by their own, no other op supported */ 929 return LDB_ERR_OPERATIONS_ERROR; 930} 931 932/* 933 return sequenceNumber from @BASEINFO 934*/ 935static int ltdb_sequence_number(struct ldb_module *module, struct ldb_request *req) 936{ 937 TALLOC_CTX *tmp_ctx = talloc_new(req); 938 struct ldb_message *msg = NULL; 939 struct ldb_dn *dn = ldb_dn_explode(tmp_ctx, LTDB_BASEINFO); 940 int tret; 941 942 if (tmp_ctx == NULL) { 943 talloc_free(tmp_ctx); 944 return LDB_ERR_OPERATIONS_ERROR; 945 } 946 947 msg = talloc(tmp_ctx, struct ldb_message); 948 if (msg == NULL) { 949 talloc_free(tmp_ctx); 950 return LDB_ERR_OPERATIONS_ERROR; 951 } 952 953 req->op.seq_num.flags = 0; 954 955 tret = ltdb_search_dn1(module, dn, msg); 956 if (tret != 1) { 957 talloc_free(tmp_ctx); 958 req->op.seq_num.seq_num = 0; 959 /* zero is as good as anything when we don't know */ 960 return LDB_SUCCESS; 961 } 962 963 switch (req->op.seq_num.type) { 964 case LDB_SEQ_HIGHEST_SEQ: 965 req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0); 966 break; 967 case LDB_SEQ_NEXT: 968 req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0); 969 req->op.seq_num.seq_num++; 970 break; 971 case LDB_SEQ_HIGHEST_TIMESTAMP: 972 { 973 const char *date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL); 974 if (date) { 975 req->op.seq_num.seq_num = ldb_string_to_time(date); 976 } else { 977 req->op.seq_num.seq_num = 0; 978 /* zero is as good as anything when we don't know */ 979 } 980 break; 981 } 982 } 983 talloc_free(tmp_ctx); 984 return LDB_SUCCESS; 985} 986 987static const struct ldb_module_ops ltdb_ops = { 988 .name = "tdb", 989 .search = ltdb_search, 990 .add = ltdb_add, 991 .modify = ltdb_modify, 992 .del = ltdb_delete, 993 .rename = ltdb_rename, 994 .request = ltdb_request, 995 .start_transaction = ltdb_start_trans, 996 .end_transaction = ltdb_end_trans, 997 .del_transaction = ltdb_del_trans, 998 .wait = ltdb_wait, 999 .sequence_number = ltdb_sequence_number 1000}; 1001 1002/* 1003 connect to the database 1004*/ 1005static int ltdb_connect(struct ldb_context *ldb, const char *url, 1006 unsigned int flags, const char *options[], 1007 struct ldb_module **module) 1008{ 1009 const char *path; 1010 int tdb_flags, open_flags; 1011 struct ltdb_private *ltdb; 1012 1013 /* parse the url */ 1014 if (strchr(url, ':')) { 1015 if (strncmp(url, "tdb://", 6) != 0) { 1016 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid tdb URL '%s'", url); 1017 return -1; 1018 } 1019 path = url+6; 1020 } else { 1021 path = url; 1022 } 1023 1024 tdb_flags = TDB_DEFAULT | TDB_SEQNUM; 1025 1026 /* check for the 'nosync' option */ 1027 if (flags & LDB_FLG_NOSYNC) { 1028 tdb_flags |= TDB_NOSYNC; 1029 } 1030 1031 /* and nommap option */ 1032 if (flags & LDB_FLG_NOMMAP) { 1033 tdb_flags |= TDB_NOMMAP; 1034 } 1035 1036 if (flags & LDB_FLG_RDONLY) { 1037 open_flags = O_RDONLY; 1038 } else { 1039 open_flags = O_CREAT | O_RDWR; 1040 } 1041 1042 ltdb = talloc_zero(ldb, struct ltdb_private); 1043 if (!ltdb) { 1044 ldb_oom(ldb); 1045 return -1; 1046 } 1047 1048 /* note that we use quite a large default hash size */ 1049 ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, 1050 tdb_flags, open_flags, 1051 ldb->create_perms, ldb); 1052 if (!ltdb->tdb) { 1053 ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path); 1054 talloc_free(ltdb); 1055 return -1; 1056 } 1057 1058 ltdb->sequence_number = 0; 1059 1060 *module = talloc(ldb, struct ldb_module); 1061 if ((*module) == NULL) { 1062 ldb_oom(ldb); 1063 talloc_free(ltdb); 1064 return -1; 1065 } 1066 talloc_set_name_const(*module, "ldb_tdb backend"); 1067 (*module)->ldb = ldb; 1068 (*module)->prev = (*module)->next = NULL; 1069 (*module)->private_data = ltdb; 1070 (*module)->ops = <db_ops; 1071 1072 if (ltdb_cache_load(*module) != 0) { 1073 talloc_free(*module); 1074 talloc_free(ltdb); 1075 return -1; 1076 } 1077 1078 return 0; 1079} 1080 1081int ldb_tdb_init(void) 1082{ 1083 return ldb_register_backend("tdb", ltdb_connect); 1084} 1085