LCOV - code coverage report
Current view: top level - lib/ldb/ldb_key_value - ldb_kv_cache.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 296 353 83.9 %
Date: 2024-04-21 15:09:00 Functions: 12 12 100.0 %

          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     1344661 : static void ldb_kv_attributes_unload(struct ldb_module *module)
      60             : {
      61     1391285 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
      62             : 
      63     1344661 :         ldb_schema_attribute_remove_flagged(ldb, LDB_ATTR_FLAG_FROM_DB);
      64             : 
      65     1298037 : }
      66             : 
      67             : /*
      68             :   add up the attrib flags for a @ATTRIBUTES element
      69             : */
      70    29548247 : static int ldb_kv_attributes_flags(struct ldb_message_element *el, unsigned *v)
      71             : {
      72      819510 :         unsigned int i;
      73    29548247 :         unsigned value = 0;
      74    59096494 :         for (i=0;i<el->num_values;i++) {
      75             :                 unsigned int j;
      76    38096861 :                 for (j = 0; ldb_kv_valid_attr_flags[j].name; j++) {
      77    38096861 :                         if (strcmp(ldb_kv_valid_attr_flags[j].name,
      78    38096861 :                                    (char *)el->values[i].data) == 0) {
      79    29548247 :                                 value |= ldb_kv_valid_attr_flags[j].value;
      80    29548247 :                                 break;
      81             :                         }
      82             :                 }
      83    29548247 :                 if (ldb_kv_valid_attr_flags[j].name == NULL) {
      84           0 :                         return -1;
      85             :                 }
      86             :         }
      87    29548247 :         *v = value;
      88    29548247 :         return 0;
      89             : }
      90             : 
      91   196194433 : static int ldb_schema_attribute_compare(const void *p1, const void *p2)
      92             : {
      93   196194433 :         const struct ldb_schema_attribute *sa1 = (const struct ldb_schema_attribute *)p1;
      94   196194433 :         const struct ldb_schema_attribute *sa2 = (const struct ldb_schema_attribute *)p2;
      95   196194433 :         return ldb_attr_cmp(sa1->name, sa2->name);
      96             : }
      97             : 
      98             : /*
      99             :   register any special handlers from @ATTRIBUTES
     100             : */
     101     1330107 : static int ldb_kv_attributes_load(struct ldb_module *module)
     102             : {
     103       45355 :         struct ldb_schema_attribute *attrs;
     104       45355 :         struct ldb_context *ldb;
     105     1330107 :         struct ldb_message *attrs_msg = NULL;
     106       45355 :         struct ldb_dn *dn;
     107       45355 :         unsigned int i;
     108     1330107 :         unsigned int num_loaded_attrs = 0;
     109       45355 :         int r;
     110             : 
     111     1330107 :         ldb = ldb_module_get_ctx(module);
     112             : 
     113     1330107 :         if (ldb->schema.attribute_handler_override) {
     114             :                 /* we skip loading the @ATTRIBUTES record when a module is supplying
     115             :                    its own attribute handling */
     116     1104843 :                 return 0;
     117             :         }
     118             : 
     119      186941 :         attrs_msg = ldb_msg_new(module);
     120      186941 :         if (attrs_msg == NULL) {
     121           0 :                 goto failed;
     122             :         }
     123             : 
     124      186941 :         dn = ldb_dn_new(module, ldb, LDB_KV_ATTRIBUTES);
     125      186941 :         if (dn == NULL) goto failed;
     126             : 
     127      186941 :         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      186941 :         talloc_free(dn);
     133      186941 :         if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
     134           0 :                 goto failed;
     135             :         }
     136      186941 :         if (r == LDB_ERR_NO_SUCH_OBJECT || attrs_msg->num_elements == 0) {
     137       14790 :                 TALLOC_FREE(attrs_msg);
     138       14790 :                 return 0;
     139             :         }
     140             : 
     141      172151 :         attrs = talloc_array(attrs_msg,
     142             :                              struct ldb_schema_attribute,
     143             :                              attrs_msg->num_elements
     144             :                              + ldb->schema.num_attributes);
     145      172151 :         if (attrs == NULL) {
     146           0 :                 goto failed;
     147             :         }
     148             : 
     149      172151 :         memcpy(attrs,
     150      172151 :                ldb->schema.attributes,
     151      172151 :                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    29907366 :         for (i=0;i<attrs_msg->num_elements;i++) {
     156    29735215 :                 unsigned flags = 0, attr_flags = 0;
     157      824678 :                 const char *syntax;
     158      824678 :                 const struct ldb_schema_syntax *s;
     159      824678 :                 const struct ldb_schema_attribute *a =
     160    30559893 :                         ldb_schema_attribute_by_name(ldb,
     161    29735215 :                                                      attrs_msg->elements[i].name);
     162    29735215 :                 if (a != NULL && a->flags & LDB_ATTR_FLAG_FIXED) {
     163             :                         /* Must already be set in the array, and kept */
     164      186968 :                         continue;
     165             :                 }
     166             : 
     167    29548247 :                 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    29548247 :                 if (flags & LDB_KV_FLAG_UNIQUE_INDEX) {
     176         426 :                         attr_flags = LDB_ATTR_FLAG_UNIQUE_INDEX;
     177             :                 }
     178    29548247 :                 flags &= ~LDB_KV_FLAG_UNIQUE_INDEX;
     179             : 
     180             :                 /* These are not currently flags, each is exclusive */
     181    29548247 :                 if (flags == LDB_KV_FLAG_CASE_INSENSITIVE) {
     182    24568336 :                         syntax = LDB_SYNTAX_DIRECTORY_STRING;
     183     4278864 :                 } else if (flags == LDB_KV_FLAG_INTEGER) {
     184        5538 :                         syntax = LDB_SYNTAX_INTEGER;
     185     4154863 :                 } else if (flags == LDB_KV_FLAG_ORDERED_INTEGER) {
     186     4154611 :                         syntax = LDB_SYNTAX_ORDERED_INTEGER;
     187         252 :                 } else if (flags == 0) {
     188         252 :                         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    29548247 :                 s = ldb_standard_syntax_by_name(ldb, syntax);
     198    29548247 :                 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    29548247 :                 attr_flags |= LDB_ATTR_FLAG_ALLOCATED | LDB_ATTR_FLAG_FROM_DB;
     207             : 
     208    30367757 :                 r = ldb_schema_attribute_fill_with_syntax(ldb,
     209             :                                                           attrs,
     210    29548247 :                                                           attrs_msg->elements[i].name,
     211             :                                                           attr_flags, s,
     212    29548247 :                                                           &attrs[num_loaded_attrs + ldb->schema.num_attributes]);
     213    29548247 :                 if (r != 0) {
     214           0 :                         goto failed;
     215             :                 }
     216    29548247 :                 num_loaded_attrs++;
     217             :         }
     218             : 
     219      172151 :         attrs = talloc_realloc(attrs_msg,
     220             :                                attrs, struct ldb_schema_attribute,
     221             :                                num_loaded_attrs + ldb->schema.num_attributes);
     222      172151 :         if (attrs == NULL) {
     223           0 :                 goto failed;
     224             :         }
     225      172151 :         TYPESAFE_QSORT(attrs, num_loaded_attrs + ldb->schema.num_attributes,
     226             :                        ldb_schema_attribute_compare);
     227      172151 :         talloc_unlink(ldb, ldb->schema.attributes);
     228      172151 :         ldb->schema.attributes = talloc_steal(ldb, attrs);
     229      172151 :         ldb->schema.num_attributes = num_loaded_attrs + ldb->schema.num_attributes;
     230      172151 :         TALLOC_FREE(attrs_msg);
     231             : 
     232      172151 :         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     1330109 : static int ldb_kv_index_load(struct ldb_module *module,
     242             :                              struct ldb_kv_private *ldb_kv)
     243             : {
     244     1330109 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     245       45357 :         struct ldb_dn *indexlist_dn;
     246       45357 :         int r, lmdb_subdb_version;
     247             : 
     248     1330109 :         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     1143160 :                 ldb_kv->cache->attribute_indexes = true;
     254     1143160 :                 ldb_kv->cache->one_level_indexes =
     255     1143160 :                     ldb->schema.one_level_indexes;
     256     1143160 :                 ldb_kv->cache->GUID_index_attribute =
     257     1143160 :                     ldb->schema.GUID_index_attribute;
     258     1143160 :                 ldb_kv->cache->GUID_index_dn_component =
     259     1143160 :                     ldb->schema.GUID_index_dn_component;
     260     1143160 :                 return 0;
     261             :         }
     262             : 
     263      186949 :         talloc_free(ldb_kv->cache->indexlist);
     264             : 
     265      186949 :         ldb_kv->cache->indexlist = ldb_msg_new(ldb_kv->cache);
     266      186949 :         if (ldb_kv->cache->indexlist == NULL) {
     267           0 :                 return -1;
     268             :         }
     269      186949 :         ldb_kv->cache->one_level_indexes = false;
     270      186949 :         ldb_kv->cache->attribute_indexes = false;
     271             : 
     272      186949 :         indexlist_dn = ldb_dn_new(ldb_kv, ldb, LDB_KV_INDEXLIST);
     273      186949 :         if (indexlist_dn == NULL) {
     274           0 :                 return -1;
     275             :         }
     276             : 
     277      193989 :         r = ldb_kv_search_dn1(module,
     278             :                               indexlist_dn,
     279      186949 :                               ldb_kv->cache->indexlist,
     280             :                               LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC |
     281             :                                   LDB_UNPACK_DATA_FLAG_NO_DN);
     282      186949 :         TALLOC_FREE(indexlist_dn);
     283             : 
     284      186949 :         if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
     285           0 :                 return -1;
     286             :         }
     287             : 
     288      186949 :         if (ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXONE) !=
     289             :             NULL) {
     290       49742 :                 ldb_kv->cache->one_level_indexes = true;
     291             :         }
     292      186949 :         if (ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXATTR) !=
     293             :             NULL) {
     294      180653 :                 ldb_kv->cache->attribute_indexes = true;
     295             :         }
     296      373898 :         ldb_kv->cache->GUID_index_attribute = ldb_msg_find_attr_as_string(
     297      186949 :             ldb_kv->cache->indexlist, LDB_KV_IDXGUID, NULL);
     298      373898 :         ldb_kv->cache->GUID_index_dn_component = ldb_msg_find_attr_as_string(
     299      186949 :             ldb_kv->cache->indexlist, LDB_KV_IDX_DN_GUID, NULL);
     300             : 
     301      193989 :         lmdb_subdb_version = ldb_msg_find_attr_as_int(
     302      186949 :             ldb_kv->cache->indexlist, LDB_KV_IDX_LMDB_SUBDB, 0);
     303             : 
     304      186949 :         if (lmdb_subdb_version != 0) {
     305           2 :                 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           2 :                 return -1;
     312             :         }
     313             : 
     314      179909 :         return 0;
     315             : }
     316             : 
     317             : /*
     318             :   initialise the baseinfo record
     319             : */
     320        6142 : static int ldb_kv_baseinfo_init(struct ldb_module *module)
     321             : {
     322         670 :         struct ldb_context *ldb;
     323        6142 :         void *data = ldb_module_get_private(module);
     324         670 :         struct ldb_kv_private *ldb_kv =
     325        6142 :             talloc_get_type(data, struct ldb_kv_private);
     326         670 :         struct ldb_message *msg;
     327         670 :         struct ldb_message_element el;
     328         670 :         struct ldb_val val;
     329         670 :         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        6142 :         const char *initial_sequence_number = "1";
     334             : 
     335        6142 :         ldb = ldb_module_get_ctx(module);
     336             : 
     337        6142 :         ldb_kv->sequence_number = atof(initial_sequence_number);
     338             : 
     339        6142 :         msg = ldb_msg_new(ldb_kv);
     340        6142 :         if (msg == NULL) {
     341           0 :                 goto failed;
     342             :         }
     343             : 
     344        6142 :         msg->num_elements = 1;
     345        6142 :         msg->elements = &el;
     346        6142 :         msg->dn = ldb_dn_new(msg, ldb, LDB_KV_BASEINFO);
     347        6142 :         if (!msg->dn) {
     348           0 :                 goto failed;
     349             :         }
     350        6142 :         el.name = talloc_strdup(msg, LDB_KV_SEQUENCE_NUMBER);
     351        6142 :         if (!el.name) {
     352           0 :                 goto failed;
     353             :         }
     354        6142 :         el.values = &val;
     355        6142 :         el.num_values = 1;
     356        6142 :         el.flags = 0;
     357        6142 :         val.data = (uint8_t *)talloc_strdup(msg, initial_sequence_number);
     358        6142 :         if (!val.data) {
     359           0 :                 goto failed;
     360             :         }
     361        6142 :         val.length = 1;
     362             : 
     363        6142 :         ret = ldb_kv_store(module, msg, TDB_INSERT);
     364             : 
     365        6142 :         talloc_free(msg);
     366             : 
     367        6142 :         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       14552 : static void ldb_kv_cache_free(struct ldb_module *module)
     379             : {
     380       14552 :         void *data = ldb_module_get_private(module);
     381        1267 :         struct ldb_kv_private *ldb_kv =
     382       14552 :             talloc_get_type(data, struct ldb_kv_private);
     383             : 
     384       14552 :         ldb_kv->sequence_number = 0;
     385       14552 :         talloc_free(ldb_kv->cache);
     386       14552 :         ldb_kv->cache = NULL;
     387       14552 : }
     388             : 
     389             : /*
     390             :   force a cache reload
     391             : */
     392       14552 : int ldb_kv_cache_reload(struct ldb_module *module)
     393             : {
     394       14552 :         ldb_kv_attributes_unload(module);
     395       14552 :         ldb_kv_cache_free(module);
     396       14552 :         return ldb_kv_cache_load(module);
     397             : }
     398    50572892 : static int get_pack_format_version(struct ldb_val key,
     399             :                                    struct ldb_val data,
     400             :                                    void *private_data)
     401             : {
     402    50572892 :         uint32_t *v = (uint32_t *) private_data;
     403    50572892 :         return ldb_unpack_get_format(&data, v);
     404             : }
     405             : 
     406             : /*
     407             :   load the cache records
     408             : */
     409   133457965 : int ldb_kv_cache_load(struct ldb_module *module)
     410             : {
     411     4440149 :         struct ldb_context *ldb;
     412   133457965 :         void *data = ldb_module_get_private(module);
     413     4440149 :         struct ldb_kv_private *ldb_kv =
     414   133457965 :             talloc_get_type(data, struct ldb_kv_private);
     415   133457965 :         struct ldb_dn *baseinfo_dn = NULL, *options_dn = NULL;
     416     4440149 :         uint64_t seq;
     417   133457965 :         struct ldb_message *baseinfo = NULL, *options = NULL;
     418     4440149 :         const struct ldb_schema_attribute *a;
     419   133457965 :         bool have_write_txn = false;
     420     4440149 :         int r;
     421     4440149 :         struct ldb_val key;
     422             : 
     423   133457965 :         ldb = ldb_module_get_ctx(module);
     424             : 
     425             :         /* a very fast check to avoid extra database reads */
     426   133457965 :         if (ldb_kv->cache != NULL && !ldb_kv->kv_ops->has_changed(ldb_kv)) {
     427    80166927 :                 return 0;
     428             :         }
     429             : 
     430    50579034 :         if (ldb_kv->cache == NULL) {
     431     1206657 :                 ldb_kv->cache = talloc_zero(ldb_kv, struct ldb_kv_cache);
     432     1206657 :                 if (ldb_kv->cache == NULL)
     433           0 :                         goto failed;
     434             :         }
     435             : 
     436    50579034 :         baseinfo = ldb_msg_new(ldb_kv->cache);
     437    50579034 :         if (baseinfo == NULL) goto failed;
     438             : 
     439    50579034 :         baseinfo_dn = ldb_dn_new(baseinfo, ldb, LDB_KV_BASEINFO);
     440    50579034 :         if (baseinfo_dn == NULL) goto failed;
     441             : 
     442    50579034 :         r = ldb_kv->kv_ops->lock_read(module);
     443    50579034 :         if (r != LDB_SUCCESS) {
     444           0 :                 goto failed;
     445             :         }
     446             : 
     447    50579034 :         key = ldb_kv_key_dn(baseinfo, baseinfo_dn);
     448    50579034 :         if (!key.data) {
     449           0 :                 goto failed_and_unlock;
     450             :         }
     451             : 
     452             :         /* Read packing format from first 4 bytes of @BASEINFO record */
     453    52307179 :         r = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key,
     454             :                                             get_pack_format_version,
     455    50579034 :                                             &ldb_kv->pack_format_version);
     456             : 
     457             :         /* possibly initialise the baseinfo */
     458    50579034 :         if (r == LDB_ERR_NO_SUCH_OBJECT) {
     459             : 
     460             :                 /* Give up the read lock, try again with a write lock */
     461        6142 :                 r = ldb_kv->kv_ops->unlock_read(module);
     462        6142 :                 if (r != LDB_SUCCESS) {
     463           0 :                         goto failed;
     464             :                 }
     465             : 
     466        6142 :                 if (ldb_kv->kv_ops->begin_write(ldb_kv) != 0) {
     467           0 :                         goto failed;
     468             :                 }
     469             : 
     470        6142 :                 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        6142 :                 ldb_kv->pack_format_version = LDB_PACKING_FORMAT;
     477        6142 :                 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        6142 :                 ldb_kv_baseinfo_init(module);
     482             : 
     483    50572892 :         } 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    50579034 :         r = ldb_kv_search_dn1(module, baseinfo_dn, baseinfo, 0);
     489    50579034 :         if (r != LDB_SUCCESS) {
     490           0 :                 goto failed_and_unlock;
     491             :         }
     492             : 
     493             :         /* Ignore the result, and update the sequence number */
     494    50579034 :         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    50579034 :         seq = ldb_msg_find_attr_as_uint64(baseinfo, LDB_KV_SEQUENCE_NUMBER, 0);
     499    50579034 :         if (seq == ldb_kv->sequence_number) {
     500    49248925 :                 goto done;
     501             :         }
     502     1330109 :         ldb_kv->sequence_number = seq;
     503             : 
     504             :         /* Read an interpret database options */
     505             : 
     506     1330109 :         options = ldb_msg_new(ldb_kv->cache);
     507     1330109 :         if (options == NULL) goto failed_and_unlock;
     508             : 
     509     1330109 :         options_dn = ldb_dn_new(options, ldb, LDB_KV_OPTIONS);
     510     1330109 :         if (options_dn == NULL) goto failed_and_unlock;
     511             : 
     512     1330109 :         r = ldb_kv_search_dn1(module, options_dn, options, 0);
     513     1330109 :         talloc_free(options_dn);
     514     1330109 :         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     1330109 :         if (r == LDB_SUCCESS) {
     520     1229239 :                 ldb_kv->check_base =
     521     1189804 :                     ldb_msg_find_attr_as_bool(options, LDB_KV_CHECK_BASE, false);
     522     1189804 :                 ldb_kv->disallow_dn_filter = ldb_msg_find_attr_as_bool(
     523             :                     options, LDB_KV_DISALLOW_DN_FILTER, false);
     524             :         } else {
     525      140305 :                 ldb_kv->check_base = false;
     526      140305 :                 ldb_kv->disallow_dn_filter = false;
     527             :         }
     528             : 
     529             :         /*
     530             :          * ltdb_attributes_unload() calls internally talloc_free() on
     531             :          * any non-fixed elements 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     1330109 :         ldb_kv_attributes_unload(module);
     538             : 
     539     1330109 :         if (ldb_kv_index_load(module, ldb_kv) == -1) {
     540           2 :                 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     1330107 :         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     1330107 :         ldb_kv->GUID_index_syntax = NULL;
     558     1330107 :         if (ldb_kv->cache->GUID_index_attribute != NULL) {
     559     1194301 :                 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     1194301 :                 a = ldb_schema_attribute_by_name(
     566     1154416 :                     ldb, ldb_kv->cache->GUID_index_attribute);
     567     1194301 :                 ldb_kv->GUID_index_syntax = a->syntax;
     568             :         } else {
     569      135806 :                 ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT;
     570             :         }
     571             : 
     572    50579032 : done:
     573    50579032 :         if (have_write_txn) {
     574        6142 :                 if (ldb_kv->kv_ops->finish_write(ldb_kv) != 0) {
     575           0 :                         goto failed;
     576             :                 }
     577             :         } else {
     578    50572890 :                 ldb_kv->kv_ops->unlock_read(module);
     579             :         }
     580             : 
     581    50579032 :         talloc_free(options);
     582    50579032 :         talloc_free(baseinfo);
     583    50579032 :         return 0;
     584             : 
     585           2 : failed_and_unlock:
     586           2 :         if (have_write_txn) {
     587           0 :                 ldb_kv->kv_ops->abort_write(ldb_kv);
     588             :         } else {
     589           2 :                 ldb_kv->kv_ops->unlock_read(module);
     590             :         }
     591             : 
     592           2 : failed:
     593           2 :         talloc_free(options);
     594           2 :         talloc_free(baseinfo);
     595           2 :         return -1;
     596             : }
     597             : 
     598             : 
     599             : /*
     600             :   increase the sequence number to indicate a database change
     601             : */
     602     2524936 : int ldb_kv_increase_sequence_number(struct ldb_module *module)
     603             : {
     604      121604 :         struct ldb_context *ldb;
     605     2524936 :         void *data = ldb_module_get_private(module);
     606      121604 :         struct ldb_kv_private *ldb_kv =
     607     2524936 :             talloc_get_type(data, struct ldb_kv_private);
     608      121604 :         struct ldb_message *msg;
     609      121604 :         struct ldb_message_element el[2];
     610      121604 :         struct ldb_val val;
     611      121604 :         struct ldb_val val_time;
     612     2524936 :         time_t t = time(NULL);
     613     2524936 :         char *s = NULL;
     614      121604 :         int ret;
     615             : 
     616     2524936 :         ldb = ldb_module_get_ctx(module);
     617             : 
     618     2524936 :         msg = ldb_msg_new(ldb_kv);
     619     2524936 :         if (msg == NULL) {
     620           0 :                 errno = ENOMEM;
     621           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     622             :         }
     623             : 
     624     2524936 :         s = talloc_asprintf(msg, "%llu", ldb_kv->sequence_number + 1);
     625     2524936 :         if (!s) {
     626           0 :                 talloc_free(msg);
     627           0 :                 errno = ENOMEM;
     628           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     629             :         }
     630             : 
     631     2524936 :         msg->num_elements = ARRAY_SIZE(el);
     632     2524936 :         msg->elements = el;
     633     2524936 :         msg->dn = ldb_dn_new(msg, ldb, LDB_KV_BASEINFO);
     634     2524936 :         if (msg->dn == NULL) {
     635           0 :                 talloc_free(msg);
     636           0 :                 errno = ENOMEM;
     637           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     638             :         }
     639     2524936 :         el[0].name = talloc_strdup(msg, LDB_KV_SEQUENCE_NUMBER);
     640     2524936 :         if (el[0].name == NULL) {
     641           0 :                 talloc_free(msg);
     642           0 :                 errno = ENOMEM;
     643           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     644             :         }
     645     2524936 :         el[0].values = &val;
     646     2524936 :         el[0].num_values = 1;
     647     2524936 :         el[0].flags = LDB_FLAG_MOD_REPLACE;
     648     2524936 :         val.data = (uint8_t *)s;
     649     2524936 :         val.length = strlen(s);
     650             : 
     651     2524936 :         el[1].name = talloc_strdup(msg, LDB_KV_MOD_TIMESTAMP);
     652     2524936 :         if (el[1].name == NULL) {
     653           0 :                 talloc_free(msg);
     654           0 :                 errno = ENOMEM;
     655           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     656             :         }
     657     2524936 :         el[1].values = &val_time;
     658     2524936 :         el[1].num_values = 1;
     659     2524936 :         el[1].flags = LDB_FLAG_MOD_REPLACE;
     660             : 
     661     2524936 :         s = ldb_timestring(msg, t);
     662     2524936 :         if (s == NULL) {
     663           0 :                 talloc_free(msg);
     664           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     665             :         }
     666             : 
     667     2524936 :         val_time.data = (uint8_t *)s;
     668     2524936 :         val_time.length = strlen(s);
     669             : 
     670     2524936 :         ret = ldb_kv_modify_internal(module, msg, NULL);
     671             : 
     672     2524936 :         talloc_free(msg);
     673             : 
     674     2524936 :         if (ret == LDB_SUCCESS) {
     675     2524936 :                 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     2524936 :         ldb_kv->kv_ops->has_changed(ldb_kv);
     681             : 
     682     2524936 :         return ret;
     683             : }
     684             : 
     685     1839119 : int ldb_kv_check_at_attributes_values(const struct ldb_val *value)
     686             : {
     687      207940 :         unsigned int i;
     688             : 
     689     2387347 :         for (i = 0; ldb_kv_valid_attr_flags[i].name != NULL; i++) {
     690     2387346 :                 if ((strcmp(ldb_kv_valid_attr_flags[i].name,
     691     2387346 :                             (char *)value->data) == 0)) {
     692     1631179 :                         return 0;
     693             :                 }
     694             :         }
     695             : 
     696           0 :         return -1;
     697             : }

Generated by: LCOV version 1.14