ldb: make key/value backends expose if there is an active transaction
[metze/samba/wip.git] / lib / ldb / ldb_tdb / ldb_cache.c
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 tdb cache functions
28  *
29  *  Description: cache special records in a ldb/tdb
30  *
31  *  Author: Andrew Tridgell
32  */
33
34 #include "ldb_tdb.h"
35 #include "ldb_private.h"
36
37 #define LTDB_FLAG_CASE_INSENSITIVE (1<<0)
38 #define LTDB_FLAG_INTEGER          (1<<1)
39 #define LTDB_FLAG_UNIQUE_INDEX     (1<<2)
40
41 /* valid attribute flags */
42 static const struct {
43         const char *name;
44         int value;
45 } ltdb_valid_attr_flags[] = {
46         { "CASE_INSENSITIVE", LTDB_FLAG_CASE_INSENSITIVE },
47         { "INTEGER", LTDB_FLAG_INTEGER },
48         { "HIDDEN", 0 },
49         { "UNIQUE_INDEX",  LTDB_FLAG_UNIQUE_INDEX},
50         { "NONE", 0 },
51         { NULL, 0 }
52 };
53
54
55 /*
56   de-register any special handlers for @ATTRIBUTES
57 */
58 static void ltdb_attributes_unload(struct ldb_module *module)
59 {
60         struct ldb_context *ldb = ldb_module_get_ctx(module);
61
62         ldb_schema_attribute_remove_flagged(ldb, LDB_ATTR_FLAG_FROM_DB);
63
64 }
65
66 /*
67   add up the attrib flags for a @ATTRIBUTES element
68 */
69 static int ltdb_attributes_flags(struct ldb_message_element *el, unsigned *v)
70 {
71         unsigned int i;
72         unsigned value = 0;
73         for (i=0;i<el->num_values;i++) {
74                 unsigned int j;
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;
79                                 break;
80                         }
81                 }
82                 if (ltdb_valid_attr_flags[j].name == NULL) {
83                         return -1;
84                 }
85         }
86         *v = value;
87         return 0;
88 }
89
90 static int ldb_schema_attribute_compare(const void *p1, const void *p2)
91 {
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);
95 }
96
97 /*
98   register any special handlers from @ATTRIBUTES
99 */
100 static int ltdb_attributes_load(struct ldb_module *module)
101 {
102         struct ldb_schema_attribute *attrs;
103         struct ldb_context *ldb;
104         struct ldb_message *attrs_msg = NULL;
105         struct ldb_dn *dn;
106         unsigned int i;
107         unsigned int num_loaded_attrs = 0;
108         int r;
109
110         ldb = ldb_module_get_ctx(module);
111
112         if (ldb->schema.attribute_handler_override) {
113                 /* we skip loading the @ATTRIBUTES record when a module is supplying
114                    its own attribute handling */
115                 return 0;
116         }
117
118         attrs_msg = ldb_msg_new(module);
119         if (attrs_msg == NULL) {
120                 goto failed;
121         }
122
123         dn = ldb_dn_new(module, ldb, LTDB_ATTRIBUTES);
124         if (dn == NULL) goto failed;
125
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);
130         talloc_free(dn);
131         if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
132                 goto failed;
133         }
134         if (r == LDB_ERR_NO_SUCH_OBJECT || attrs_msg->num_elements == 0) {
135                 TALLOC_FREE(attrs_msg);
136                 return 0;
137         }
138
139         attrs = talloc_array(attrs_msg,
140                              struct ldb_schema_attribute,
141                              attrs_msg->num_elements
142                              + ldb->schema.num_attributes);
143         if (attrs == NULL) {
144                 goto failed;
145         }
146
147         memcpy(attrs,
148                ldb->schema.attributes,
149                sizeof(ldb->schema.attributes[0]) * ldb->schema.num_attributes);
150
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;
155                 const char *syntax;
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 */
162                         continue;
163                 }
164
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);
169                         goto failed;
170                 }
171
172                 if (flags & LTDB_FLAG_UNIQUE_INDEX) {
173                         attr_flags = LDB_ATTR_FLAG_UNIQUE_INDEX;
174                 }
175                 flags &= ~LTDB_FLAG_UNIQUE_INDEX;
176
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;
184                 } else {
185                         ldb_debug(ldb, LDB_DEBUG_ERROR, 
186                                   "Invalid flag combination 0x%x for '%s' "
187                                   "in @ATTRIBUTES",
188                                   flags, attrs_msg->elements[i].name);
189                         goto failed;
190                 }
191
192                 s = ldb_standard_syntax_by_name(ldb, syntax);
193                 if (s == NULL) {
194                         ldb_debug(ldb, LDB_DEBUG_ERROR, 
195                                   "Invalid attribute syntax '%s' for '%s' "
196                                   "in @ATTRIBUTES",
197                                   syntax, attrs_msg->elements[i].name);
198                         goto failed;
199                 }
200
201                 attr_flags |= LDB_ATTR_FLAG_ALLOCATED | LDB_ATTR_FLAG_FROM_DB;
202
203                 r = ldb_schema_attribute_fill_with_syntax(ldb,
204                                                           attrs,
205                                                           attrs_msg->elements[i].name,
206                                                           attr_flags, s,
207                                                           &attrs[num_loaded_attrs + ldb->schema.num_attributes]);
208                 if (r != 0) {
209                         goto failed;
210                 }
211                 num_loaded_attrs++;
212         }
213
214         attrs = talloc_realloc(attrs_msg,
215                                attrs, struct ldb_schema_attribute,
216                                num_loaded_attrs + ldb->schema.num_attributes);
217         if (attrs == NULL) {
218                 goto failed;
219         }
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);
226
227         return 0;
228 failed:
229         TALLOC_FREE(attrs_msg);
230         return -1;
231 }
232
233 /*
234   register any index records we find for the DB
235 */
236 static int ltdb_index_load(struct ldb_module *module,
237                            struct ltdb_private *ltdb)
238 {
239         struct ldb_context *ldb = ldb_module_get_ctx(module);
240         struct ldb_dn *indexlist_dn;
241         int r;
242
243         if (ldb->schema.index_handler_override) {
244                 /*
245                  * we skip loading the @INDEXLIST record when a module is
246                  * supplying its own attribute handling
247                  */
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;
254                 return 0;
255         }
256
257         talloc_free(ltdb->cache->indexlist);
258
259         ltdb->cache->indexlist = ldb_msg_new(ltdb->cache);
260         if (ltdb->cache->indexlist == NULL) {
261                 return -1;
262         }
263         ltdb->cache->one_level_indexes = false;
264         ltdb->cache->attribute_indexes = false;
265
266         indexlist_dn = ldb_dn_new(ltdb, ldb, LTDB_INDEXLIST);
267         if (indexlist_dn == NULL) {
268                 return -1;
269         }
270
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);
276
277         if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
278                 return -1;
279         }
280
281         if (ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXONE) != NULL) {
282                 ltdb->cache->one_level_indexes = true;
283         }
284         if (ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXATTR) != NULL) {
285                 ltdb->cache->attribute_indexes = true;
286         }
287         ltdb->cache->GUID_index_attribute
288                 = ldb_msg_find_attr_as_string(ltdb->cache->indexlist,
289                                               LTDB_IDXGUID, NULL);
290         ltdb->cache->GUID_index_dn_component
291                 = ldb_msg_find_attr_as_string(ltdb->cache->indexlist,
292                                               LTDB_IDX_DN_GUID, NULL);
293
294         return 0;
295 }
296
297 /*
298   initialise the baseinfo record
299 */
300 static int ltdb_baseinfo_init(struct ldb_module *module)
301 {
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;
307         struct ldb_val val;
308         int ret;
309         /* the initial sequence number must be different from the one
310            set in ltdb_cache_free(). Thanks to Jon for pointing this
311            out. */
312         const char *initial_sequence_number = "1";
313
314         ldb = ldb_module_get_ctx(module);
315
316         ltdb->sequence_number = atof(initial_sequence_number);
317
318         msg = ldb_msg_new(ltdb);
319         if (msg == NULL) {
320                 goto failed;
321         }
322
323         msg->num_elements = 1;
324         msg->elements = &el;
325         msg->dn = ldb_dn_new(msg, ldb, LTDB_BASEINFO);
326         if (!msg->dn) {
327                 goto failed;
328         }
329         el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER);
330         if (!el.name) {
331                 goto failed;
332         }
333         el.values = &val;
334         el.num_values = 1;
335         el.flags = 0;
336         val.data = (uint8_t *)talloc_strdup(msg, initial_sequence_number);
337         if (!val.data) {
338                 goto failed;
339         }
340         val.length = 1;
341         
342         ret = ltdb_store(module, msg, TDB_INSERT);
343
344         talloc_free(msg);
345
346         return ret;
347
348 failed:
349         talloc_free(msg);
350         errno = ENOMEM;
351         return LDB_ERR_OPERATIONS_ERROR;
352 }
353
354 /*
355   free any cache records
356  */
357 static void ltdb_cache_free(struct ldb_module *module)
358 {
359         void *data = ldb_module_get_private(module);
360         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
361
362         ltdb->sequence_number = 0;
363         talloc_free(ltdb->cache);
364         ltdb->cache = NULL;
365 }
366
367 /*
368   force a cache reload
369 */
370 int ltdb_cache_reload(struct ldb_module *module)
371 {
372         ltdb_attributes_unload(module);
373         ltdb_cache_free(module);
374         return ltdb_cache_load(module);
375 }
376
377 /*
378   load the cache records
379 */
380 int ltdb_cache_load(struct ldb_module *module)
381 {
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;
386         uint64_t seq;
387         struct ldb_message *baseinfo = NULL, *options = NULL;
388         const struct ldb_schema_attribute *a;
389         int r;
390
391         ldb = ldb_module_get_ctx(module);
392
393         /* a very fast check to avoid extra database reads */
394         if (ltdb->cache != NULL && !ltdb->kv_ops->has_changed(ltdb)) {
395                 return 0;
396         }
397
398         if (ltdb->cache == NULL) {
399                 ltdb->cache = talloc_zero(ltdb, struct ltdb_cache);
400                 if (ltdb->cache == NULL) goto failed;
401         }
402
403         baseinfo = ldb_msg_new(ltdb->cache);
404         if (baseinfo == NULL) goto failed;
405
406         baseinfo_dn = ldb_dn_new(baseinfo, ldb, LTDB_BASEINFO);
407         if (baseinfo_dn == NULL) goto failed;
408
409         r= ltdb_search_dn1(module, baseinfo_dn, baseinfo, 0);
410         if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
411                 goto failed;
412         }
413         
414         /* possibly initialise the baseinfo */
415         if (r == LDB_ERR_NO_SUCH_OBJECT) {
416
417                 if (ltdb->kv_ops->begin_write(ltdb) != 0) {
418                         goto failed;
419                 }
420
421                 /* error handling for ltdb_baseinfo_init() is by
422                    looking for the record again. */
423                 ltdb_baseinfo_init(module);
424
425                 if (ltdb->kv_ops->finish_write(ltdb) != 0) {
426                         goto failed;
427                 }
428
429                 if (ltdb_search_dn1(module, baseinfo_dn, baseinfo, 0) != LDB_SUCCESS) {
430                         goto failed;
431                 }
432         }
433
434         /* Ignore the result, and update the sequence number */
435         ltdb->kv_ops->has_changed(ltdb);
436
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) {
441                 goto done;
442         }
443         ltdb->sequence_number = seq;
444
445         /* Read an interpret database options */
446         options = ldb_msg_new(ltdb->cache);
447         if (options == NULL) goto failed;
448
449         options_dn = ldb_dn_new(options, ldb, LTDB_OPTIONS);
450         if (options_dn == NULL) goto failed;
451
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) {
455                 goto failed;
456         }
457         
458         /* set flags if they do exist */
459         if (r == LDB_SUCCESS) {
460                 ltdb->check_base = ldb_msg_find_attr_as_bool(options,
461                                                              LTDB_CHECK_BASE,
462                                                              false);
463                 ltdb->disallow_dn_filter = ldb_msg_find_attr_as_bool(options,
464                                                                      LTDB_DISALLOW_DN_FILTER,
465                                                                      false);
466         } else {
467                 ltdb->check_base = false;
468                 ltdb->disallow_dn_filter = false;
469         }
470
471         /*
472          * ltdb_attributes_unload() calls internally talloc_free() on
473          * any non-fixed elemnts in ldb->schema.attributes.
474          *
475          * NOTE WELL: This is per-ldb, not per module, so overwrites
476          * the handlers across all databases when used under Samba's
477          * partition module.
478          */
479         ltdb_attributes_unload(module);
480
481         if (ltdb_index_load(module, ltdb) == -1) {
482                 goto failed;
483         }
484
485         /*
486          * NOTE WELL: This is per-ldb, not per module, so overwrites
487          * the handlers across all databases when used under Samba's
488          * partition module.
489          */
490         if (ltdb_attributes_load(module) == -1) {
491                 goto failed;
492         }
493
494         ltdb->GUID_index_syntax = NULL;
495         if (ltdb->cache->GUID_index_attribute != NULL) {
496                 /*
497                  * Now the attributes are loaded, set the guid_index_syntax.
498                  * This can't fail, it will return a default at worst
499                  */
500                 a = ldb_schema_attribute_by_name(ldb,
501                                                  ltdb->cache->GUID_index_attribute);
502                 ltdb->GUID_index_syntax = a->syntax;
503         }
504
505 done:
506         talloc_free(options);
507         talloc_free(baseinfo);
508         return 0;
509
510 failed:
511         talloc_free(options);
512         talloc_free(baseinfo);
513         return -1;
514 }
515
516
517 /*
518   increase the sequence number to indicate a database change
519 */
520 int ltdb_increase_sequence_number(struct ldb_module *module)
521 {
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];
527         struct ldb_val val;
528         struct ldb_val val_time;
529         time_t t = time(NULL);
530         char *s = NULL;
531         int ret;
532
533         ldb = ldb_module_get_ctx(module);
534
535         msg = ldb_msg_new(ltdb);
536         if (msg == NULL) {
537                 errno = ENOMEM;
538                 return LDB_ERR_OPERATIONS_ERROR;
539         }
540
541         s = talloc_asprintf(msg, "%llu", ltdb->sequence_number+1);
542         if (!s) {
543                 talloc_free(msg);
544                 errno = ENOMEM;
545                 return LDB_ERR_OPERATIONS_ERROR;
546         }
547
548         msg->num_elements = ARRAY_SIZE(el);
549         msg->elements = el;
550         msg->dn = ldb_dn_new(msg, ldb, LTDB_BASEINFO);
551         if (msg->dn == NULL) {
552                 talloc_free(msg);
553                 errno = ENOMEM;
554                 return LDB_ERR_OPERATIONS_ERROR;
555         }
556         el[0].name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER);
557         if (el[0].name == NULL) {
558                 talloc_free(msg);
559                 errno = ENOMEM;
560                 return LDB_ERR_OPERATIONS_ERROR;
561         }
562         el[0].values = &val;
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);
567
568         el[1].name = talloc_strdup(msg, LTDB_MOD_TIMESTAMP);
569         if (el[1].name == NULL) {
570                 talloc_free(msg);
571                 errno = ENOMEM;
572                 return LDB_ERR_OPERATIONS_ERROR;
573         }
574         el[1].values = &val_time;
575         el[1].num_values = 1;
576         el[1].flags = LDB_FLAG_MOD_REPLACE;
577
578         s = ldb_timestring(msg, t);
579         if (s == NULL) {
580                 talloc_free(msg);
581                 return LDB_ERR_OPERATIONS_ERROR;
582         }
583
584         val_time.data = (uint8_t *)s;
585         val_time.length = strlen(s);
586
587         ret = ltdb_modify_internal(module, msg, NULL);
588
589         talloc_free(msg);
590
591         if (ret == LDB_SUCCESS) {
592                 ltdb->sequence_number += 1;
593         }
594
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);
598
599         return ret;
600 }
601
602 int ltdb_check_at_attributes_values(const struct ldb_val *value)
603 {
604         unsigned int i;
605
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)) {
608                         return 0;
609                 }
610         }
611
612         return -1;
613 }
614