Line data Source code
1 : /*
2 : ldb database library
3 :
4 : Copyright (C) Andrew Tridgell 2004
5 :
6 : ** NOTE! The following LGPL license applies to the ldb
7 : ** library. This does NOT imply that all of Samba is released
8 : ** under the LGPL
9 :
10 : This library is free software; you can redistribute it and/or
11 : modify it under the terms of the GNU Lesser General Public
12 : License as published by the Free Software Foundation; either
13 : version 3 of the License, or (at your option) any later version.
14 :
15 : This library is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 : Lesser General Public License for more details.
19 :
20 : You should have received a copy of the GNU Lesser General Public
21 : License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : /*
25 : * Name: ldb
26 : *
27 : * Component: ldb key value cache functions
28 : *
29 : * Description: cache special records in a ldb/tdb
30 : *
31 : * Author: Andrew Tridgell
32 : */
33 :
34 : #include "ldb_kv.h"
35 : #include "ldb_private.h"
36 :
37 : #define LDB_KV_FLAG_CASE_INSENSITIVE (1<<0)
38 : #define LDB_KV_FLAG_INTEGER (1<<1)
39 : #define LDB_KV_FLAG_UNIQUE_INDEX (1<<2)
40 : #define LDB_KV_FLAG_ORDERED_INTEGER (1<<3)
41 :
42 : /* valid attribute flags */
43 : static const struct {
44 : const char *name;
45 : int value;
46 : } ldb_kv_valid_attr_flags[] = {
47 : { "CASE_INSENSITIVE", LDB_KV_FLAG_CASE_INSENSITIVE },
48 : { "INTEGER", LDB_KV_FLAG_INTEGER },
49 : { "ORDERED_INTEGER", LDB_KV_FLAG_ORDERED_INTEGER },
50 : { "HIDDEN", 0 },
51 : { "UNIQUE_INDEX", LDB_KV_FLAG_UNIQUE_INDEX},
52 : { "NONE", 0 },
53 : { NULL, 0 }
54 : };
55 :
56 : /*
57 : de-register any special handlers for @ATTRIBUTES
58 : */
59 808788 : static void ldb_kv_attributes_unload(struct ldb_module *module)
60 : {
61 808788 : struct ldb_context *ldb = ldb_module_get_ctx(module);
62 :
63 808788 : ldb_schema_attribute_remove_flagged(ldb, LDB_ATTR_FLAG_FROM_DB);
64 :
65 808788 : }
66 :
67 : /*
68 : add up the attrib flags for a @ATTRIBUTES element
69 : */
70 13628658 : static int ldb_kv_attributes_flags(struct ldb_message_element *el, unsigned *v)
71 : {
72 : unsigned int i;
73 13628658 : unsigned value = 0;
74 27257316 : for (i=0;i<el->num_values;i++) {
75 : unsigned int j;
76 17555142 : for (j = 0; ldb_kv_valid_attr_flags[j].name; j++) {
77 17555142 : if (strcmp(ldb_kv_valid_attr_flags[j].name,
78 17555142 : (char *)el->values[i].data) == 0) {
79 13628658 : value |= ldb_kv_valid_attr_flags[j].value;
80 13628658 : break;
81 : }
82 : }
83 13628658 : if (ldb_kv_valid_attr_flags[j].name == NULL) {
84 0 : return -1;
85 : }
86 : }
87 13628658 : *v = value;
88 13628658 : return 0;
89 : }
90 :
91 95844792 : static int ldb_schema_attribute_compare(const void *p1, const void *p2)
92 : {
93 95844792 : const struct ldb_schema_attribute *sa1 = (const struct ldb_schema_attribute *)p1;
94 95844792 : const struct ldb_schema_attribute *sa2 = (const struct ldb_schema_attribute *)p2;
95 95844792 : return ldb_attr_cmp(sa1->name, sa2->name);
96 : }
97 :
98 : /*
99 : register any special handlers from @ATTRIBUTES
100 : */
101 796812 : static int ldb_kv_attributes_load(struct ldb_module *module)
102 : {
103 : struct ldb_schema_attribute *attrs;
104 : struct ldb_context *ldb;
105 796812 : struct ldb_message *attrs_msg = NULL;
106 : struct ldb_dn *dn;
107 : unsigned int i;
108 796812 : unsigned int num_loaded_attrs = 0;
109 : int r;
110 :
111 796812 : ldb = ldb_module_get_ctx(module);
112 :
113 796812 : if (ldb->schema.attribute_handler_override) {
114 : /* we skip loading the @ATTRIBUTES record when a module is supplying
115 : its own attribute handling */
116 683197 : return 0;
117 : }
118 :
119 113615 : attrs_msg = ldb_msg_new(module);
120 113615 : if (attrs_msg == NULL) {
121 0 : goto failed;
122 : }
123 :
124 113615 : dn = ldb_dn_new(module, ldb, LDB_KV_ATTRIBUTES);
125 113615 : if (dn == NULL) goto failed;
126 :
127 113615 : r = ldb_kv_search_dn1(module,
128 : dn,
129 : attrs_msg,
130 : LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC |
131 : LDB_UNPACK_DATA_FLAG_NO_DN);
132 113615 : talloc_free(dn);
133 113615 : if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
134 0 : goto failed;
135 : }
136 113615 : if (r == LDB_ERR_NO_SUCH_OBJECT || attrs_msg->num_elements == 0) {
137 7882 : TALLOC_FREE(attrs_msg);
138 7882 : return 0;
139 : }
140 :
141 105733 : attrs = talloc_array(attrs_msg,
142 : struct ldb_schema_attribute,
143 : attrs_msg->num_elements
144 : + ldb->schema.num_attributes);
145 105733 : if (attrs == NULL) {
146 0 : goto failed;
147 : }
148 :
149 191622 : memcpy(attrs,
150 105733 : ldb->schema.attributes,
151 105733 : sizeof(ldb->schema.attributes[0]) * ldb->schema.num_attributes);
152 :
153 : /* mapping these flags onto ldap 'syntaxes' isn't strictly correct,
154 : but its close enough for now */
155 13820895 : for (i=0;i<attrs_msg->num_elements;i++) {
156 13715162 : unsigned flags = 0, attr_flags = 0;
157 : const char *syntax;
158 : const struct ldb_schema_syntax *s;
159 12183831 : const struct ldb_schema_attribute *a =
160 13715162 : ldb_schema_attribute_by_name(ldb,
161 13715162 : attrs_msg->elements[i].name);
162 13715162 : if (a != NULL && a->flags & LDB_ATTR_FLAG_FIXED) {
163 : /* Must already be set in the array, and kept */
164 86504 : continue;
165 : }
166 :
167 13628658 : if (ldb_kv_attributes_flags(&attrs_msg->elements[i], &flags) !=
168 : 0) {
169 0 : ldb_debug(ldb, LDB_DEBUG_ERROR,
170 : "Invalid @ATTRIBUTES element for '%s'",
171 0 : attrs_msg->elements[i].name);
172 0 : goto failed;
173 : }
174 :
175 13628658 : if (flags & LDB_KV_FLAG_UNIQUE_INDEX) {
176 410 : attr_flags = LDB_ATTR_FLAG_UNIQUE_INDEX;
177 : }
178 13628658 : flags &= ~LDB_KV_FLAG_UNIQUE_INDEX;
179 :
180 : /* These are not currently flags, each is exclusive */
181 13628658 : if (flags == LDB_KV_FLAG_CASE_INSENSITIVE) {
182 11663054 : syntax = LDB_SYNTAX_DIRECTORY_STRING;
183 1965604 : } else if (flags == LDB_KV_FLAG_INTEGER) {
184 5595 : syntax = LDB_SYNTAX_INTEGER;
185 1960009 : } else if (flags == LDB_KV_FLAG_ORDERED_INTEGER) {
186 1959574 : syntax = LDB_SYNTAX_ORDERED_INTEGER;
187 435 : } else if (flags == 0) {
188 435 : syntax = LDB_SYNTAX_OCTET_STRING;
189 : } else {
190 0 : ldb_debug(ldb, LDB_DEBUG_ERROR,
191 : "Invalid flag combination 0x%x for '%s' "
192 : "in @ATTRIBUTES",
193 0 : flags, attrs_msg->elements[i].name);
194 0 : goto failed;
195 : }
196 :
197 13628658 : s = ldb_standard_syntax_by_name(ldb, syntax);
198 13628658 : if (s == NULL) {
199 0 : ldb_debug(ldb, LDB_DEBUG_ERROR,
200 : "Invalid attribute syntax '%s' for '%s' "
201 : "in @ATTRIBUTES",
202 0 : syntax, attrs_msg->elements[i].name);
203 0 : goto failed;
204 : }
205 :
206 13628658 : attr_flags |= LDB_ATTR_FLAG_ALLOCATED | LDB_ATTR_FLAG_FROM_DB;
207 :
208 25735745 : r = ldb_schema_attribute_fill_with_syntax(ldb,
209 : attrs,
210 13628658 : attrs_msg->elements[i].name,
211 : attr_flags, s,
212 13628658 : &attrs[num_loaded_attrs + ldb->schema.num_attributes]);
213 13628658 : if (r != 0) {
214 0 : goto failed;
215 : }
216 13628658 : num_loaded_attrs++;
217 : }
218 :
219 105733 : attrs = talloc_realloc(attrs_msg,
220 : attrs, struct ldb_schema_attribute,
221 : num_loaded_attrs + ldb->schema.num_attributes);
222 105733 : if (attrs == NULL) {
223 0 : goto failed;
224 : }
225 105733 : TYPESAFE_QSORT(attrs, num_loaded_attrs + ldb->schema.num_attributes,
226 : ldb_schema_attribute_compare);
227 105733 : talloc_unlink(ldb, ldb->schema.attributes);
228 105733 : ldb->schema.attributes = talloc_steal(ldb, attrs);
229 105733 : ldb->schema.num_attributes = num_loaded_attrs + ldb->schema.num_attributes;
230 105733 : TALLOC_FREE(attrs_msg);
231 :
232 105733 : return 0;
233 0 : failed:
234 0 : TALLOC_FREE(attrs_msg);
235 0 : return -1;
236 : }
237 :
238 : /*
239 : register any index records we find for the DB
240 : */
241 796812 : static int ldb_kv_index_load(struct ldb_module *module,
242 : struct ldb_kv_private *ldb_kv)
243 : {
244 796812 : struct ldb_context *ldb = ldb_module_get_ctx(module);
245 : struct ldb_dn *indexlist_dn;
246 : int r, lmdb_subdb_version;
247 :
248 796812 : if (ldb->schema.index_handler_override) {
249 : /*
250 : * we skip loading the @INDEXLIST record when a module is
251 : * supplying its own attribute handling
252 : */
253 683177 : ldb_kv->cache->attribute_indexes = true;
254 1211126 : ldb_kv->cache->one_level_indexes =
255 683177 : ldb->schema.one_level_indexes;
256 1211126 : ldb_kv->cache->GUID_index_attribute =
257 683177 : ldb->schema.GUID_index_attribute;
258 1211126 : ldb_kv->cache->GUID_index_dn_component =
259 683177 : ldb->schema.GUID_index_dn_component;
260 683177 : return 0;
261 : }
262 :
263 113635 : talloc_free(ldb_kv->cache->indexlist);
264 :
265 113635 : ldb_kv->cache->indexlist = ldb_msg_new(ldb_kv->cache);
266 113635 : if (ldb_kv->cache->indexlist == NULL) {
267 0 : return -1;
268 : }
269 113635 : ldb_kv->cache->one_level_indexes = false;
270 113635 : ldb_kv->cache->attribute_indexes = false;
271 :
272 113635 : indexlist_dn = ldb_dn_new(ldb_kv, ldb, LDB_KV_INDEXLIST);
273 113635 : if (indexlist_dn == NULL) {
274 0 : return -1;
275 : }
276 :
277 113635 : r = ldb_kv_search_dn1(module,
278 : indexlist_dn,
279 113635 : ldb_kv->cache->indexlist,
280 : LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC |
281 : LDB_UNPACK_DATA_FLAG_NO_DN);
282 113635 : TALLOC_FREE(indexlist_dn);
283 :
284 113635 : if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
285 0 : return -1;
286 : }
287 :
288 113635 : if (ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXONE) !=
289 : NULL) {
290 23816 : ldb_kv->cache->one_level_indexes = true;
291 : }
292 113635 : if (ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXATTR) !=
293 : NULL) {
294 107710 : ldb_kv->cache->attribute_indexes = true;
295 : }
296 134535 : ldb_kv->cache->GUID_index_attribute = ldb_msg_find_attr_as_string(
297 113635 : ldb_kv->cache->indexlist, LDB_KV_IDXGUID, NULL);
298 134535 : ldb_kv->cache->GUID_index_dn_component = ldb_msg_find_attr_as_string(
299 113635 : ldb_kv->cache->indexlist, LDB_KV_IDX_DN_GUID, NULL);
300 :
301 113635 : lmdb_subdb_version = ldb_msg_find_attr_as_int(
302 113635 : ldb_kv->cache->indexlist, LDB_KV_IDX_LMDB_SUBDB, 0);
303 :
304 113635 : if (lmdb_subdb_version != 0) {
305 0 : ldb_set_errstring(ldb,
306 : "FATAL: This ldb_mdb database has "
307 : "been written in a new version of LDB "
308 : "using a sub-database index that "
309 : "is not understood by ldb "
310 : LDB_VERSION);
311 0 : return -1;
312 : }
313 :
314 113635 : return 0;
315 : }
316 :
317 : /*
318 : initialise the baseinfo record
319 : */
320 5510 : static int ldb_kv_baseinfo_init(struct ldb_module *module)
321 : {
322 : struct ldb_context *ldb;
323 5510 : void *data = ldb_module_get_private(module);
324 5292 : struct ldb_kv_private *ldb_kv =
325 218 : talloc_get_type(data, struct ldb_kv_private);
326 : struct ldb_message *msg;
327 : struct ldb_message_element el;
328 : struct ldb_val val;
329 : int ret;
330 : /* the initial sequence number must be different from the one
331 : set in ltdb_cache_free(). Thanks to Jon for pointing this
332 : out. */
333 5510 : const char *initial_sequence_number = "1";
334 :
335 5510 : ldb = ldb_module_get_ctx(module);
336 :
337 5510 : ldb_kv->sequence_number = atof(initial_sequence_number);
338 :
339 5510 : msg = ldb_msg_new(ldb_kv);
340 5510 : if (msg == NULL) {
341 0 : goto failed;
342 : }
343 :
344 5510 : msg->num_elements = 1;
345 5510 : msg->elements = ⪙
346 5510 : msg->dn = ldb_dn_new(msg, ldb, LDB_KV_BASEINFO);
347 5510 : if (!msg->dn) {
348 0 : goto failed;
349 : }
350 5510 : el.name = talloc_strdup(msg, LDB_KV_SEQUENCE_NUMBER);
351 5510 : if (!el.name) {
352 0 : goto failed;
353 : }
354 5510 : el.values = &val;
355 5510 : el.num_values = 1;
356 5510 : el.flags = 0;
357 5510 : val.data = (uint8_t *)talloc_strdup(msg, initial_sequence_number);
358 5510 : if (!val.data) {
359 0 : goto failed;
360 : }
361 5510 : val.length = 1;
362 :
363 5510 : ret = ldb_kv_store(module, msg, TDB_INSERT);
364 :
365 5510 : talloc_free(msg);
366 :
367 5510 : return ret;
368 :
369 0 : failed:
370 0 : talloc_free(msg);
371 0 : errno = ENOMEM;
372 0 : return LDB_ERR_OPERATIONS_ERROR;
373 : }
374 :
375 : /*
376 : free any cache records
377 : */
378 11976 : static void ldb_kv_cache_free(struct ldb_module *module)
379 : {
380 11976 : void *data = ldb_module_get_private(module);
381 11450 : struct ldb_kv_private *ldb_kv =
382 526 : talloc_get_type(data, struct ldb_kv_private);
383 :
384 11976 : ldb_kv->sequence_number = 0;
385 11976 : talloc_free(ldb_kv->cache);
386 11976 : ldb_kv->cache = NULL;
387 11976 : }
388 :
389 : /*
390 : force a cache reload
391 : */
392 11976 : int ldb_kv_cache_reload(struct ldb_module *module)
393 : {
394 11976 : ldb_kv_attributes_unload(module);
395 11976 : ldb_kv_cache_free(module);
396 11976 : return ldb_kv_cache_load(module);
397 : }
398 25900467 : static int get_pack_format_version(struct ldb_val key,
399 : struct ldb_val data,
400 : void *private_data)
401 : {
402 25900467 : uint32_t *v = (uint32_t *) private_data;
403 25900467 : return ldb_unpack_get_format(&data, v);
404 : }
405 :
406 : /*
407 : load the cache records
408 : */
409 85480029 : int ldb_kv_cache_load(struct ldb_module *module)
410 : {
411 : struct ldb_context *ldb;
412 85480029 : void *data = ldb_module_get_private(module);
413 73549341 : struct ldb_kv_private *ldb_kv =
414 11930688 : talloc_get_type(data, struct ldb_kv_private);
415 85480029 : struct ldb_dn *baseinfo_dn = NULL, *options_dn = NULL;
416 : uint64_t seq;
417 85480029 : struct ldb_message *baseinfo = NULL, *options = NULL;
418 : const struct ldb_schema_attribute *a;
419 85480029 : bool have_write_txn = false;
420 : int r;
421 : struct ldb_val key;
422 :
423 85480029 : ldb = ldb_module_get_ctx(module);
424 :
425 : /* a very fast check to avoid extra database reads */
426 85480029 : if (ldb_kv->cache != NULL && !ldb_kv->kv_ops->has_changed(ldb_kv)) {
427 59574052 : return 0;
428 : }
429 :
430 25905977 : if (ldb_kv->cache == NULL) {
431 719158 : ldb_kv->cache = talloc_zero(ldb_kv, struct ldb_kv_cache);
432 719158 : if (ldb_kv->cache == NULL)
433 0 : goto failed;
434 : }
435 :
436 25905977 : baseinfo = ldb_msg_new(ldb_kv->cache);
437 25905977 : if (baseinfo == NULL) goto failed;
438 :
439 25905977 : baseinfo_dn = ldb_dn_new(baseinfo, ldb, LDB_KV_BASEINFO);
440 25905977 : if (baseinfo_dn == NULL) goto failed;
441 :
442 25905977 : r = ldb_kv->kv_ops->lock_read(module);
443 25905977 : if (r != LDB_SUCCESS) {
444 0 : goto failed;
445 : }
446 :
447 25905977 : key = ldb_kv_key_dn(baseinfo, baseinfo_dn);
448 25905977 : if (!key.data) {
449 0 : goto failed_and_unlock;
450 : }
451 :
452 : /* Read packing format from first 4 bytes of @BASEINFO record */
453 51212877 : r = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key,
454 : get_pack_format_version,
455 25905977 : &ldb_kv->pack_format_version);
456 :
457 : /* possibly initialise the baseinfo */
458 25905977 : if (r == LDB_ERR_NO_SUCH_OBJECT) {
459 :
460 : /* Give up the read lock, try again with a write lock */
461 5510 : r = ldb_kv->kv_ops->unlock_read(module);
462 5510 : if (r != LDB_SUCCESS) {
463 0 : goto failed;
464 : }
465 :
466 5510 : if (ldb_kv->kv_ops->begin_write(ldb_kv) != 0) {
467 0 : goto failed;
468 : }
469 :
470 5510 : have_write_txn = true;
471 :
472 : /*
473 : * We need to write but haven't figured out packing format yet.
474 : * Just go with version 1 and we'll repack if we got it wrong.
475 : */
476 5510 : ldb_kv->pack_format_version = LDB_PACKING_FORMAT;
477 5510 : ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT;
478 :
479 : /* error handling for ltdb_baseinfo_init() is by
480 : looking for the record again. */
481 5510 : ldb_kv_baseinfo_init(module);
482 :
483 25900467 : } else if (r != LDB_SUCCESS) {
484 0 : goto failed_and_unlock;
485 : }
486 :
487 : /* OK now we definitely have a @BASEINFO record so fetch it */
488 25905977 : r = ldb_kv_search_dn1(module, baseinfo_dn, baseinfo, 0);
489 25905977 : if (r != LDB_SUCCESS) {
490 0 : goto failed_and_unlock;
491 : }
492 :
493 : /* Ignore the result, and update the sequence number */
494 25905977 : ldb_kv->kv_ops->has_changed(ldb_kv);
495 :
496 : /* if the current internal sequence number is the same as the one
497 : in the database then assume the rest of the cache is OK */
498 25905977 : seq = ldb_msg_find_attr_as_uint64(baseinfo, LDB_KV_SEQUENCE_NUMBER, 0);
499 25905977 : if (seq == ldb_kv->sequence_number) {
500 25109165 : goto done;
501 : }
502 796812 : ldb_kv->sequence_number = seq;
503 :
504 : /* Read an interpret database options */
505 :
506 796812 : options = ldb_msg_new(ldb_kv->cache);
507 796812 : if (options == NULL) goto failed_and_unlock;
508 :
509 796812 : options_dn = ldb_dn_new(options, ldb, LDB_KV_OPTIONS);
510 796812 : if (options_dn == NULL) goto failed_and_unlock;
511 :
512 796812 : r = ldb_kv_search_dn1(module, options_dn, options, 0);
513 796812 : talloc_free(options_dn);
514 796812 : if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
515 0 : goto failed_and_unlock;
516 : }
517 :
518 : /* set flags if they do exist */
519 796812 : if (r == LDB_SUCCESS) {
520 704967 : ldb_kv->check_base =
521 704967 : ldb_msg_find_attr_as_bool(options, LDB_KV_CHECK_BASE, false);
522 704967 : ldb_kv->disallow_dn_filter = ldb_msg_find_attr_as_bool(
523 : options, LDB_KV_DISALLOW_DN_FILTER, false);
524 : } else {
525 91845 : ldb_kv->check_base = false;
526 91845 : ldb_kv->disallow_dn_filter = false;
527 : }
528 :
529 : /*
530 : * ltdb_attributes_unload() calls internally talloc_free() on
531 : * any non-fixed elemnts in ldb->schema.attributes.
532 : *
533 : * NOTE WELL: This is per-ldb, not per module, so overwrites
534 : * the handlers across all databases when used under Samba's
535 : * partition module.
536 : */
537 796812 : ldb_kv_attributes_unload(module);
538 :
539 796812 : if (ldb_kv_index_load(module, ldb_kv) == -1) {
540 0 : goto failed_and_unlock;
541 : }
542 :
543 : /*
544 : * NOTE WELL: This is per-ldb, not per module, so overwrites
545 : * the handlers across all databases when used under Samba's
546 : * partition module.
547 : */
548 796812 : if (ldb_kv_attributes_load(module) == -1) {
549 0 : goto failed_and_unlock;
550 : }
551 :
552 : /*
553 : * Initialise packing version and GUID index syntax, and force the
554 : * two to travel together, ie a GUID indexed database must use V2
555 : * packing format and a DN indexed database must use V1.
556 : */
557 796812 : ldb_kv->GUID_index_syntax = NULL;
558 796812 : if (ldb_kv->cache->GUID_index_attribute != NULL) {
559 708385 : ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT_V2;
560 :
561 : /*
562 : * Now the attributes are loaded, set the guid_index_syntax.
563 : * This can't fail, it will return a default at worst
564 : */
565 708385 : a = ldb_schema_attribute_by_name(
566 708385 : ldb, ldb_kv->cache->GUID_index_attribute);
567 708385 : ldb_kv->GUID_index_syntax = a->syntax;
568 : } else {
569 88427 : ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT;
570 : }
571 :
572 25905977 : done:
573 25905977 : if (have_write_txn) {
574 5510 : if (ldb_kv->kv_ops->finish_write(ldb_kv) != 0) {
575 0 : goto failed;
576 : }
577 : } else {
578 25900467 : ldb_kv->kv_ops->unlock_read(module);
579 : }
580 :
581 25905977 : talloc_free(options);
582 25905977 : talloc_free(baseinfo);
583 25905977 : return 0;
584 :
585 0 : failed_and_unlock:
586 0 : if (have_write_txn) {
587 0 : ldb_kv->kv_ops->abort_write(ldb_kv);
588 : } else {
589 0 : ldb_kv->kv_ops->unlock_read(module);
590 : }
591 :
592 0 : failed:
593 0 : talloc_free(options);
594 0 : talloc_free(baseinfo);
595 0 : return -1;
596 : }
597 :
598 :
599 : /*
600 : increase the sequence number to indicate a database change
601 : */
602 1693811 : int ldb_kv_increase_sequence_number(struct ldb_module *module)
603 : {
604 : struct ldb_context *ldb;
605 1693811 : void *data = ldb_module_get_private(module);
606 1457145 : struct ldb_kv_private *ldb_kv =
607 236666 : talloc_get_type(data, struct ldb_kv_private);
608 : struct ldb_message *msg;
609 : struct ldb_message_element el[2];
610 : struct ldb_val val;
611 : struct ldb_val val_time;
612 1693811 : time_t t = time(NULL);
613 1693811 : char *s = NULL;
614 : int ret;
615 :
616 1693811 : ldb = ldb_module_get_ctx(module);
617 :
618 1693811 : msg = ldb_msg_new(ldb_kv);
619 1693811 : if (msg == NULL) {
620 0 : errno = ENOMEM;
621 0 : return LDB_ERR_OPERATIONS_ERROR;
622 : }
623 :
624 1693811 : s = talloc_asprintf(msg, "%llu", ldb_kv->sequence_number + 1);
625 1693811 : if (!s) {
626 0 : talloc_free(msg);
627 0 : errno = ENOMEM;
628 0 : return LDB_ERR_OPERATIONS_ERROR;
629 : }
630 :
631 1693811 : msg->num_elements = ARRAY_SIZE(el);
632 1693811 : msg->elements = el;
633 1693811 : msg->dn = ldb_dn_new(msg, ldb, LDB_KV_BASEINFO);
634 1693811 : if (msg->dn == NULL) {
635 0 : talloc_free(msg);
636 0 : errno = ENOMEM;
637 0 : return LDB_ERR_OPERATIONS_ERROR;
638 : }
639 1693811 : el[0].name = talloc_strdup(msg, LDB_KV_SEQUENCE_NUMBER);
640 1693811 : if (el[0].name == NULL) {
641 0 : talloc_free(msg);
642 0 : errno = ENOMEM;
643 0 : return LDB_ERR_OPERATIONS_ERROR;
644 : }
645 1693811 : el[0].values = &val;
646 1693811 : el[0].num_values = 1;
647 1693811 : el[0].flags = LDB_FLAG_MOD_REPLACE;
648 1693811 : val.data = (uint8_t *)s;
649 1693811 : val.length = strlen(s);
650 :
651 1693811 : el[1].name = talloc_strdup(msg, LDB_KV_MOD_TIMESTAMP);
652 1693811 : if (el[1].name == NULL) {
653 0 : talloc_free(msg);
654 0 : errno = ENOMEM;
655 0 : return LDB_ERR_OPERATIONS_ERROR;
656 : }
657 1693811 : el[1].values = &val_time;
658 1693811 : el[1].num_values = 1;
659 1693811 : el[1].flags = LDB_FLAG_MOD_REPLACE;
660 :
661 1693811 : s = ldb_timestring(msg, t);
662 1693811 : if (s == NULL) {
663 0 : talloc_free(msg);
664 0 : return LDB_ERR_OPERATIONS_ERROR;
665 : }
666 :
667 1693811 : val_time.data = (uint8_t *)s;
668 1693811 : val_time.length = strlen(s);
669 :
670 1693811 : ret = ldb_kv_modify_internal(module, msg, NULL);
671 :
672 1693811 : talloc_free(msg);
673 :
674 1693811 : if (ret == LDB_SUCCESS) {
675 1693811 : ldb_kv->sequence_number += 1;
676 : }
677 :
678 : /* updating the tdb_seqnum here avoids us reloading the cache
679 : records due to our own modification */
680 1693811 : ldb_kv->kv_ops->has_changed(ldb_kv);
681 :
682 1693811 : return ret;
683 : }
684 :
685 1426848 : int ldb_kv_check_at_attributes_values(const struct ldb_val *value)
686 : {
687 : unsigned int i;
688 :
689 1853360 : for (i = 0; ldb_kv_valid_attr_flags[i].name != NULL; i++) {
690 1853359 : if ((strcmp(ldb_kv_valid_attr_flags[i].name,
691 1853359 : (char *)value->data) == 0)) {
692 1426847 : return 0;
693 : }
694 : }
695 :
696 1 : return -1;
697 : }
|