4
Copyright (C) Andrew Tridgell 2004
5
Copyright (C) Stefan Metzmacher 2004
6
Copyright (C) Simo Sorce 2006-2008
9
** NOTE! The following LGPL license applies to the ldb
10
** library. This does NOT imply that all of Samba is released
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.
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.
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/>.
30
* Component: ldb tdb backend
32
* Description: core functions for tdb backend
34
* Author: Andrew Tridgell
35
* Author: Stefan Metzmacher
39
* - description: make the module use asyncronous calls
43
* - description: make it possible to use event contexts
52
map a tdb error code to a ldb error code
54
static int ltdb_err_map(enum TDB_ERROR tdb_code)
62
return LDB_ERR_OPERATIONS_ERROR;
64
return LDB_ERR_PROTOCOL_ERROR;
68
case TDB_ERR_LOCK_TIMEOUT:
69
return LDB_ERR_TIME_LIMIT_EXCEEDED;
71
return LDB_ERR_ENTRY_ALREADY_EXISTS;
73
return LDB_ERR_NO_SUCH_OBJECT;
75
return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
81
lock the database for read - use by ltdb_search and ltdb_sequence_number
83
int ltdb_lock_read(struct ldb_module *module)
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);
94
unlock the database after a ltdb_lock_read()
96
int ltdb_unlock_read(struct ldb_module *module)
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);
108
form a TDB_DATA for a record key
111
note that the key for a record can depend on whether the
112
dn refers to a case sensitive index record or not
114
struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn)
116
struct ldb_context *ldb = ldb_module_get_ctx(module);
118
char *key_str = NULL;
119
const char *dn_folded = NULL;
122
most DNs are case insensitive. The exception is index DNs for
123
case sensitive attributes
125
there are 3 cases dealt with in this code:
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
133
dn_folded = ldb_dn_get_casefold(dn);
138
key_str = talloc_strdup(ldb, "DN=");
143
key_str = talloc_strdup_append_buffer(key_str, dn_folded);
148
key.dptr = (uint8_t *)key_str;
149
key.dsize = strlen(key_str) + 1;
161
check special dn's have valid attributes
162
currently only @ATTRIBUTES is checked
164
static int ltdb_check_special_dn(struct ldb_module *module,
165
const struct ldb_message *msg)
167
struct ldb_context *ldb = ldb_module_get_ctx(module);
170
if (! ldb_dn_is_special(msg->dn) ||
171
! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
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;
191
we've made a modification to a dn - possibly reindex and
192
update sequence number
194
static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
196
int ret = LDB_SUCCESS;
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);
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);
214
store a record into the db
216
int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
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;
223
tdb_key = ltdb_key(module, msg->dn);
225
return LDB_ERR_OTHER;
228
ret = ltdb_pack_data(module, msg, &tdb_data);
230
talloc_free(tdb_key.dptr);
231
return LDB_ERR_OTHER;
234
ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
236
ret = ltdb_err_map(tdb_error(ltdb->tdb));
240
ret = ltdb_index_add(module, msg);
241
if (ret != LDB_SUCCESS) {
242
tdb_delete(ltdb->tdb, tdb_key);
246
talloc_free(tdb_key.dptr);
247
talloc_free(tdb_data.dptr);
253
static int ltdb_add_internal(struct ldb_module *module,
254
const struct ldb_message *msg)
256
struct ldb_context *ldb = ldb_module_get_ctx(module);
259
ret = ltdb_check_special_dn(module, msg);
260
if (ret != LDB_SUCCESS) {
264
if (ltdb_cache_load(module) != 0) {
265
return LDB_ERR_OPERATIONS_ERROR;
268
ret = ltdb_store(module, msg, TDB_INSERT);
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));
277
if (ret == LDB_SUCCESS) {
278
ret = ltdb_index_one(module, msg, 1);
279
if (ret != LDB_SUCCESS) {
283
ret = ltdb_modified(module, msg->dn);
284
if (ret != LDB_SUCCESS) {
293
add a record to the database
295
static int ltdb_add(struct ltdb_context *ctx)
297
struct ldb_module *module = ctx->module;
298
struct ldb_request *req = ctx->req;
301
ldb_request_set_state(req, LDB_ASYNC_PENDING);
303
tret = ltdb_add_internal(module, req->op.add.message);
304
if (tret != LDB_SUCCESS) {
312
delete a record from the database, not updating indexes (used for deleting
315
int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn)
317
void *data = ldb_module_get_private(module);
318
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
322
tdb_key = ltdb_key(module, dn);
324
return LDB_ERR_OTHER;
327
ret = tdb_delete(ltdb->tdb, tdb_key);
328
talloc_free(tdb_key.dptr);
331
ret = ltdb_err_map(tdb_error(ltdb->tdb));
337
static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn)
339
struct ldb_message *msg;
342
msg = talloc(module, struct ldb_message);
344
return LDB_ERR_OPERATIONS_ERROR;
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 */
355
ret = ltdb_delete_noindex(module, dn);
356
if (ret != LDB_SUCCESS) {
360
/* remove one level attribute */
361
ret = ltdb_index_one(module, msg, 0);
362
if (ret != LDB_SUCCESS) {
366
/* remove any indexed attributes */
367
ret = ltdb_index_del(module, msg);
368
if (ret != LDB_SUCCESS) {
372
ret = ltdb_modified(module, dn);
373
if (ret != LDB_SUCCESS) {
383
delete a record from the database
385
static int ltdb_delete(struct ltdb_context *ctx)
387
struct ldb_module *module = ctx->module;
388
struct ldb_request *req = ctx->req;
391
ldb_request_set_state(req, LDB_ASYNC_PENDING);
393
if (ltdb_cache_load(module) != 0) {
394
return LDB_ERR_OPERATIONS_ERROR;
397
tret = ltdb_delete_internal(module, req->op.del.dn);
398
if (tret != LDB_SUCCESS) {
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
410
return the index of the first matching element if found, otherwise -1
412
static int find_element(const struct ldb_message *msg, const char *name)
415
for (i=0;i<msg->num_elements;i++) {
416
if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
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!
429
returns 0 on success, -1 on failure (and sets errno)
431
static int msg_add_element(struct ldb_context *ldb,
432
struct ldb_message *msg,
433
struct ldb_message_element *el)
435
struct ldb_message_element *e2;
438
e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
439
msg->num_elements+1);
447
e2 = &msg->elements[msg->num_elements];
450
e2->flags = el->flags;
452
if (el->num_values != 0) {
453
e2->values = talloc_array(msg->elements,
454
struct ldb_val, el->num_values);
460
for (i=0;i<el->num_values;i++) {
461
e2->values[i] = el->values[i];
463
e2->num_values = el->num_values;
471
delete all elements having a specified attribute name
473
static int msg_delete_attribute(struct ldb_module *module,
474
struct ldb_context *ldb,
475
struct ldb_message *msg, const char *name)
480
dn = ldb_dn_get_linearized(msg->dn);
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);
491
talloc_free(msg->elements[i].values);
492
if (msg->num_elements > (i+1)) {
493
memmove(&msg->elements[i],
495
sizeof(struct ldb_message_element)*
496
(msg->num_elements - (i+1)));
500
msg->elements = talloc_realloc(msg, msg->elements,
501
struct ldb_message_element,
510
delete all elements matching an attribute name/value
512
return 0 on success, -1 on failure
514
static int msg_delete_element(struct ldb_module *module,
515
struct ldb_message *msg,
517
const struct ldb_val *val)
519
struct ldb_context *ldb = ldb_module_get_ctx(module);
522
struct ldb_message_element *el;
523
const struct ldb_schema_attribute *a;
525
found = find_element(msg, name);
530
el = &msg->elements[found];
532
a = ldb_schema_attribute_by_name(ldb, el->name);
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)));
543
if (el->num_values == 0) {
544
return msg_delete_attribute(module, ldb,
556
modify a record - internal interface
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
562
int ltdb_modify_internal(struct ldb_module *module,
563
const struct ldb_message *msg)
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;
573
tdb_key = ltdb_key(module, msg->dn);
575
return LDB_ERR_OTHER;
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));
584
msg2 = talloc(tdb_key.dptr, struct ldb_message);
586
talloc_free(tdb_key.dptr);
587
return LDB_ERR_OTHER;
590
ret = ltdb_unpack_data(module, &tdb_data, msg2);
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;
606
switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
608
case LDB_FLAG_MOD_ADD:
609
/* add this element to the message. fail if it
611
idx = find_element(msg2, el->name);
614
if (msg_add_element(ldb, msg2, el) != 0) {
621
el2 = &msg2->elements[idx];
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). */
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;
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;
641
vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
642
el2->num_values + el->num_values);
649
for (j=0;j<el->num_values;j++) {
650
vals[el2->num_values + j] =
651
ldb_val_dup(vals, &el->values[j]);
655
el2->num_values += el->num_values;
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);
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;
672
/* add the replacement element, if not empty */
673
if (el->num_values != 0 &&
674
msg_add_element(ldb, msg2, el) != 0) {
680
case LDB_FLAG_MOD_DELETE:
682
dn = ldb_dn_get_linearized(msg->dn);
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;
699
for (j=0;j<msg->elements[i].num_values;j++) {
700
if (msg_delete_element(module,
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;
708
ret = ltdb_index_del_value(module, dn, &msg->elements[i], j);
709
if (ret != LDB_SUCCESS) {
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;
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) {
731
ret = ltdb_modified(module, msg->dn);
732
if (ret != LDB_SUCCESS) {
736
talloc_free(tdb_key.dptr);
741
talloc_free(tdb_key.dptr);
749
static int ltdb_modify(struct ltdb_context *ctx)
751
struct ldb_module *module = ctx->module;
752
struct ldb_request *req = ctx->req;
755
ldb_request_set_state(req, LDB_ASYNC_PENDING);
757
tret = ltdb_check_special_dn(module, req->op.mod.message);
758
if (tret != LDB_SUCCESS) {
762
if (ltdb_cache_load(module) != 0) {
763
return LDB_ERR_OPERATIONS_ERROR;
766
tret = ltdb_modify_internal(module, req->op.mod.message);
767
if (tret != LDB_SUCCESS) {
777
static int ltdb_rename(struct ltdb_context *ctx)
779
struct ldb_module *module = ctx->module;
780
struct ldb_request *req = ctx->req;
781
struct ldb_message *msg;
784
ldb_request_set_state(req, LDB_ASYNC_PENDING);
786
if (ltdb_cache_load(ctx->module) != 0) {
787
return LDB_ERR_OPERATIONS_ERROR;
790
msg = talloc(ctx, struct ldb_message);
792
return LDB_ERR_OPERATIONS_ERROR;
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 */
803
msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
805
return LDB_ERR_OPERATIONS_ERROR;
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.
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) {
821
tret = ltdb_add_internal(module, msg);
822
if (tret != LDB_SUCCESS) {
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) {
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;
844
static int ltdb_start_trans(struct ldb_module *module)
846
void *data = ldb_module_get_private(module);
847
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
849
if (tdb_transaction_start(ltdb->tdb) != 0) {
850
return ltdb_err_map(tdb_error(ltdb->tdb));
853
ltdb->in_transaction++;
855
ltdb_index_transaction_start(module);
860
static int ltdb_end_trans(struct ldb_module *module)
862
void *data = ldb_module_get_private(module);
863
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
865
ltdb->in_transaction--;
867
if (ltdb_index_transaction_commit(module) != 0) {
868
tdb_transaction_cancel(ltdb->tdb);
869
return ltdb_err_map(tdb_error(ltdb->tdb));
872
if (tdb_transaction_commit(ltdb->tdb) != 0) {
873
return ltdb_err_map(tdb_error(ltdb->tdb));
879
static int ltdb_del_trans(struct ldb_module *module)
881
void *data = ldb_module_get_private(module);
882
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
884
ltdb->in_transaction--;
886
if (ltdb_index_transaction_cancel(module) != 0) {
887
tdb_transaction_cancel(ltdb->tdb);
888
return ltdb_err_map(tdb_error(ltdb->tdb));
891
if (tdb_transaction_cancel(ltdb->tdb) != 0) {
892
return ltdb_err_map(tdb_error(ltdb->tdb));
899
return sequenceNumber from @BASEINFO
901
static int ltdb_sequence_number(struct ltdb_context *ctx,
902
struct ldb_extended **ext)
904
struct ldb_context *ldb;
905
struct ldb_module *module = ctx->module;
906
struct ldb_request *req = ctx->req;
908
struct ldb_seqnum_request *seq;
909
struct ldb_seqnum_result *res;
910
struct ldb_message *msg = NULL;
915
ldb = ldb_module_get_ctx(module);
917
seq = talloc_get_type(req->op.extended.data,
918
struct ldb_seqnum_request);
920
return LDB_ERR_OPERATIONS_ERROR;
923
ldb_request_set_state(req, LDB_ASYNC_PENDING);
925
if (ltdb_lock_read(module) != 0) {
926
return LDB_ERR_OPERATIONS_ERROR;
929
res = talloc_zero(req, struct ldb_seqnum_result);
931
ret = LDB_ERR_OPERATIONS_ERROR;
934
tmp_ctx = talloc_new(req);
935
if (tmp_ctx == NULL) {
936
ret = LDB_ERR_OPERATIONS_ERROR;
940
dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO);
942
msg = talloc(tmp_ctx, struct ldb_message);
944
ret = LDB_ERR_OPERATIONS_ERROR;
948
ret = ltdb_search_dn1(module, dn, msg);
949
if (ret != LDB_SUCCESS) {
954
case LDB_SEQ_HIGHEST_SEQ:
955
res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
958
res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
961
case LDB_SEQ_HIGHEST_TIMESTAMP:
962
date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
964
res->seq_num = ldb_string_to_time(date);
967
/* zero is as good as anything when we don't know */
972
*ext = talloc_zero(req, struct ldb_extended);
974
ret = LDB_ERR_OPERATIONS_ERROR;
977
(*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
978
(*ext)->data = talloc_steal(*ext, res);
983
talloc_free(tmp_ctx);
984
ltdb_unlock_read(module);
988
static void ltdb_request_done(struct ltdb_context *ctx, int error)
990
struct ldb_context *ldb;
991
struct ldb_request *req;
992
struct ldb_reply *ares;
994
ldb = ldb_module_get_ctx(ctx->module);
997
/* if we already returned an error just return */
998
if (ldb_request_get_status(req) != LDB_SUCCESS) {
1002
ares = talloc_zero(req, struct ldb_reply);
1005
req->callback(req, NULL);
1008
ares->type = LDB_REPLY_DONE;
1009
ares->error = error;
1011
req->callback(req, ares);
1014
static void ltdb_timeout(struct tevent_context *ev,
1015
struct tevent_timer *te,
1019
struct ltdb_context *ctx;
1020
ctx = talloc_get_type(private_data, struct ltdb_context);
1022
if (!ctx->request_terminated) {
1023
/* request is done now */
1024
ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED);
1027
if (!ctx->request_terminated) {
1028
/* neutralize the spy */
1029
ctx->spy->ctx = NULL;
1034
static void ltdb_request_extended_done(struct ltdb_context *ctx,
1035
struct ldb_extended *ext,
1038
struct ldb_context *ldb;
1039
struct ldb_request *req;
1040
struct ldb_reply *ares;
1042
ldb = ldb_module_get_ctx(ctx->module);
1045
/* if we already returned an error just return */
1046
if (ldb_request_get_status(req) != LDB_SUCCESS) {
1050
ares = talloc_zero(req, struct ldb_reply);
1053
req->callback(req, NULL);
1056
ares->type = LDB_REPLY_DONE;
1057
ares->response = ext;
1058
ares->error = error;
1060
req->callback(req, ares);
1063
static void ltdb_handle_extended(struct ltdb_context *ctx)
1065
struct ldb_extended *ext = NULL;
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);
1073
/* not recognized */
1074
ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1077
ltdb_request_extended_done(ctx, ext, ret);
1080
static void ltdb_callback(struct tevent_context *ev,
1081
struct tevent_timer *te,
1085
struct ltdb_context *ctx;
1088
ctx = talloc_get_type(private_data, struct ltdb_context);
1090
if (ctx->request_terminated) {
1094
switch (ctx->req->operation) {
1096
ret = ltdb_search(ctx);
1099
ret = ltdb_add(ctx);
1102
ret = ltdb_modify(ctx);
1105
ret = ltdb_delete(ctx);
1108
ret = ltdb_rename(ctx);
1111
ltdb_handle_extended(ctx);
1114
/* no other op supported */
1115
ret = LDB_ERR_UNWILLING_TO_PERFORM;
1118
if (!ctx->request_terminated) {
1119
/* request is done now */
1120
ltdb_request_done(ctx, ret);
1124
if (!ctx->request_terminated) {
1125
/* neutralize the spy */
1126
ctx->spy->ctx = NULL;
1131
static int ltdb_request_destructor(void *ptr)
1133
struct ltdb_req_spy *spy = talloc_get_type(ptr, struct ltdb_req_spy);
1135
if (spy->ctx != NULL) {
1136
spy->ctx->request_terminated = true;
1142
static int ltdb_handle_request(struct ldb_module *module,
1143
struct ldb_request *req)
1145
struct ldb_context *ldb;
1146
struct tevent_context *ev;
1147
struct ltdb_context *ac;
1148
struct tevent_timer *te;
1151
if (check_critical_controls(req->controls)) {
1152
return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1155
ldb = ldb_module_get_ctx(module);
1157
if (req->starttime == 0 || req->timeout == 0) {
1158
ldb_set_errstring(ldb, "Invalid timeout settings");
1159
return LDB_ERR_TIME_LIMIT_EXCEEDED;
1162
ev = ldb_get_event_context(ldb);
1164
ac = talloc_zero(ldb, struct ltdb_context);
1166
ldb_set_errstring(ldb, "Out of Memory");
1167
return LDB_ERR_OPERATIONS_ERROR;
1170
ac->module = module;
1175
te = tevent_add_timer(ev, ac, tv, ltdb_callback, ac);
1178
return LDB_ERR_OPERATIONS_ERROR;
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) {
1185
return LDB_ERR_OPERATIONS_ERROR;
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) {
1193
return LDB_ERR_OPERATIONS_ERROR;
1197
talloc_set_destructor((TALLOC_CTX *)ac->spy, ltdb_request_destructor);
1202
static const struct ldb_module_ops ltdb_ops = {
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,
1216
connect to the database
1218
static int ltdb_connect(struct ldb_context *ldb, const char *url,
1219
unsigned int flags, const char *options[],
1220
struct ldb_module **_module)
1222
struct ldb_module *module;
1224
int tdb_flags, open_flags;
1225
struct ltdb_private *ltdb;
1228
if (strchr(url, ':')) {
1229
if (strncmp(url, "tdb://", 6) != 0) {
1230
ldb_debug(ldb, LDB_DEBUG_ERROR,
1231
"Invalid tdb URL '%s'", url);
1239
tdb_flags = TDB_DEFAULT | TDB_SEQNUM;
1241
/* check for the 'nosync' option */
1242
if (flags & LDB_FLG_NOSYNC) {
1243
tdb_flags |= TDB_NOSYNC;
1246
/* and nommap option */
1247
if (flags & LDB_FLG_NOMMAP) {
1248
tdb_flags |= TDB_NOMMAP;
1251
if (flags & LDB_FLG_RDONLY) {
1252
open_flags = O_RDONLY;
1254
open_flags = O_CREAT | O_RDWR;
1257
ltdb = talloc_zero(ldb, struct ltdb_private);
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);
1268
ldb_debug(ldb, LDB_DEBUG_ERROR,
1269
"Unable to open tdb '%s'\n", path);
1274
ltdb->sequence_number = 0;
1276
module = ldb_module_new(ldb, ldb, "ldb_tdb backend", <db_ops);
1281
ldb_module_set_private(module, ltdb);
1283
if (ltdb_cache_load(module) != 0) {
1284
talloc_free(module);
1293
const struct ldb_backend_ops ldb_tdb_backend_ops = {
1295
.connect_fn = ltdb_connect