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

Generated by: LCOV version 1.13