/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- ltdb_err_map
- init_ltdb_handle
- ltdb_key
- ltdb_check_special_dn
- ltdb_modified
- ltdb_store
- ltdb_add_internal
- ltdb_add
- ltdb_delete_noindex
- ltdb_delete_internal
- ltdb_delete
- find_element
- msg_add_element
- msg_delete_attribute
- msg_delete_element
- ltdb_modify_internal
- ltdb_modify
- ltdb_rename
- ltdb_start_trans
- ltdb_end_trans
- ltdb_del_trans
- ltdb_wait
- ltdb_request
- ltdb_sequence_number
- ltdb_connect
- 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 = <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
1081 int ldb_tdb_init(void)
/* [<][>][^][v][top][bottom][index][help] */
1082 {
1083 return ldb_register_backend("tdb", ltdb_connect);
1084 }