diff options
-rw-r--r-- | lib/ldb/common/ldb_pack.c | 23 | ||||
-rw-r--r-- | lib/ldb/include/ldb_module.h | 9 | ||||
-rw-r--r-- | lib/ldb/ldb_key_value/ldb_kv.c | 2 | ||||
-rw-r--r-- | lib/ldb/ldb_key_value/ldb_kv.h | 1 | ||||
-rw-r--r-- | lib/ldb/ldb_key_value/ldb_kv_cache.c | 37 |
5 files changed, 64 insertions, 8 deletions
diff --git a/lib/ldb/common/ldb_pack.c b/lib/ldb/common/ldb_pack.c index 5360a36cccc..e59c542fc5b 100644 --- a/lib/ldb/common/ldb_pack.c +++ b/lib/ldb/common/ldb_pack.c @@ -33,12 +33,6 @@ #include "ldb_private.h" -/* change this if the data format ever changes */ -#define LDB_PACKING_FORMAT 0x26011967 - -/* old packing formats */ -#define LDB_PACKING_FORMAT_NODN 0x26011966 - /* use a portable integer format */ static void put_uint32(uint8_t *p, int ofs, unsigned int val) { @@ -195,7 +189,7 @@ int ldb_unpack_data_flags(struct ldb_context *ldb, size_t remaining; size_t dn_len; unsigned int i, j; - unsigned format; + uint32_t format; unsigned int nelem = 0; size_t len; struct ldb_val *ldb_val_single_array = NULL; @@ -208,7 +202,10 @@ int ldb_unpack_data_flags(struct ldb_context *ldb, goto failed; } - format = pull_uint32(p, 0); + if (ldb_unpack_get_format(data, &format) != LDB_SUCCESS) { + errno = EIO; + goto failed; + } message->num_elements = pull_uint32(p, 4); p += 8; @@ -402,6 +399,16 @@ failed: return -1; } +int ldb_unpack_get_format(const struct ldb_val *data, + uint32_t *pack_format_version) +{ + if (data->length < 4) { + return LDB_ERR_OPERATIONS_ERROR; + } + *pack_format_version = pull_uint32(data->data, 0); + return LDB_SUCCESS; +} + /* * Unpack a ldb message from a linear buffer in ldb_val * diff --git a/lib/ldb/include/ldb_module.h b/lib/ldb/include/ldb_module.h index 759a54a3169..d9114e99e34 100644 --- a/lib/ldb/include/ldb_module.h +++ b/lib/ldb/include/ldb_module.h @@ -544,12 +544,21 @@ int ldb_unpack_data_flags(struct ldb_context *ldb, struct ldb_message *message, unsigned int flags); +int ldb_unpack_get_format(const struct ldb_val *data, + uint32_t *pack_format_version); + /* currently unused (was NO_DATA_ALLOC) 0x0001 */ #define LDB_UNPACK_DATA_FLAG_NO_DN 0x0002 #define LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC 0x0004 #define LDB_UNPACK_DATA_FLAG_NO_ATTRS 0x0008 #define LDB_UNPACK_DATA_FLAG_READ_LOCKED 0x0010 +/* In-use packing formats */ +#define LDB_PACKING_FORMAT 0x26011967 + +/* Old packing formats */ +#define LDB_PACKING_FORMAT_NODN 0x26011966 + /** Forces a specific ldb handle to use the global event context. diff --git a/lib/ldb/ldb_key_value/ldb_kv.c b/lib/ldb/ldb_key_value/ldb_kv.c index 53c326d36b2..81a77462c83 100644 --- a/lib/ldb/ldb_key_value/ldb_kv.c +++ b/lib/ldb/ldb_key_value/ldb_kv.c @@ -1894,6 +1894,8 @@ int ldb_kv_init_store(struct ldb_kv_private *ldb_kv, ldb_kv->sequence_number = 0; + ldb_kv->pack_format_version = LDB_PACKING_FORMAT; + ldb_kv->pid = getpid(); ldb_kv->module = ldb_module_new(ldb, ldb, name, &ldb_kv_ops); diff --git a/lib/ldb/ldb_key_value/ldb_kv.h b/lib/ldb/ldb_key_value/ldb_kv.h index 97bdcf09875..c9e55321d0d 100644 --- a/lib/ldb/ldb_key_value/ldb_kv.h +++ b/lib/ldb/ldb_key_value/ldb_kv.h @@ -63,6 +63,7 @@ struct ldb_kv_private { unsigned int connect_flags; unsigned long long sequence_number; + uint32_t pack_format_version; /* the low level tdb seqnum - used to avoid loading BASEINFO when possible */ diff --git a/lib/ldb/ldb_key_value/ldb_kv_cache.c b/lib/ldb/ldb_key_value/ldb_kv_cache.c index b14697c2a5e..c5f661113fd 100644 --- a/lib/ldb/ldb_key_value/ldb_kv_cache.c +++ b/lib/ldb/ldb_key_value/ldb_kv_cache.c @@ -395,6 +395,13 @@ int ldb_kv_cache_reload(struct ldb_module *module) ldb_kv_cache_free(module); return ldb_kv_cache_load(module); } +static int get_pack_format_version(struct ldb_val key, + struct ldb_val data, + void *private_data) +{ + uint32_t *v = (uint32_t *) private_data; + return ldb_unpack_get_format(&data, v); +} /* load the cache records @@ -411,6 +418,8 @@ int ldb_kv_cache_load(struct ldb_module *module) const struct ldb_schema_attribute *a; bool have_write_txn = false; int r; + uint32_t pack_format_version; + struct ldb_val key; ldb = ldb_module_get_ctx(module); @@ -435,6 +444,34 @@ int ldb_kv_cache_load(struct ldb_module *module) if (r != LDB_SUCCESS) { goto failed; } + + key = ldb_kv_key_dn(module, baseinfo, baseinfo_dn); + if (!key.data) { + goto failed_and_unlock; + } + + /* Read packing format from first 4 bytes of @BASEINFO record */ + r = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, + get_pack_format_version, + &pack_format_version); + + if (r != LDB_ERR_NO_SUCH_OBJECT) { + if (r != LDB_SUCCESS) { + goto failed_and_unlock; + } + + /* Make sure the database has the right format */ + if (pack_format_version != ldb_kv->pack_format_version) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Unexpected packing format. " + "Expected: %#010x, Got: %#010x", + pack_format_version, + ldb_kv->pack_format_version); + goto failed_and_unlock; + } + } + + /* Now fetch the whole @BASEINFO record */ r = ldb_kv_search_dn1(module, baseinfo_dn, baseinfo, 0); if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { goto failed_and_unlock; |