root/source3/lib/ldb/ldb_tdb/ldb_tdb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ltdb_err_map
  2. init_ltdb_handle
  3. ltdb_key
  4. ltdb_check_special_dn
  5. ltdb_modified
  6. ltdb_store
  7. ltdb_add_internal
  8. ltdb_add
  9. ltdb_delete_noindex
  10. ltdb_delete_internal
  11. ltdb_delete
  12. find_element
  13. msg_add_element
  14. msg_delete_attribute
  15. msg_delete_element
  16. ltdb_modify_internal
  17. ltdb_modify
  18. ltdb_rename
  19. ltdb_start_trans
  20. ltdb_end_trans
  21. ltdb_del_trans
  22. ltdb_wait
  23. ltdb_request
  24. ltdb_sequence_number
  25. ltdb_connect
  26. ldb_tdb_init

   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 
  49 int 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 */
  54 static int ltdb_err_map(enum TDB_ERROR tdb_code)
     /* [<][>][^][v][top][bottom][index][help] */
  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 
  81 struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module,
     /* [<][>][^][v][top][bottom][index][help] */
  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 */
 121 struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 158 failed:
 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 */
 169 int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg)
     /* [<][>][^][v][top][bottom][index][help] */
 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 */
 197 static int ltdb_modified(struct ldb_module *module, const struct ldb_dn *dn)
     /* [<][>][^][v][top][bottom][index][help] */
 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 */
 219 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 248 done:
 249         talloc_free(tdb_key.dptr);
 250         talloc_free(tdb_data.dptr);
 251 
 252         return ret;
 253 }
 254 
 255 
 256 static int ltdb_add_internal(struct ldb_module *module, const struct ldb_message *msg)
     /* [<][>][^][v][top][bottom][index][help] */
 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 */
 296 static int ltdb_add(struct ldb_module *module, struct ldb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 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         }
 324 done:
 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 */
 333 int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 355 static int ltdb_delete_internal(struct ldb_module *module, const struct ldb_dn *dn)
     /* [<][>][^][v][top][bottom][index][help] */
 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 */
 400 static int ltdb_delete(struct ldb_module *module, struct ldb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 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         }
 434 done:
 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 */
 446 static int find_element(const struct ldb_message *msg, const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 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 */
 465 static int msg_add_element(struct ldb_context *ldb,
     /* [<][>][^][v][top][bottom][index][help] */
 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 */
 505 static int msg_delete_attribute(struct ldb_module *module,
     /* [<][>][^][v][top][bottom][index][help] */
 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 */
 546 static int msg_delete_element(struct ldb_module *module,
     /* [<][>][^][v][top][bottom][index][help] */
 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 */
 591 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 751 failed:
 752         talloc_free(tdb_key.dptr);
 753         free(tdb_data.dptr);
 754         return ret;
 755 }
 756 
 757 /*
 758   modify a record
 759 */
 760 static int ltdb_modify(struct ldb_module *module, struct ldb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 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         }
 801 done:
 802         req->handle->state = LDB_ASYNC_DONE;
 803         return ret;
 804 }
 805 
 806 /*
 807   rename a record
 808 */
 809 static int ltdb_rename(struct ldb_module *module, struct ldb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 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         }
 872 done:
 873         req->handle->state = LDB_ASYNC_DONE;
 874         return ret;
 875 }
 876 
 877 static int ltdb_start_trans(struct ldb_module *module)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 889 static int ltdb_end_trans(struct ldb_module *module)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 901 static int ltdb_del_trans(struct ldb_module *module)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 913 static int ltdb_wait(struct ldb_handle *handle, enum ldb_wait_type type)
     /* [<][>][^][v][top][bottom][index][help] */
 914 {
 915         return handle->status;
 916 }
 917 
 918 static int ltdb_request(struct ldb_module *module, struct ldb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 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 */
 935 static int ltdb_sequence_number(struct ldb_module *module, struct ldb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 987 static 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 */
1005 static int ltdb_connect(struct ldb_context *ldb, const char *url, 
     /* [<][>][^][v][top][bottom][index][help] */
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 = &ltdb_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 
1081 int ldb_tdb_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
1082 {
1083         return ldb_register_backend("tdb", ltdb_connect);
1084 }

/* [<][>][^][v][top][bottom][index][help] */