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_HIDDEN (1<<2)
41 /* valid attribute flags */
45 } ltdb_valid_attr_flags
[] = {
46 { "CASE_INSENSITIVE", LTDB_FLAG_CASE_INSENSITIVE
},
47 { "INTEGER", LTDB_FLAG_INTEGER
},
48 { "HIDDEN", LTDB_FLAG_HIDDEN
},
55 de-register any special handlers for @ATTRIBUTES
57 static void ltdb_attributes_unload(struct ldb_module
*module
)
59 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
61 ldb_schema_attribute_remove_flagged(ldb
, LDB_ATTR_FLAG_FROM_DB
);
66 add up the attrib flags for a @ATTRIBUTES element
68 static int ltdb_attributes_flags(struct ldb_message_element
*el
, unsigned *v
)
72 for (i
=0;i
<el
->num_values
;i
++) {
74 for (j
=0;ltdb_valid_attr_flags
[j
].name
;j
++) {
75 if (strcmp(ltdb_valid_attr_flags
[j
].name
,
76 (char *)el
->values
[i
].data
) == 0) {
77 value
|= ltdb_valid_attr_flags
[j
].value
;
81 if (ltdb_valid_attr_flags
[j
].name
== NULL
) {
89 static int ldb_schema_attribute_compare(const void *p1
, const void *p2
)
91 const struct ldb_schema_attribute
*sa1
= (const struct ldb_schema_attribute
*)p1
;
92 const struct ldb_schema_attribute
*sa2
= (const struct ldb_schema_attribute
*)p2
;
93 return ldb_attr_cmp(sa1
->name
, sa2
->name
);
97 register any special handlers from @ATTRIBUTES
99 static int ltdb_attributes_load(struct ldb_module
*module
)
101 struct ldb_schema_attribute
*attrs
;
102 struct ldb_context
*ldb
;
103 struct ldb_message
*attrs_msg
= NULL
;
106 unsigned int num_loaded_attrs
= 0;
109 ldb
= ldb_module_get_ctx(module
);
111 if (ldb
->schema
.attribute_handler_override
) {
112 /* we skip loading the @ATTRIBUTES record when a module is supplying
113 its own attribute handling */
117 attrs_msg
= ldb_msg_new(module
);
118 if (attrs_msg
== NULL
) {
122 dn
= ldb_dn_new(module
, ldb
, LTDB_ATTRIBUTES
);
123 if (dn
== NULL
) goto failed
;
125 r
= ltdb_search_dn1(module
, dn
, attrs_msg
,
126 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
127 |LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC
128 |LDB_UNPACK_DATA_FLAG_NO_DN
);
130 if (r
!= LDB_SUCCESS
&& r
!= LDB_ERR_NO_SUCH_OBJECT
) {
133 if (r
== LDB_ERR_NO_SUCH_OBJECT
|| attrs_msg
->num_elements
== 0) {
134 TALLOC_FREE(attrs_msg
);
138 attrs
= talloc_array(attrs_msg
,
139 struct ldb_schema_attribute
,
140 attrs_msg
->num_elements
141 + ldb
->schema
.num_attributes
);
147 ldb
->schema
.attributes
,
148 sizeof(ldb
->schema
.attributes
[0]) * ldb
->schema
.num_attributes
);
150 /* mapping these flags onto ldap 'syntaxes' isn't strictly correct,
151 but its close enough for now */
152 for (i
=0;i
<attrs_msg
->num_elements
;i
++) {
155 const struct ldb_schema_syntax
*s
;
156 const struct ldb_schema_attribute
*a
=
157 ldb_schema_attribute_by_name(ldb
,
158 attrs_msg
->elements
[i
].name
);
159 if (a
!= NULL
&& a
->flags
& LDB_ATTR_FLAG_FIXED
) {
160 /* Must already be set in the array, and kept */
164 if (ltdb_attributes_flags(&attrs_msg
->elements
[i
], &flags
) != 0) {
165 ldb_debug(ldb
, LDB_DEBUG_ERROR
,
166 "Invalid @ATTRIBUTES element for '%s'",
167 attrs_msg
->elements
[i
].name
);
170 switch (flags
& ~LTDB_FLAG_HIDDEN
) {
172 syntax
= LDB_SYNTAX_OCTET_STRING
;
174 case LTDB_FLAG_CASE_INSENSITIVE
:
175 syntax
= LDB_SYNTAX_DIRECTORY_STRING
;
177 case LTDB_FLAG_INTEGER
:
178 syntax
= LDB_SYNTAX_INTEGER
;
181 ldb_debug(ldb
, LDB_DEBUG_ERROR
,
182 "Invalid flag combination 0x%x for '%s' "
184 flags
, attrs_msg
->elements
[i
].name
);
188 s
= ldb_standard_syntax_by_name(ldb
, syntax
);
190 ldb_debug(ldb
, LDB_DEBUG_ERROR
,
191 "Invalid attribute syntax '%s' for '%s' "
193 syntax
, attrs_msg
->elements
[i
].name
);
197 flags
|= LDB_ATTR_FLAG_ALLOCATED
| LDB_ATTR_FLAG_FROM_DB
;
199 r
= ldb_schema_attribute_fill_with_syntax(ldb
,
201 attrs_msg
->elements
[i
].name
,
203 &attrs
[num_loaded_attrs
+ ldb
->schema
.num_attributes
]);
210 attrs
= talloc_realloc(attrs_msg
,
211 attrs
, struct ldb_schema_attribute
,
212 num_loaded_attrs
+ ldb
->schema
.num_attributes
);
216 TYPESAFE_QSORT(attrs
, num_loaded_attrs
+ ldb
->schema
.num_attributes
,
217 ldb_schema_attribute_compare
);
218 talloc_unlink(ldb
, ldb
->schema
.attributes
);
219 ldb
->schema
.attributes
= talloc_steal(ldb
, attrs
);
220 ldb
->schema
.num_attributes
= num_loaded_attrs
+ ldb
->schema
.num_attributes
;
221 TALLOC_FREE(attrs_msg
);
225 TALLOC_FREE(attrs_msg
);
231 initialise the baseinfo record
233 static int ltdb_baseinfo_init(struct ldb_module
*module
)
235 struct ldb_context
*ldb
;
236 void *data
= ldb_module_get_private(module
);
237 struct ltdb_private
*ltdb
= talloc_get_type(data
, struct ltdb_private
);
238 struct ldb_message
*msg
;
239 struct ldb_message_element el
;
242 /* the initial sequence number must be different from the one
243 set in ltdb_cache_free(). Thanks to Jon for pointing this
245 const char *initial_sequence_number
= "1";
247 ldb
= ldb_module_get_ctx(module
);
249 ltdb
->sequence_number
= atof(initial_sequence_number
);
251 msg
= ldb_msg_new(ltdb
);
256 msg
->num_elements
= 1;
258 msg
->dn
= ldb_dn_new(msg
, ldb
, LTDB_BASEINFO
);
262 el
.name
= talloc_strdup(msg
, LTDB_SEQUENCE_NUMBER
);
269 val
.data
= (uint8_t *)talloc_strdup(msg
, initial_sequence_number
);
275 ret
= ltdb_store(module
, msg
, TDB_INSERT
);
284 return LDB_ERR_OPERATIONS_ERROR
;
288 free any cache records
290 static void ltdb_cache_free(struct ldb_module
*module
)
292 void *data
= ldb_module_get_private(module
);
293 struct ltdb_private
*ltdb
= talloc_get_type(data
, struct ltdb_private
);
295 ltdb
->sequence_number
= 0;
296 talloc_free(ltdb
->cache
);
303 int ltdb_cache_reload(struct ldb_module
*module
)
305 ltdb_attributes_unload(module
);
306 ltdb_cache_free(module
);
307 return ltdb_cache_load(module
);
311 load the cache records
313 int ltdb_cache_load(struct ldb_module
*module
)
315 struct ldb_context
*ldb
;
316 void *data
= ldb_module_get_private(module
);
317 struct ltdb_private
*ltdb
= talloc_get_type(data
, struct ltdb_private
);
318 struct ldb_dn
*baseinfo_dn
= NULL
, *options_dn
= NULL
;
319 struct ldb_dn
*indexlist_dn
= NULL
;
321 struct ldb_message
*baseinfo
= NULL
, *options
= NULL
;
324 ldb
= ldb_module_get_ctx(module
);
326 /* a very fast check to avoid extra database reads */
327 if (ltdb
->cache
!= NULL
&&
328 tdb_get_seqnum(ltdb
->tdb
) == ltdb
->tdb_seqnum
) {
332 if (ltdb
->cache
== NULL
) {
333 ltdb
->cache
= talloc_zero(ltdb
, struct ltdb_cache
);
334 if (ltdb
->cache
== NULL
) goto failed
;
335 ltdb
->cache
->indexlist
= ldb_msg_new(ltdb
->cache
);
336 if (ltdb
->cache
->indexlist
== NULL
) {
341 baseinfo
= ldb_msg_new(ltdb
->cache
);
342 if (baseinfo
== NULL
) goto failed
;
344 baseinfo_dn
= ldb_dn_new(baseinfo
, ldb
, LTDB_BASEINFO
);
345 if (baseinfo_dn
== NULL
) goto failed
;
347 r
= ltdb_search_dn1(module
, baseinfo_dn
, baseinfo
, 0);
348 if (r
!= LDB_SUCCESS
&& r
!= LDB_ERR_NO_SUCH_OBJECT
) {
352 /* possibly initialise the baseinfo */
353 if (r
== LDB_ERR_NO_SUCH_OBJECT
) {
355 if (tdb_transaction_start(ltdb
->tdb
) != 0) {
359 /* error handling for ltdb_baseinfo_init() is by
360 looking for the record again. */
361 ltdb_baseinfo_init(module
);
363 tdb_transaction_commit(ltdb
->tdb
);
365 if (ltdb_search_dn1(module
, baseinfo_dn
, baseinfo
, 0) != LDB_SUCCESS
) {
370 ltdb
->tdb_seqnum
= tdb_get_seqnum(ltdb
->tdb
);
372 /* if the current internal sequence number is the same as the one
373 in the database then assume the rest of the cache is OK */
374 seq
= ldb_msg_find_attr_as_uint64(baseinfo
, LTDB_SEQUENCE_NUMBER
, 0);
375 if (seq
== ltdb
->sequence_number
) {
378 ltdb
->sequence_number
= seq
;
380 /* Read an interpret database options */
381 options
= ldb_msg_new(ltdb
->cache
);
382 if (options
== NULL
) goto failed
;
384 options_dn
= ldb_dn_new(options
, ldb
, LTDB_OPTIONS
);
385 if (options_dn
== NULL
) goto failed
;
387 r
= ltdb_search_dn1(module
, options_dn
, options
, 0);
388 talloc_free(options_dn
);
389 if (r
!= LDB_SUCCESS
&& r
!= LDB_ERR_NO_SUCH_OBJECT
) {
393 /* set flags if they do exist */
394 if (r
== LDB_SUCCESS
) {
395 ltdb
->check_base
= ldb_msg_find_attr_as_bool(options
,
398 ltdb
->disallow_dn_filter
= ldb_msg_find_attr_as_bool(options
,
399 LTDB_DISALLOW_DN_FILTER
,
402 ltdb
->check_base
= false;
403 ltdb
->disallow_dn_filter
= false;
406 talloc_free(ltdb
->cache
->indexlist
);
408 * ltdb_attributes_unload() calls internally talloc_free() on
409 * any non-fixed elemnts in ldb->schema.attributes.
411 * NOTE WELL: This is per-ldb, not per module, so overwrites
412 * the handlers across all databases when used under Samba's
415 ltdb_attributes_unload(module
);
416 ltdb
->cache
->indexlist
= ldb_msg_new(ltdb
->cache
);
417 if (ltdb
->cache
->indexlist
== NULL
) {
420 ltdb
->cache
->one_level_indexes
= false;
421 ltdb
->cache
->attribute_indexes
= false;
423 indexlist_dn
= ldb_dn_new(module
, ldb
, LTDB_INDEXLIST
);
424 if (indexlist_dn
== NULL
) goto failed
;
426 r
= ltdb_search_dn1(module
, indexlist_dn
, ltdb
->cache
->indexlist
,
427 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
428 |LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC
429 |LDB_UNPACK_DATA_FLAG_NO_DN
);
430 if (r
!= LDB_SUCCESS
&& r
!= LDB_ERR_NO_SUCH_OBJECT
) {
434 if (ldb_msg_find_element(ltdb
->cache
->indexlist
, LTDB_IDXONE
) != NULL
) {
435 ltdb
->cache
->one_level_indexes
= true;
437 if (ldb_msg_find_element(ltdb
->cache
->indexlist
, LTDB_IDXATTR
) != NULL
) {
438 ltdb
->cache
->attribute_indexes
= true;
442 * NOTE WELL: This is per-ldb, not per module, so overwrites
443 * the handlers across all databases when used under Samba's
446 if (ltdb_attributes_load(module
) == -1) {
451 talloc_free(options
);
452 talloc_free(baseinfo
);
453 talloc_free(indexlist_dn
);
457 talloc_free(options
);
458 talloc_free(baseinfo
);
459 talloc_free(indexlist_dn
);
465 increase the sequence number to indicate a database change
467 int ltdb_increase_sequence_number(struct ldb_module
*module
)
469 struct ldb_context
*ldb
;
470 void *data
= ldb_module_get_private(module
);
471 struct ltdb_private
*ltdb
= talloc_get_type(data
, struct ltdb_private
);
472 struct ldb_message
*msg
;
473 struct ldb_message_element el
[2];
475 struct ldb_val val_time
;
476 time_t t
= time(NULL
);
480 ldb
= ldb_module_get_ctx(module
);
482 msg
= ldb_msg_new(ltdb
);
485 return LDB_ERR_OPERATIONS_ERROR
;
488 s
= talloc_asprintf(msg
, "%llu", ltdb
->sequence_number
+1);
492 return LDB_ERR_OPERATIONS_ERROR
;
495 msg
->num_elements
= ARRAY_SIZE(el
);
497 msg
->dn
= ldb_dn_new(msg
, ldb
, LTDB_BASEINFO
);
498 if (msg
->dn
== NULL
) {
501 return LDB_ERR_OPERATIONS_ERROR
;
503 el
[0].name
= talloc_strdup(msg
, LTDB_SEQUENCE_NUMBER
);
504 if (el
[0].name
== NULL
) {
507 return LDB_ERR_OPERATIONS_ERROR
;
510 el
[0].num_values
= 1;
511 el
[0].flags
= LDB_FLAG_MOD_REPLACE
;
512 val
.data
= (uint8_t *)s
;
513 val
.length
= strlen(s
);
515 el
[1].name
= talloc_strdup(msg
, LTDB_MOD_TIMESTAMP
);
516 if (el
[1].name
== NULL
) {
519 return LDB_ERR_OPERATIONS_ERROR
;
521 el
[1].values
= &val_time
;
522 el
[1].num_values
= 1;
523 el
[1].flags
= LDB_FLAG_MOD_REPLACE
;
525 s
= ldb_timestring(msg
, t
);
528 return LDB_ERR_OPERATIONS_ERROR
;
531 val_time
.data
= (uint8_t *)s
;
532 val_time
.length
= strlen(s
);
534 ret
= ltdb_modify_internal(module
, msg
, NULL
);
538 if (ret
== LDB_SUCCESS
) {
539 ltdb
->sequence_number
+= 1;
542 /* updating the tdb_seqnum here avoids us reloading the cache
543 records due to our own modification */
544 ltdb
->tdb_seqnum
= tdb_get_seqnum(ltdb
->tdb
);
549 int ltdb_check_at_attributes_values(const struct ldb_val
*value
)
553 for (i
= 0; ltdb_valid_attr_flags
[i
].name
!= NULL
; i
++) {
554 if ((strcmp(ltdb_valid_attr_flags
[i
].name
, (char *)value
->data
) == 0)) {