1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-26 10:04:02 +03:00

ldb_tdb: Change ltdb_connect() NOT to request a kernel-level read only TDB

We support opening and LDB multiple times in a process, but do not support this in tdb.

As we can open the ldb with different flags, we must ensure a later read-write
open is possible.

Additionally, a read-only TDB will refuse the all-record lock, preventing
the ldb from even loading.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13033

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
This commit is contained in:
Andrew Bartlett 2017-09-18 10:43:32 +12:00 committed by Douglas Bagnall
parent 13777d35d0
commit 22854f9b8d
3 changed files with 52 additions and 8 deletions

View File

@ -310,6 +310,11 @@ static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn,
rec.dptr = (uint8_t *)&list2;
rec.dsize = sizeof(void *);
/*
* This is not a store into the main DB, but into an in-memory
* TDB, so we don't need a guard on ltdb->read_only
*/
ret = tdb_store(ltdb->idxptr->itdb, key, rec, TDB_INSERT);
if (ret != 0) {
return ltdb_err_map(tdb_error(ltdb->idxptr->itdb));
@ -1760,6 +1765,14 @@ int ltdb_reindex(struct ldb_module *module)
int ret;
struct ltdb_reindex_context ctx;
/*
* Only triggered after a modification, but make clear we do
* not re-index a read-only DB
*/
if (ltdb->read_only) {
return LDB_ERR_UNWILLING_TO_PERFORM;
}
if (ltdb_cache_reload(module) != 0) {
return LDB_ERR_OPERATIONS_ERROR;
}

View File

@ -308,6 +308,10 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg
struct ldb_val ldb_data;
int ret = LDB_SUCCESS;
if (ltdb->read_only) {
return LDB_ERR_UNWILLING_TO_PERFORM;
}
tdb_key = ltdb_key(module, msg->dn);
if (tdb_key.dptr == NULL) {
return LDB_ERR_OTHER;
@ -476,6 +480,10 @@ int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn)
TDB_DATA tdb_key;
int ret;
if (ltdb->read_only) {
return LDB_ERR_UNWILLING_TO_PERFORM;
}
tdb_key = ltdb_key(module, dn);
if (!tdb_key.dptr) {
return LDB_ERR_OTHER;
@ -1165,6 +1173,11 @@ static int ltdb_start_trans(struct ldb_module *module)
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
/* Do not take out the transaction lock on a read-only DB */
if (ltdb->read_only) {
return LDB_ERR_UNWILLING_TO_PERFORM;
}
if (tdb_transaction_start(ltdb->tdb) != 0) {
return ltdb_err_map(tdb_error(ltdb->tdb));
}
@ -1648,20 +1661,36 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url,
tdb_flags |= TDB_NOMMAP;
}
if (flags & LDB_FLG_RDONLY) {
open_flags = O_RDONLY;
} else if (flags & LDB_FLG_DONT_CREATE_DB) {
open_flags = O_RDWR;
} else {
open_flags = O_CREAT | O_RDWR;
}
ltdb = talloc_zero(ldb, struct ltdb_private);
if (!ltdb) {
ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
if (flags & LDB_FLG_RDONLY) {
/*
* This is weird, but because we can only have one tdb
* in this process, and the other one could be
* read-write, we can't use the tdb readonly. Plus a
* read only tdb prohibits the all-record lock.
*/
open_flags = O_RDWR;
ltdb->read_only = true;
} else if (flags & LDB_FLG_DONT_CREATE_DB) {
/*
* This is used by ldbsearch to prevent creation of the database
* if the name is wrong
*/
open_flags = O_RDWR;
} else {
/*
* This is the normal case
*/
open_flags = O_CREAT | O_RDWR;
}
/* note that we use quite a large default hash size */
ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000,
tdb_flags, open_flags,

View File

@ -32,6 +32,8 @@ struct ltdb_private {
bool warn_unindexed;
bool warn_reindex;
bool read_only;
};
struct ltdb_context {