4 Copyright (C) Andrew Tridgell 2004
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
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.
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.
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/>.
27 * Component: ldb tdb cache functions
29 * Description: cache special records in a ldb/tdb
31 * Author: Andrew Tridgell
35 #include "ldb_private.h"
37 #define LTDB_FLAG_CASE_INSENSITIVE (1<<0)
38 #define LTDB_FLAG_INTEGER (1<<1)
39 #define LTDB_FLAG_UNIQUE_INDEX (1<<2)
41 /* valid attribute flags */
45 } ltdb_valid_attr_flags[] = {
46 { "CASE_INSENSITIVE", LTDB_FLAG_CASE_INSENSITIVE },
47 { "INTEGER", LTDB_FLAG_INTEGER },
49 { "UNIQUE_INDEX", LTDB_FLAG_UNIQUE_INDEX},
56 de-register any special handlers for @ATTRIBUTES
58 static void ltdb_attributes_unload(struct ldb_module *module)
60 struct ldb_context *ldb = ldb_module_get_ctx(module);
62 ldb_schema_attribute_remove_flagged(ldb, LDB_ATTR_FLAG_FROM_DB);
67 add up the attrib flags for a @ATTRIBUTES element
69 static int ltdb_attributes_flags(struct ldb_message_element *el, unsigned *v)
73 for (i=0;i<el->num_values;i++) {
75 for (j=0;ltdb_valid_attr_flags[j].name;j++) {
76 if (strcmp(ltdb_valid_attr_flags[j].name,
77 (char *)el->values[i].data) == 0) {
78 value |= ltdb_valid_attr_flags[j].value;
82 if (ltdb_valid_attr_flags[j].name == NULL) {
90 static int ldb_schema_attribute_compare(const void *p1, const void *p2)
92 const struct ldb_schema_attribute *sa1 = (const struct ldb_schema_attribute *)p1;
93 const struct ldb_schema_attribute *sa2 = (const struct ldb_schema_attribute *)p2;
94 return ldb_attr_cmp(sa1->name, sa2->name);
98 register any special handlers from @ATTRIBUTES
100 static int ltdb_attributes_load(struct ldb_module *module)
102 struct ldb_schema_attribute *attrs;
103 struct ldb_context *ldb;
104 struct ldb_message *attrs_msg = NULL;
107 unsigned int num_loaded_attrs = 0;
110 ldb = ldb_module_get_ctx(module);
112 if (ldb->schema.attribute_handler_override) {
113 /* we skip loading the @ATTRIBUTES record when a module is supplying
114 its own attribute handling */
118 attrs_msg = ldb_msg_new(module);
119 if (attrs_msg == NULL) {
123 dn = ldb_dn_new(module, ldb, LTDB_ATTRIBUTES);
124 if (dn == NULL) goto failed;
126 r = ltdb_search_dn1(module, dn, attrs_msg,
127 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
128 |LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC
129 |LDB_UNPACK_DATA_FLAG_NO_DN);
131 if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
134 if (r == LDB_ERR_NO_SUCH_OBJECT || attrs_msg->num_elements == 0) {
135 TALLOC_FREE(attrs_msg);
139 attrs = talloc_array(attrs_msg,
140 struct ldb_schema_attribute,
141 attrs_msg->num_elements
142 + ldb->schema.num_attributes);
148 ldb->schema.attributes,
149 sizeof(ldb->schema.attributes[0]) * ldb->schema.num_attributes);
151 /* mapping these flags onto ldap 'syntaxes' isn't strictly correct,
152 but its close enough for now */
153 for (i=0;i<attrs_msg->num_elements;i++) {
154 unsigned flags = 0, attr_flags = 0;
156 const struct ldb_schema_syntax *s;
157 const struct ldb_schema_attribute *a =
158 ldb_schema_attribute_by_name(ldb,
159 attrs_msg->elements[i].name);
160 if (a != NULL && a->flags & LDB_ATTR_FLAG_FIXED) {
161 /* Must already be set in the array, and kept */
165 if (ltdb_attributes_flags(&attrs_msg->elements[i], &flags) != 0) {
166 ldb_debug(ldb, LDB_DEBUG_ERROR,
167 "Invalid @ATTRIBUTES element for '%s'",
168 attrs_msg->elements[i].name);
172 if (flags & LTDB_FLAG_UNIQUE_INDEX) {
173 attr_flags = LDB_ATTR_FLAG_UNIQUE_INDEX;
175 flags &= ~LTDB_FLAG_UNIQUE_INDEX;
177 /* These are not currently flags, each is exclusive */
178 if (flags == LTDB_FLAG_CASE_INSENSITIVE) {
179 syntax = LDB_SYNTAX_DIRECTORY_STRING;
180 } else if (flags == LTDB_FLAG_INTEGER) {
181 syntax = LDB_SYNTAX_INTEGER;
182 } else if (flags == 0) {
183 syntax = LDB_SYNTAX_OCTET_STRING;
185 ldb_debug(ldb, LDB_DEBUG_ERROR,
186 "Invalid flag combination 0x%x for '%s' "
188 flags, attrs_msg->elements[i].name);
192 s = ldb_standard_syntax_by_name(ldb, syntax);
194 ldb_debug(ldb, LDB_DEBUG_ERROR,
195 "Invalid attribute syntax '%s' for '%s' "
197 syntax, attrs_msg->elements[i].name);
201 attr_flags |= LDB_ATTR_FLAG_ALLOCATED | LDB_ATTR_FLAG_FROM_DB;
203 r = ldb_schema_attribute_fill_with_syntax(ldb,
205 attrs_msg->elements[i].name,
207 &attrs[num_loaded_attrs + ldb->schema.num_attributes]);
214 attrs = talloc_realloc(attrs_msg,
215 attrs, struct ldb_schema_attribute,
216 num_loaded_attrs + ldb->schema.num_attributes);
220 TYPESAFE_QSORT(attrs, num_loaded_attrs + ldb->schema.num_attributes,
221 ldb_schema_attribute_compare);
222 talloc_unlink(ldb, ldb->schema.attributes);
223 ldb->schema.attributes = talloc_steal(ldb, attrs);
224 ldb->schema.num_attributes = num_loaded_attrs + ldb->schema.num_attributes;
225 TALLOC_FREE(attrs_msg);
229 TALLOC_FREE(attrs_msg);
234 register any index records we find for the DB
236 static int ltdb_index_load(struct ldb_module *module,
237 struct ltdb_private *ltdb)
239 struct ldb_context *ldb = ldb_module_get_ctx(module);
240 struct ldb_dn *indexlist_dn;
243 if (ldb->schema.index_handler_override) {
245 * we skip loading the @INDEXLIST record when a module is
246 * supplying its own attribute handling
248 ltdb->cache->attribute_indexes = true;
249 ltdb->cache->one_level_indexes = ldb->schema.one_level_indexes;
250 ltdb->cache->GUID_index_attribute
251 = ldb->schema.GUID_index_attribute;
252 ltdb->cache->GUID_index_dn_component
253 = ldb->schema.GUID_index_dn_component;
257 talloc_free(ltdb->cache->indexlist);
259 ltdb->cache->indexlist = ldb_msg_new(ltdb->cache);
260 if (ltdb->cache->indexlist == NULL) {
263 ltdb->cache->one_level_indexes = false;
264 ltdb->cache->attribute_indexes = false;
266 indexlist_dn = ldb_dn_new(ltdb, ldb, LTDB_INDEXLIST);
267 if (indexlist_dn == NULL) {
271 r = ltdb_search_dn1(module, indexlist_dn, ltdb->cache->indexlist,
272 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
273 |LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC
274 |LDB_UNPACK_DATA_FLAG_NO_DN);
275 TALLOC_FREE(indexlist_dn);
277 if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
281 if (ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXONE) != NULL) {
282 ltdb->cache->one_level_indexes = true;
284 if (ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXATTR) != NULL) {
285 ltdb->cache->attribute_indexes = true;
287 ltdb->cache->GUID_index_attribute
288 = ldb_msg_find_attr_as_string(ltdb->cache->indexlist,
290 ltdb->cache->GUID_index_dn_component
291 = ldb_msg_find_attr_as_string(ltdb->cache->indexlist,
292 LTDB_IDX_DN_GUID, NULL);
298 initialise the baseinfo record
300 static int ltdb_baseinfo_init(struct ldb_module *module)
302 struct ldb_context *ldb;
303 void *data = ldb_module_get_private(module);
304 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
305 struct ldb_message *msg;
306 struct ldb_message_element el;
309 /* the initial sequence number must be different from the one
310 set in ltdb_cache_free(). Thanks to Jon for pointing this
312 const char *initial_sequence_number = "1";
314 ldb = ldb_module_get_ctx(module);
316 ltdb->sequence_number = atof(initial_sequence_number);
318 msg = ldb_msg_new(ltdb);
323 msg->num_elements = 1;
325 msg->dn = ldb_dn_new(msg, ldb, LTDB_BASEINFO);
329 el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER);
336 val.data = (uint8_t *)talloc_strdup(msg, initial_sequence_number);
342 ret = ltdb_store(module, msg, TDB_INSERT);
351 return LDB_ERR_OPERATIONS_ERROR;
355 free any cache records
357 static void ltdb_cache_free(struct ldb_module *module)
359 void *data = ldb_module_get_private(module);
360 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
362 ltdb->sequence_number = 0;
363 talloc_free(ltdb->cache);
370 int ltdb_cache_reload(struct ldb_module *module)
372 ltdb_attributes_unload(module);
373 ltdb_cache_free(module);
374 return ltdb_cache_load(module);
378 load the cache records
380 int ltdb_cache_load(struct ldb_module *module)
382 struct ldb_context *ldb;
383 void *data = ldb_module_get_private(module);
384 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
385 struct ldb_dn *baseinfo_dn = NULL, *options_dn = NULL;
387 struct ldb_message *baseinfo = NULL, *options = NULL;
388 const struct ldb_schema_attribute *a;
391 ldb = ldb_module_get_ctx(module);
393 /* a very fast check to avoid extra database reads */
394 if (ltdb->cache != NULL && !ltdb->kv_ops->has_changed(ltdb)) {
398 if (ltdb->cache == NULL) {
399 ltdb->cache = talloc_zero(ltdb, struct ltdb_cache);
400 if (ltdb->cache == NULL) goto failed;
403 baseinfo = ldb_msg_new(ltdb->cache);
404 if (baseinfo == NULL) goto failed;
406 baseinfo_dn = ldb_dn_new(baseinfo, ldb, LTDB_BASEINFO);
407 if (baseinfo_dn == NULL) goto failed;
409 r= ltdb_search_dn1(module, baseinfo_dn, baseinfo, 0);
410 if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
414 /* possibly initialise the baseinfo */
415 if (r == LDB_ERR_NO_SUCH_OBJECT) {
417 if (ltdb->kv_ops->begin_write(ltdb) != 0) {
421 /* error handling for ltdb_baseinfo_init() is by
422 looking for the record again. */
423 ltdb_baseinfo_init(module);
425 if (ltdb->kv_ops->finish_write(ltdb) != 0) {
429 if (ltdb_search_dn1(module, baseinfo_dn, baseinfo, 0) != LDB_SUCCESS) {
434 /* Ignore the result, and update the sequence number */
435 ltdb->kv_ops->has_changed(ltdb);
437 /* if the current internal sequence number is the same as the one
438 in the database then assume the rest of the cache is OK */
439 seq = ldb_msg_find_attr_as_uint64(baseinfo, LTDB_SEQUENCE_NUMBER, 0);
440 if (seq == ltdb->sequence_number) {
443 ltdb->sequence_number = seq;
445 /* Read an interpret database options */
446 options = ldb_msg_new(ltdb->cache);
447 if (options == NULL) goto failed;
449 options_dn = ldb_dn_new(options, ldb, LTDB_OPTIONS);
450 if (options_dn == NULL) goto failed;
452 r= ltdb_search_dn1(module, options_dn, options, 0);
453 talloc_free(options_dn);
454 if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
458 /* set flags if they do exist */
459 if (r == LDB_SUCCESS) {
460 ltdb->check_base = ldb_msg_find_attr_as_bool(options,
463 ltdb->disallow_dn_filter = ldb_msg_find_attr_as_bool(options,
464 LTDB_DISALLOW_DN_FILTER,
467 ltdb->check_base = false;
468 ltdb->disallow_dn_filter = false;
472 * ltdb_attributes_unload() calls internally talloc_free() on
473 * any non-fixed elemnts in ldb->schema.attributes.
475 * NOTE WELL: This is per-ldb, not per module, so overwrites
476 * the handlers across all databases when used under Samba's
479 ltdb_attributes_unload(module);
481 if (ltdb_index_load(module, ltdb) == -1) {
486 * NOTE WELL: This is per-ldb, not per module, so overwrites
487 * the handlers across all databases when used under Samba's
490 if (ltdb_attributes_load(module) == -1) {
494 ltdb->GUID_index_syntax = NULL;
495 if (ltdb->cache->GUID_index_attribute != NULL) {
497 * Now the attributes are loaded, set the guid_index_syntax.
498 * This can't fail, it will return a default at worst
500 a = ldb_schema_attribute_by_name(ldb,
501 ltdb->cache->GUID_index_attribute);
502 ltdb->GUID_index_syntax = a->syntax;
506 talloc_free(options);
507 talloc_free(baseinfo);
511 talloc_free(options);
512 talloc_free(baseinfo);
518 increase the sequence number to indicate a database change
520 int ltdb_increase_sequence_number(struct ldb_module *module)
522 struct ldb_context *ldb;
523 void *data = ldb_module_get_private(module);
524 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
525 struct ldb_message *msg;
526 struct ldb_message_element el[2];
528 struct ldb_val val_time;
529 time_t t = time(NULL);
533 ldb = ldb_module_get_ctx(module);
535 msg = ldb_msg_new(ltdb);
538 return LDB_ERR_OPERATIONS_ERROR;
541 s = talloc_asprintf(msg, "%llu", ltdb->sequence_number+1);
545 return LDB_ERR_OPERATIONS_ERROR;
548 msg->num_elements = ARRAY_SIZE(el);
550 msg->dn = ldb_dn_new(msg, ldb, LTDB_BASEINFO);
551 if (msg->dn == NULL) {
554 return LDB_ERR_OPERATIONS_ERROR;
556 el[0].name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER);
557 if (el[0].name == NULL) {
560 return LDB_ERR_OPERATIONS_ERROR;
563 el[0].num_values = 1;
564 el[0].flags = LDB_FLAG_MOD_REPLACE;
565 val.data = (uint8_t *)s;
566 val.length = strlen(s);
568 el[1].name = talloc_strdup(msg, LTDB_MOD_TIMESTAMP);
569 if (el[1].name == NULL) {
572 return LDB_ERR_OPERATIONS_ERROR;
574 el[1].values = &val_time;
575 el[1].num_values = 1;
576 el[1].flags = LDB_FLAG_MOD_REPLACE;
578 s = ldb_timestring(msg, t);
581 return LDB_ERR_OPERATIONS_ERROR;
584 val_time.data = (uint8_t *)s;
585 val_time.length = strlen(s);
587 ret = ltdb_modify_internal(module, msg, NULL);
591 if (ret == LDB_SUCCESS) {
592 ltdb->sequence_number += 1;
595 /* updating the tdb_seqnum here avoids us reloading the cache
596 records due to our own modification */
597 ltdb->kv_ops->has_changed(ltdb);
602 int ltdb_check_at_attributes_values(const struct ldb_val *value)
606 for (i = 0; ltdb_valid_attr_flags[i].name != NULL; i++) {
607 if ((strcmp(ltdb_valid_attr_flags[i].name, (char *)value->data) == 0)) {