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