/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- ltdb_err_map
- ltdb_lock_read
- ltdb_unlock_read
- 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_sequence_number
- ltdb_request_done
- ltdb_timeout
- ltdb_request_extended_done
- ltdb_handle_extended
- ltdb_callback
- ltdb_request_destructor
- ltdb_handle_request
- ltdb_connect
1 /*
2 ldb database library
3
4 Copyright (C) Andrew Tridgell 2004
5 Copyright (C) Stefan Metzmacher 2004
6 Copyright (C) Simo Sorce 2006-2008
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 * - description: make it possible to use event contexts
44 * date: Jan 2008
45 * Author: Simo Sorce
46 */
47
48 #include "ldb_tdb.h"
49
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 lock the database for read - use by ltdb_search and ltdb_sequence_number
82 */
83 int ltdb_lock_read(struct ldb_module *module)
/* [<][>][^][v][top][bottom][index][help] */
84 {
85 void *data = ldb_module_get_private(module);
86 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
87 if (ltdb->in_transaction == 0) {
88 return tdb_lockall_read(ltdb->tdb);
89 }
90 return 0;
91 }
92
93 /*
94 unlock the database after a ltdb_lock_read()
95 */
96 int ltdb_unlock_read(struct ldb_module *module)
/* [<][>][^][v][top][bottom][index][help] */
97 {
98 void *data = ldb_module_get_private(module);
99 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
100 if (ltdb->in_transaction == 0) {
101 return tdb_unlockall_read(ltdb->tdb);
102 }
103 return 0;
104 }
105
106
107 /*
108 form a TDB_DATA for a record key
109 caller frees
110
111 note that the key for a record can depend on whether the
112 dn refers to a case sensitive index record or not
113 */
114 struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn)
/* [<][>][^][v][top][bottom][index][help] */
115 {
116 struct ldb_context *ldb = ldb_module_get_ctx(module);
117 TDB_DATA key;
118 char *key_str = NULL;
119 const char *dn_folded = NULL;
120
121 /*
122 most DNs are case insensitive. The exception is index DNs for
123 case sensitive attributes
124
125 there are 3 cases dealt with in this code:
126
127 1) if the dn doesn't start with @ then uppercase the attribute
128 names and the attributes values of case insensitive attributes
129 2) if the dn starts with @ then leave it alone -
130 the indexing code handles the rest
131 */
132
133 dn_folded = ldb_dn_get_casefold(dn);
134 if (!dn_folded) {
135 goto failed;
136 }
137
138 key_str = talloc_strdup(ldb, "DN=");
139 if (!key_str) {
140 goto failed;
141 }
142
143 key_str = talloc_strdup_append_buffer(key_str, dn_folded);
144 if (!key_str) {
145 goto failed;
146 }
147
148 key.dptr = (uint8_t *)key_str;
149 key.dsize = strlen(key_str) + 1;
150
151 return key;
152
153 failed:
154 errno = ENOMEM;
155 key.dptr = NULL;
156 key.dsize = 0;
157 return key;
158 }
159
160 /*
161 check special dn's have valid attributes
162 currently only @ATTRIBUTES is checked
163 */
164 static int ltdb_check_special_dn(struct ldb_module *module,
/* [<][>][^][v][top][bottom][index][help] */
165 const struct ldb_message *msg)
166 {
167 struct ldb_context *ldb = ldb_module_get_ctx(module);
168 int i, j;
169
170 if (! ldb_dn_is_special(msg->dn) ||
171 ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
172 return 0;
173 }
174
175 /* we have @ATTRIBUTES, let's check attributes are fine */
176 /* should we check that we deny multivalued attributes ? */
177 for (i = 0; i < msg->num_elements; i++) {
178 for (j = 0; j < msg->elements[i].num_values; j++) {
179 if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
180 ldb_set_errstring(ldb, "Invalid attribute value in an @ATTRIBUTES entry");
181 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
182 }
183 }
184 }
185
186 return 0;
187 }
188
189
190 /*
191 we've made a modification to a dn - possibly reindex and
192 update sequence number
193 */
194 static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
/* [<][>][^][v][top][bottom][index][help] */
195 {
196 int ret = LDB_SUCCESS;
197
198 if (ldb_dn_is_special(dn) &&
199 (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
200 ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
201 ret = ltdb_reindex(module);
202 }
203
204 if (ret == LDB_SUCCESS &&
205 !(ldb_dn_is_special(dn) &&
206 ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
207 ret = ltdb_increase_sequence_number(module);
208 }
209
210 return ret;
211 }
212
213 /*
214 store a record into the db
215 */
216 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
/* [<][>][^][v][top][bottom][index][help] */
217 {
218 void *data = ldb_module_get_private(module);
219 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
220 TDB_DATA tdb_key, tdb_data;
221 int ret;
222
223 tdb_key = ltdb_key(module, msg->dn);
224 if (!tdb_key.dptr) {
225 return LDB_ERR_OTHER;
226 }
227
228 ret = ltdb_pack_data(module, msg, &tdb_data);
229 if (ret == -1) {
230 talloc_free(tdb_key.dptr);
231 return LDB_ERR_OTHER;
232 }
233
234 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
235 if (ret == -1) {
236 ret = ltdb_err_map(tdb_error(ltdb->tdb));
237 goto done;
238 }
239
240 ret = ltdb_index_add(module, msg);
241 if (ret != LDB_SUCCESS) {
242 tdb_delete(ltdb->tdb, tdb_key);
243 }
244
245 done:
246 talloc_free(tdb_key.dptr);
247 talloc_free(tdb_data.dptr);
248
249 return ret;
250 }
251
252
253 static int ltdb_add_internal(struct ldb_module *module,
/* [<][>][^][v][top][bottom][index][help] */
254 const struct ldb_message *msg)
255 {
256 struct ldb_context *ldb = ldb_module_get_ctx(module);
257 int ret;
258
259 ret = ltdb_check_special_dn(module, msg);
260 if (ret != LDB_SUCCESS) {
261 return ret;
262 }
263
264 if (ltdb_cache_load(module) != 0) {
265 return LDB_ERR_OPERATIONS_ERROR;
266 }
267
268 ret = ltdb_store(module, msg, TDB_INSERT);
269
270 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
271 ldb_asprintf_errstring(ldb,
272 "Entry %s already exists",
273 ldb_dn_get_linearized(msg->dn));
274 return ret;
275 }
276
277 if (ret == LDB_SUCCESS) {
278 ret = ltdb_index_one(module, msg, 1);
279 if (ret != LDB_SUCCESS) {
280 return ret;
281 }
282
283 ret = ltdb_modified(module, msg->dn);
284 if (ret != LDB_SUCCESS) {
285 return ret;
286 }
287 }
288
289 return ret;
290 }
291
292 /*
293 add a record to the database
294 */
295 static int ltdb_add(struct ltdb_context *ctx)
/* [<][>][^][v][top][bottom][index][help] */
296 {
297 struct ldb_module *module = ctx->module;
298 struct ldb_request *req = ctx->req;
299 int tret;
300
301 ldb_request_set_state(req, LDB_ASYNC_PENDING);
302
303 tret = ltdb_add_internal(module, req->op.add.message);
304 if (tret != LDB_SUCCESS) {
305 return tret;
306 }
307
308 return LDB_SUCCESS;
309 }
310
311 /*
312 delete a record from the database, not updating indexes (used for deleting
313 index records)
314 */
315 int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn)
/* [<][>][^][v][top][bottom][index][help] */
316 {
317 void *data = ldb_module_get_private(module);
318 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
319 TDB_DATA tdb_key;
320 int ret;
321
322 tdb_key = ltdb_key(module, dn);
323 if (!tdb_key.dptr) {
324 return LDB_ERR_OTHER;
325 }
326
327 ret = tdb_delete(ltdb->tdb, tdb_key);
328 talloc_free(tdb_key.dptr);
329
330 if (ret != 0) {
331 ret = ltdb_err_map(tdb_error(ltdb->tdb));
332 }
333
334 return ret;
335 }
336
337 static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn)
/* [<][>][^][v][top][bottom][index][help] */
338 {
339 struct ldb_message *msg;
340 int ret;
341
342 msg = talloc(module, struct ldb_message);
343 if (msg == NULL) {
344 return LDB_ERR_OPERATIONS_ERROR;
345 }
346
347 /* in case any attribute of the message was indexed, we need
348 to fetch the old record */
349 ret = ltdb_search_dn1(module, dn, msg);
350 if (ret != LDB_SUCCESS) {
351 /* not finding the old record is an error */
352 goto done;
353 }
354
355 ret = ltdb_delete_noindex(module, dn);
356 if (ret != LDB_SUCCESS) {
357 goto done;
358 }
359
360 /* remove one level attribute */
361 ret = ltdb_index_one(module, msg, 0);
362 if (ret != LDB_SUCCESS) {
363 goto done;
364 }
365
366 /* remove any indexed attributes */
367 ret = ltdb_index_del(module, msg);
368 if (ret != LDB_SUCCESS) {
369 goto done;
370 }
371
372 ret = ltdb_modified(module, dn);
373 if (ret != LDB_SUCCESS) {
374 goto done;
375 }
376
377 done:
378 talloc_free(msg);
379 return ret;
380 }
381
382 /*
383 delete a record from the database
384 */
385 static int ltdb_delete(struct ltdb_context *ctx)
/* [<][>][^][v][top][bottom][index][help] */
386 {
387 struct ldb_module *module = ctx->module;
388 struct ldb_request *req = ctx->req;
389 int tret;
390
391 ldb_request_set_state(req, LDB_ASYNC_PENDING);
392
393 if (ltdb_cache_load(module) != 0) {
394 return LDB_ERR_OPERATIONS_ERROR;
395 }
396
397 tret = ltdb_delete_internal(module, req->op.del.dn);
398 if (tret != LDB_SUCCESS) {
399 return tret;
400 }
401
402 return LDB_SUCCESS;
403 }
404
405 /*
406 find an element by attribute name. At the moment this does a linear search,
407 it should be re-coded to use a binary search once all places that modify
408 records guarantee sorted order
409
410 return the index of the first matching element if found, otherwise -1
411 */
412 static int find_element(const struct ldb_message *msg, const char *name)
/* [<][>][^][v][top][bottom][index][help] */
413 {
414 unsigned int i;
415 for (i=0;i<msg->num_elements;i++) {
416 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
417 return i;
418 }
419 }
420 return -1;
421 }
422
423
424 /*
425 add an element to an existing record. Assumes a elements array that we
426 can call re-alloc on, and assumed that we can re-use the data pointers from
427 the passed in additional values. Use with care!
428
429 returns 0 on success, -1 on failure (and sets errno)
430 */
431 static int msg_add_element(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
432 struct ldb_message *msg,
433 struct ldb_message_element *el)
434 {
435 struct ldb_message_element *e2;
436 unsigned int i;
437
438 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
439 msg->num_elements+1);
440 if (!e2) {
441 errno = ENOMEM;
442 return -1;
443 }
444
445 msg->elements = e2;
446
447 e2 = &msg->elements[msg->num_elements];
448
449 e2->name = el->name;
450 e2->flags = el->flags;
451 e2->values = NULL;
452 if (el->num_values != 0) {
453 e2->values = talloc_array(msg->elements,
454 struct ldb_val, el->num_values);
455 if (!e2->values) {
456 errno = ENOMEM;
457 return -1;
458 }
459 }
460 for (i=0;i<el->num_values;i++) {
461 e2->values[i] = el->values[i];
462 }
463 e2->num_values = el->num_values;
464
465 msg->num_elements++;
466
467 return 0;
468 }
469
470 /*
471 delete all elements having a specified attribute name
472 */
473 static int msg_delete_attribute(struct ldb_module *module,
/* [<][>][^][v][top][bottom][index][help] */
474 struct ldb_context *ldb,
475 struct ldb_message *msg, const char *name)
476 {
477 const char *dn;
478 unsigned int i, j;
479
480 dn = ldb_dn_get_linearized(msg->dn);
481 if (dn == NULL) {
482 return -1;
483 }
484
485 for (i=0;i<msg->num_elements;i++) {
486 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
487 for (j=0;j<msg->elements[i].num_values;j++) {
488 ltdb_index_del_value(module, dn,
489 &msg->elements[i], j);
490 }
491 talloc_free(msg->elements[i].values);
492 if (msg->num_elements > (i+1)) {
493 memmove(&msg->elements[i],
494 &msg->elements[i+1],
495 sizeof(struct ldb_message_element)*
496 (msg->num_elements - (i+1)));
497 }
498 msg->num_elements--;
499 i--;
500 msg->elements = talloc_realloc(msg, msg->elements,
501 struct ldb_message_element,
502 msg->num_elements);
503 }
504 }
505
506 return 0;
507 }
508
509 /*
510 delete all elements matching an attribute name/value
511
512 return 0 on success, -1 on failure
513 */
514 static int msg_delete_element(struct ldb_module *module,
/* [<][>][^][v][top][bottom][index][help] */
515 struct ldb_message *msg,
516 const char *name,
517 const struct ldb_val *val)
518 {
519 struct ldb_context *ldb = ldb_module_get_ctx(module);
520 unsigned int i;
521 int found;
522 struct ldb_message_element *el;
523 const struct ldb_schema_attribute *a;
524
525 found = find_element(msg, name);
526 if (found == -1) {
527 return -1;
528 }
529
530 el = &msg->elements[found];
531
532 a = ldb_schema_attribute_by_name(ldb, el->name);
533
534 for (i=0;i<el->num_values;i++) {
535 if (a->syntax->comparison_fn(ldb, ldb,
536 &el->values[i], val) == 0) {
537 if (i<el->num_values-1) {
538 memmove(&el->values[i], &el->values[i+1],
539 sizeof(el->values[i])*
540 (el->num_values-(i+1)));
541 }
542 el->num_values--;
543 if (el->num_values == 0) {
544 return msg_delete_attribute(module, ldb,
545 msg, name);
546 }
547 return 0;
548 }
549 }
550
551 return -1;
552 }
553
554
555 /*
556 modify a record - internal interface
557
558 yuck - this is O(n^2). Luckily n is usually small so we probably
559 get away with it, but if we ever have really large attribute lists
560 then we'll need to look at this again
561 */
562 int ltdb_modify_internal(struct ldb_module *module,
/* [<][>][^][v][top][bottom][index][help] */
563 const struct ldb_message *msg)
564 {
565 struct ldb_context *ldb = ldb_module_get_ctx(module);
566 void *data = ldb_module_get_private(module);
567 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
568 TDB_DATA tdb_key, tdb_data;
569 struct ldb_message *msg2;
570 unsigned i, j;
571 int ret, idx;
572
573 tdb_key = ltdb_key(module, msg->dn);
574 if (!tdb_key.dptr) {
575 return LDB_ERR_OTHER;
576 }
577
578 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
579 if (!tdb_data.dptr) {
580 talloc_free(tdb_key.dptr);
581 return ltdb_err_map(tdb_error(ltdb->tdb));
582 }
583
584 msg2 = talloc(tdb_key.dptr, struct ldb_message);
585 if (msg2 == NULL) {
586 talloc_free(tdb_key.dptr);
587 return LDB_ERR_OTHER;
588 }
589
590 ret = ltdb_unpack_data(module, &tdb_data, msg2);
591 if (ret == -1) {
592 ret = LDB_ERR_OTHER;
593 goto failed;
594 }
595
596 if (!msg2->dn) {
597 msg2->dn = msg->dn;
598 }
599
600 for (i=0;i<msg->num_elements;i++) {
601 struct ldb_message_element *el = &msg->elements[i];
602 struct ldb_message_element *el2;
603 struct ldb_val *vals;
604 const char *dn;
605
606 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
607
608 case LDB_FLAG_MOD_ADD:
609 /* add this element to the message. fail if it
610 already exists */
611 idx = find_element(msg2, el->name);
612
613 if (idx == -1) {
614 if (msg_add_element(ldb, msg2, el) != 0) {
615 ret = LDB_ERR_OTHER;
616 goto failed;
617 }
618 continue;
619 }
620
621 el2 = &msg2->elements[idx];
622
623 /* An attribute with this name already exists,
624 * add all values if they don't already exist
625 * (check both the other elements to be added,
626 * and those already in the db). */
627
628 for (j=0;j<el->num_values;j++) {
629 if (ldb_msg_find_val(el2, &el->values[j])) {
630 ldb_asprintf_errstring(ldb, "%s: value #%d already exists", el->name, j);
631 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
632 goto failed;
633 }
634 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
635 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
636 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
637 goto failed;
638 }
639 }
640
641 vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
642 el2->num_values + el->num_values);
643
644 if (vals == NULL) {
645 ret = LDB_ERR_OTHER;
646 goto failed;
647 }
648
649 for (j=0;j<el->num_values;j++) {
650 vals[el2->num_values + j] =
651 ldb_val_dup(vals, &el->values[j]);
652 }
653
654 el2->values = vals;
655 el2->num_values += el->num_values;
656
657 break;
658
659 case LDB_FLAG_MOD_REPLACE:
660 /* replace all elements of this attribute name with the elements
661 listed. The attribute not existing is not an error */
662 msg_delete_attribute(module, ldb, msg2, el->name);
663
664 for (j=0;j<el->num_values;j++) {
665 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
666 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
667 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
668 goto failed;
669 }
670 }
671
672 /* add the replacement element, if not empty */
673 if (el->num_values != 0 &&
674 msg_add_element(ldb, msg2, el) != 0) {
675 ret = LDB_ERR_OTHER;
676 goto failed;
677 }
678 break;
679
680 case LDB_FLAG_MOD_DELETE:
681
682 dn = ldb_dn_get_linearized(msg->dn);
683 if (dn == NULL) {
684 ret = LDB_ERR_OTHER;
685 goto failed;
686 }
687
688 /* we could be being asked to delete all
689 values or just some values */
690 if (msg->elements[i].num_values == 0) {
691 if (msg_delete_attribute(module, ldb, msg2,
692 msg->elements[i].name) != 0) {
693 ldb_asprintf_errstring(ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn);
694 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
695 goto failed;
696 }
697 break;
698 }
699 for (j=0;j<msg->elements[i].num_values;j++) {
700 if (msg_delete_element(module,
701 msg2,
702 msg->elements[i].name,
703 &msg->elements[i].values[j]) != 0) {
704 ldb_asprintf_errstring(ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn);
705 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
706 goto failed;
707 }
708 ret = ltdb_index_del_value(module, dn, &msg->elements[i], j);
709 if (ret != LDB_SUCCESS) {
710 goto failed;
711 }
712 }
713 break;
714 default:
715 ldb_asprintf_errstring(ldb,
716 "Invalid ldb_modify flags on %s: 0x%x",
717 msg->elements[i].name,
718 msg->elements[i].flags & LDB_FLAG_MOD_MASK);
719 ret = LDB_ERR_PROTOCOL_ERROR;
720 goto failed;
721 }
722 }
723
724 /* we've made all the mods
725 * save the modified record back into the database */
726 ret = ltdb_store(module, msg2, TDB_MODIFY);
727 if (ret != LDB_SUCCESS) {
728 goto failed;
729 }
730
731 ret = ltdb_modified(module, msg->dn);
732 if (ret != LDB_SUCCESS) {
733 goto failed;
734 }
735
736 talloc_free(tdb_key.dptr);
737 free(tdb_data.dptr);
738 return ret;
739
740 failed:
741 talloc_free(tdb_key.dptr);
742 free(tdb_data.dptr);
743 return ret;
744 }
745
746 /*
747 modify a record
748 */
749 static int ltdb_modify(struct ltdb_context *ctx)
/* [<][>][^][v][top][bottom][index][help] */
750 {
751 struct ldb_module *module = ctx->module;
752 struct ldb_request *req = ctx->req;
753 int tret;
754
755 ldb_request_set_state(req, LDB_ASYNC_PENDING);
756
757 tret = ltdb_check_special_dn(module, req->op.mod.message);
758 if (tret != LDB_SUCCESS) {
759 return tret;
760 }
761
762 if (ltdb_cache_load(module) != 0) {
763 return LDB_ERR_OPERATIONS_ERROR;
764 }
765
766 tret = ltdb_modify_internal(module, req->op.mod.message);
767 if (tret != LDB_SUCCESS) {
768 return tret;
769 }
770
771 return LDB_SUCCESS;
772 }
773
774 /*
775 rename a record
776 */
777 static int ltdb_rename(struct ltdb_context *ctx)
/* [<][>][^][v][top][bottom][index][help] */
778 {
779 struct ldb_module *module = ctx->module;
780 struct ldb_request *req = ctx->req;
781 struct ldb_message *msg;
782 int tret;
783
784 ldb_request_set_state(req, LDB_ASYNC_PENDING);
785
786 if (ltdb_cache_load(ctx->module) != 0) {
787 return LDB_ERR_OPERATIONS_ERROR;
788 }
789
790 msg = talloc(ctx, struct ldb_message);
791 if (msg == NULL) {
792 return LDB_ERR_OPERATIONS_ERROR;
793 }
794
795 /* in case any attribute of the message was indexed, we need
796 to fetch the old record */
797 tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
798 if (tret != LDB_SUCCESS) {
799 /* not finding the old record is an error */
800 return tret;
801 }
802
803 msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
804 if (!msg->dn) {
805 return LDB_ERR_OPERATIONS_ERROR;
806 }
807
808 if (ldb_dn_compare(req->op.rename.olddn, req->op.rename.newdn) == 0) {
809 /* The rename operation is apparently only changing case -
810 the DNs are the same. Delete the old DN before adding
811 the new one to avoid a TDB_ERR_EXISTS error.
812
813 The only drawback to this is that if the delete
814 succeeds but the add fails, we rely on the
815 transaction to roll this all back. */
816 tret = ltdb_delete_internal(module, req->op.rename.olddn);
817 if (tret != LDB_SUCCESS) {
818 return tret;
819 }
820
821 tret = ltdb_add_internal(module, msg);
822 if (tret != LDB_SUCCESS) {
823 return tret;
824 }
825 } else {
826 /* The rename operation is changing DNs. Try to add the new
827 DN first to avoid clobbering another DN not related to
828 this rename operation. */
829 tret = ltdb_add_internal(module, msg);
830 if (tret != LDB_SUCCESS) {
831 return tret;
832 }
833
834 tret = ltdb_delete_internal(module, req->op.rename.olddn);
835 if (tret != LDB_SUCCESS) {
836 ltdb_delete_internal(module, req->op.rename.newdn);
837 return LDB_ERR_OPERATIONS_ERROR;
838 }
839 }
840
841 return LDB_SUCCESS;
842 }
843
844 static int ltdb_start_trans(struct ldb_module *module)
/* [<][>][^][v][top][bottom][index][help] */
845 {
846 void *data = ldb_module_get_private(module);
847 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
848
849 if (tdb_transaction_start(ltdb->tdb) != 0) {
850 return ltdb_err_map(tdb_error(ltdb->tdb));
851 }
852
853 ltdb->in_transaction++;
854
855 ltdb_index_transaction_start(module);
856
857 return LDB_SUCCESS;
858 }
859
860 static int ltdb_end_trans(struct ldb_module *module)
/* [<][>][^][v][top][bottom][index][help] */
861 {
862 void *data = ldb_module_get_private(module);
863 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
864
865 ltdb->in_transaction--;
866
867 if (ltdb_index_transaction_commit(module) != 0) {
868 tdb_transaction_cancel(ltdb->tdb);
869 return ltdb_err_map(tdb_error(ltdb->tdb));
870 }
871
872 if (tdb_transaction_commit(ltdb->tdb) != 0) {
873 return ltdb_err_map(tdb_error(ltdb->tdb));
874 }
875
876 return LDB_SUCCESS;
877 }
878
879 static int ltdb_del_trans(struct ldb_module *module)
/* [<][>][^][v][top][bottom][index][help] */
880 {
881 void *data = ldb_module_get_private(module);
882 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
883
884 ltdb->in_transaction--;
885
886 if (ltdb_index_transaction_cancel(module) != 0) {
887 tdb_transaction_cancel(ltdb->tdb);
888 return ltdb_err_map(tdb_error(ltdb->tdb));
889 }
890
891 if (tdb_transaction_cancel(ltdb->tdb) != 0) {
892 return ltdb_err_map(tdb_error(ltdb->tdb));
893 }
894
895 return LDB_SUCCESS;
896 }
897
898 /*
899 return sequenceNumber from @BASEINFO
900 */
901 static int ltdb_sequence_number(struct ltdb_context *ctx,
/* [<][>][^][v][top][bottom][index][help] */
902 struct ldb_extended **ext)
903 {
904 struct ldb_context *ldb;
905 struct ldb_module *module = ctx->module;
906 struct ldb_request *req = ctx->req;
907 TALLOC_CTX *tmp_ctx;
908 struct ldb_seqnum_request *seq;
909 struct ldb_seqnum_result *res;
910 struct ldb_message *msg = NULL;
911 struct ldb_dn *dn;
912 const char *date;
913 int ret;
914
915 ldb = ldb_module_get_ctx(module);
916
917 seq = talloc_get_type(req->op.extended.data,
918 struct ldb_seqnum_request);
919 if (seq == NULL) {
920 return LDB_ERR_OPERATIONS_ERROR;
921 }
922
923 ldb_request_set_state(req, LDB_ASYNC_PENDING);
924
925 if (ltdb_lock_read(module) != 0) {
926 return LDB_ERR_OPERATIONS_ERROR;
927 }
928
929 res = talloc_zero(req, struct ldb_seqnum_result);
930 if (res == NULL) {
931 ret = LDB_ERR_OPERATIONS_ERROR;
932 goto done;
933 }
934 tmp_ctx = talloc_new(req);
935 if (tmp_ctx == NULL) {
936 ret = LDB_ERR_OPERATIONS_ERROR;
937 goto done;
938 }
939
940 dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO);
941
942 msg = talloc(tmp_ctx, struct ldb_message);
943 if (msg == NULL) {
944 ret = LDB_ERR_OPERATIONS_ERROR;
945 goto done;
946 }
947
948 ret = ltdb_search_dn1(module, dn, msg);
949 if (ret != LDB_SUCCESS) {
950 goto done;
951 }
952
953 switch (seq->type) {
954 case LDB_SEQ_HIGHEST_SEQ:
955 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
956 break;
957 case LDB_SEQ_NEXT:
958 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
959 res->seq_num++;
960 break;
961 case LDB_SEQ_HIGHEST_TIMESTAMP:
962 date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
963 if (date) {
964 res->seq_num = ldb_string_to_time(date);
965 } else {
966 res->seq_num = 0;
967 /* zero is as good as anything when we don't know */
968 }
969 break;
970 }
971
972 *ext = talloc_zero(req, struct ldb_extended);
973 if (*ext == NULL) {
974 ret = LDB_ERR_OPERATIONS_ERROR;
975 goto done;
976 }
977 (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
978 (*ext)->data = talloc_steal(*ext, res);
979
980 ret = LDB_SUCCESS;
981
982 done:
983 talloc_free(tmp_ctx);
984 ltdb_unlock_read(module);
985 return ret;
986 }
987
988 static void ltdb_request_done(struct ltdb_context *ctx, int error)
/* [<][>][^][v][top][bottom][index][help] */
989 {
990 struct ldb_context *ldb;
991 struct ldb_request *req;
992 struct ldb_reply *ares;
993
994 ldb = ldb_module_get_ctx(ctx->module);
995 req = ctx->req;
996
997 /* if we already returned an error just return */
998 if (ldb_request_get_status(req) != LDB_SUCCESS) {
999 return;
1000 }
1001
1002 ares = talloc_zero(req, struct ldb_reply);
1003 if (!ares) {
1004 ldb_oom(ldb);
1005 req->callback(req, NULL);
1006 return;
1007 }
1008 ares->type = LDB_REPLY_DONE;
1009 ares->error = error;
1010
1011 req->callback(req, ares);
1012 }
1013
1014 static void ltdb_timeout(struct tevent_context *ev,
/* [<][>][^][v][top][bottom][index][help] */
1015 struct tevent_timer *te,
1016 struct timeval t,
1017 void *private_data)
1018 {
1019 struct ltdb_context *ctx;
1020 ctx = talloc_get_type(private_data, struct ltdb_context);
1021
1022 if (!ctx->request_terminated) {
1023 /* request is done now */
1024 ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED);
1025 }
1026
1027 if (!ctx->request_terminated) {
1028 /* neutralize the spy */
1029 ctx->spy->ctx = NULL;
1030 }
1031 talloc_free(ctx);
1032 }
1033
1034 static void ltdb_request_extended_done(struct ltdb_context *ctx,
/* [<][>][^][v][top][bottom][index][help] */
1035 struct ldb_extended *ext,
1036 int error)
1037 {
1038 struct ldb_context *ldb;
1039 struct ldb_request *req;
1040 struct ldb_reply *ares;
1041
1042 ldb = ldb_module_get_ctx(ctx->module);
1043 req = ctx->req;
1044
1045 /* if we already returned an error just return */
1046 if (ldb_request_get_status(req) != LDB_SUCCESS) {
1047 return;
1048 }
1049
1050 ares = talloc_zero(req, struct ldb_reply);
1051 if (!ares) {
1052 ldb_oom(ldb);
1053 req->callback(req, NULL);
1054 return;
1055 }
1056 ares->type = LDB_REPLY_DONE;
1057 ares->response = ext;
1058 ares->error = error;
1059
1060 req->callback(req, ares);
1061 }
1062
1063 static void ltdb_handle_extended(struct ltdb_context *ctx)
/* [<][>][^][v][top][bottom][index][help] */
1064 {
1065 struct ldb_extended *ext = NULL;
1066 int ret;
1067
1068 if (strcmp(ctx->req->op.extended.oid,
1069 LDB_EXTENDED_SEQUENCE_NUMBER) == 0) {
1070 /* get sequence number */
1071 ret = ltdb_sequence_number(ctx, &ext);
1072 } else {
1073 /* not recognized */
1074 ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1075 }
1076
1077 ltdb_request_extended_done(ctx, ext, ret);
1078 }
1079
1080 static void ltdb_callback(struct tevent_context *ev,
/* [<][>][^][v][top][bottom][index][help] */
1081 struct tevent_timer *te,
1082 struct timeval t,
1083 void *private_data)
1084 {
1085 struct ltdb_context *ctx;
1086 int ret;
1087
1088 ctx = talloc_get_type(private_data, struct ltdb_context);
1089
1090 if (ctx->request_terminated) {
1091 goto done;
1092 }
1093
1094 switch (ctx->req->operation) {
1095 case LDB_SEARCH:
1096 ret = ltdb_search(ctx);
1097 break;
1098 case LDB_ADD:
1099 ret = ltdb_add(ctx);
1100 break;
1101 case LDB_MODIFY:
1102 ret = ltdb_modify(ctx);
1103 break;
1104 case LDB_DELETE:
1105 ret = ltdb_delete(ctx);
1106 break;
1107 case LDB_RENAME:
1108 ret = ltdb_rename(ctx);
1109 break;
1110 case LDB_EXTENDED:
1111 ltdb_handle_extended(ctx);
1112 goto done;
1113 default:
1114 /* no other op supported */
1115 ret = LDB_ERR_UNWILLING_TO_PERFORM;
1116 }
1117
1118 if (!ctx->request_terminated) {
1119 /* request is done now */
1120 ltdb_request_done(ctx, ret);
1121 }
1122
1123 done:
1124 if (!ctx->request_terminated) {
1125 /* neutralize the spy */
1126 ctx->spy->ctx = NULL;
1127 }
1128 talloc_free(ctx);
1129 }
1130
1131 static int ltdb_request_destructor(void *ptr)
/* [<][>][^][v][top][bottom][index][help] */
1132 {
1133 struct ltdb_req_spy *spy = talloc_get_type(ptr, struct ltdb_req_spy);
1134
1135 if (spy->ctx != NULL) {
1136 spy->ctx->request_terminated = true;
1137 }
1138
1139 return 0;
1140 }
1141
1142 static int ltdb_handle_request(struct ldb_module *module,
/* [<][>][^][v][top][bottom][index][help] */
1143 struct ldb_request *req)
1144 {
1145 struct ldb_context *ldb;
1146 struct tevent_context *ev;
1147 struct ltdb_context *ac;
1148 struct tevent_timer *te;
1149 struct timeval tv;
1150
1151 if (check_critical_controls(req->controls)) {
1152 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1153 }
1154
1155 ldb = ldb_module_get_ctx(module);
1156
1157 if (req->starttime == 0 || req->timeout == 0) {
1158 ldb_set_errstring(ldb, "Invalid timeout settings");
1159 return LDB_ERR_TIME_LIMIT_EXCEEDED;
1160 }
1161
1162 ev = ldb_get_event_context(ldb);
1163
1164 ac = talloc_zero(ldb, struct ltdb_context);
1165 if (ac == NULL) {
1166 ldb_set_errstring(ldb, "Out of Memory");
1167 return LDB_ERR_OPERATIONS_ERROR;
1168 }
1169
1170 ac->module = module;
1171 ac->req = req;
1172
1173 tv.tv_sec = 0;
1174 tv.tv_usec = 0;
1175 te = tevent_add_timer(ev, ac, tv, ltdb_callback, ac);
1176 if (NULL == te) {
1177 talloc_free(ac);
1178 return LDB_ERR_OPERATIONS_ERROR;
1179 }
1180
1181 tv.tv_sec = req->starttime + req->timeout;
1182 ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac);
1183 if (NULL == ac->timeout_event) {
1184 talloc_free(ac);
1185 return LDB_ERR_OPERATIONS_ERROR;
1186 }
1187
1188 /* set a spy so that we do not try to use the request context
1189 * if it is freed before ltdb_callback fires */
1190 ac->spy = talloc(req, struct ltdb_req_spy);
1191 if (NULL == ac->spy) {
1192 talloc_free(ac);
1193 return LDB_ERR_OPERATIONS_ERROR;
1194 }
1195 ac->spy->ctx = ac;
1196
1197 talloc_set_destructor((TALLOC_CTX *)ac->spy, ltdb_request_destructor);
1198
1199 return LDB_SUCCESS;
1200 }
1201
1202 static const struct ldb_module_ops ltdb_ops = {
1203 .name = "tdb",
1204 .search = ltdb_handle_request,
1205 .add = ltdb_handle_request,
1206 .modify = ltdb_handle_request,
1207 .del = ltdb_handle_request,
1208 .rename = ltdb_handle_request,
1209 .extended = ltdb_handle_request,
1210 .start_transaction = ltdb_start_trans,
1211 .end_transaction = ltdb_end_trans,
1212 .del_transaction = ltdb_del_trans,
1213 };
1214
1215 /*
1216 connect to the database
1217 */
1218 static int ltdb_connect(struct ldb_context *ldb, const char *url,
/* [<][>][^][v][top][bottom][index][help] */
1219 unsigned int flags, const char *options[],
1220 struct ldb_module **_module)
1221 {
1222 struct ldb_module *module;
1223 const char *path;
1224 int tdb_flags, open_flags;
1225 struct ltdb_private *ltdb;
1226
1227 /* parse the url */
1228 if (strchr(url, ':')) {
1229 if (strncmp(url, "tdb://", 6) != 0) {
1230 ldb_debug(ldb, LDB_DEBUG_ERROR,
1231 "Invalid tdb URL '%s'", url);
1232 return -1;
1233 }
1234 path = url+6;
1235 } else {
1236 path = url;
1237 }
1238
1239 tdb_flags = TDB_DEFAULT | TDB_SEQNUM;
1240
1241 /* check for the 'nosync' option */
1242 if (flags & LDB_FLG_NOSYNC) {
1243 tdb_flags |= TDB_NOSYNC;
1244 }
1245
1246 /* and nommap option */
1247 if (flags & LDB_FLG_NOMMAP) {
1248 tdb_flags |= TDB_NOMMAP;
1249 }
1250
1251 if (flags & LDB_FLG_RDONLY) {
1252 open_flags = O_RDONLY;
1253 } else {
1254 open_flags = O_CREAT | O_RDWR;
1255 }
1256
1257 ltdb = talloc_zero(ldb, struct ltdb_private);
1258 if (!ltdb) {
1259 ldb_oom(ldb);
1260 return -1;
1261 }
1262
1263 /* note that we use quite a large default hash size */
1264 ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000,
1265 tdb_flags, open_flags,
1266 ldb_get_create_perms(ldb), ldb);
1267 if (!ltdb->tdb) {
1268 ldb_debug(ldb, LDB_DEBUG_ERROR,
1269 "Unable to open tdb '%s'\n", path);
1270 talloc_free(ltdb);
1271 return -1;
1272 }
1273
1274 ltdb->sequence_number = 0;
1275
1276 module = ldb_module_new(ldb, ldb, "ldb_tdb backend", <db_ops);
1277 if (!module) {
1278 talloc_free(ltdb);
1279 return -1;
1280 }
1281 ldb_module_set_private(module, ltdb);
1282
1283 if (ltdb_cache_load(module) != 0) {
1284 talloc_free(module);
1285 talloc_free(ltdb);
1286 return -1;
1287 }
1288
1289 *_module = module;
1290 return 0;
1291 }
1292
1293 const struct ldb_backend_ops ldb_tdb_backend_ops = {
1294 .name = "tdb",
1295 .connect_fn = ltdb_connect
1296 };