summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2018-05-04 14:35:14 +1200
committerAndrew Bartlett <abartlet@samba.org>2018-05-09 04:29:48 +0200
commit1174b52b91de045b5c111dff97c49488ac963bfa (patch)
treeedcfc6278291c9efd8b53736e1a967ba0f968d32
parent4e78aeedb8329953df83fc7f2c191b2c97a051d0 (diff)
downloadsamba-1174b52b91de045b5c111dff97c49488ac963bfa.tar.gz
ldb_tdb: Prevent ldb_tdb reuse after a fork()
We may relax this restriction in the future, but for now do not assume that the caller has done a tdb_reopen_all() at the right time. Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Garming Sam <garming@catalyst.net.nz>
-rw-r--r--lib/ldb/ldb_tdb/ldb_tdb.c111
-rw-r--r--lib/ldb/ldb_tdb/ldb_tdb.h7
2 files changed, 109 insertions, 9 deletions
diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c
index 0833a4fd0ca..93fc96faca3 100644
--- a/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -100,6 +100,17 @@ static int ltdb_lock_read(struct ldb_module *module)
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
int tdb_ret = 0;
int ret;
+ pid_t pid = getpid();
+
+ if (ltdb->pid != pid) {
+ ldb_asprintf_errstring(
+ ldb_module_get_ctx(module),
+ __location__": Reusing ldb opend by pid %d in "
+ "process %d\n",
+ ltdb->pid,
+ pid);
+ return LDB_ERR_PROTOCOL_ERROR;
+ }
if (tdb_transaction_active(ltdb->tdb) == false &&
ltdb->read_lock_count == 0) {
@@ -128,6 +139,17 @@ static int ltdb_unlock_read(struct ldb_module *module)
{
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
+ pid_t pid = getpid();
+
+ if (ltdb->pid != pid) {
+ ldb_asprintf_errstring(
+ ldb_module_get_ctx(module),
+ __location__": Reusing ldb opend by pid %d in "
+ "process %d\n",
+ ltdb->pid,
+ pid);
+ return LDB_ERR_PROTOCOL_ERROR;
+ }
if (!tdb_transaction_active(ltdb->tdb) && ltdb->read_lock_count == 1) {
tdb_unlockall_read(ltdb->tdb);
ltdb->read_lock_count--;
@@ -1447,21 +1469,69 @@ static int ltdb_rename(struct ltdb_context *ctx)
static int ltdb_tdb_transaction_start(struct ltdb_private *ltdb)
{
+ pid_t pid = getpid();
+
+ if (ltdb->pid != pid) {
+ ldb_asprintf_errstring(
+ ldb_module_get_ctx(ltdb->module),
+ __location__": Reusing ldb opend by pid %d in "
+ "process %d\n",
+ ltdb->pid,
+ pid);
+ return LDB_ERR_PROTOCOL_ERROR;
+ }
+
return tdb_transaction_start(ltdb->tdb);
}
static int ltdb_tdb_transaction_cancel(struct ltdb_private *ltdb)
{
+ pid_t pid = getpid();
+
+ if (ltdb->pid != pid) {
+ ldb_asprintf_errstring(
+ ldb_module_get_ctx(ltdb->module),
+ __location__": Reusing ldb opend by pid %d in "
+ "process %d\n",
+ ltdb->pid,
+ pid);
+ return LDB_ERR_PROTOCOL_ERROR;
+ }
+
return tdb_transaction_cancel(ltdb->tdb);
}
static int ltdb_tdb_transaction_prepare_commit(struct ltdb_private *ltdb)
{
+ pid_t pid = getpid();
+
+ if (ltdb->pid != pid) {
+ ldb_asprintf_errstring(
+ ldb_module_get_ctx(ltdb->module),
+ __location__": Reusing ldb opend by pid %d in "
+ "process %d\n",
+ ltdb->pid,
+ pid);
+ return LDB_ERR_PROTOCOL_ERROR;
+ }
+
return tdb_transaction_prepare_commit(ltdb->tdb);
}
static int ltdb_tdb_transaction_commit(struct ltdb_private *ltdb)
{
+ pid_t pid = getpid();
+
+ if (ltdb->pid != pid) {
+ ldb_asprintf_errstring(
+ ldb_module_get_ctx(ltdb->module),
+ __location__": Reusing ldb opend by pid %d in "
+ "process %d\n",
+ ltdb->pid,
+ pid);
+ return LDB_ERR_PROTOCOL_ERROR;
+ }
+
return tdb_transaction_commit(ltdb->tdb);
}
@@ -1470,6 +1540,18 @@ 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);
+ pid_t pid = getpid();
+
+ if (ltdb->pid != pid) {
+ ldb_asprintf_errstring(
+ ldb_module_get_ctx(ltdb->module),
+ __location__": Reusing ldb opend by pid %d in "
+ "process %d\n",
+ ltdb->pid,
+ pid);
+ return LDB_ERR_PROTOCOL_ERROR;
+ }
+
/* Do not take out the transaction lock on a read-only DB */
if (ltdb->read_only) {
return LDB_ERR_UNWILLING_TO_PERFORM;
@@ -1498,6 +1580,17 @@ static int ltdb_prepare_commit(struct ldb_module *module)
int ret;
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
+ pid_t pid = getpid();
+
+ if (ltdb->pid != pid) {
+ ldb_asprintf_errstring(
+ ldb_module_get_ctx(module),
+ __location__": Reusing ldb opend by pid %d in "
+ "process %d\n",
+ ltdb->pid,
+ pid);
+ return LDB_ERR_PROTOCOL_ERROR;
+ }
if (!ltdb->kv_ops->transaction_active(ltdb)) {
ldb_set_errstring(ldb_module_get_ctx(module),
@@ -2138,8 +2231,6 @@ int init_store(struct ltdb_private *ltdb,
const char *options[],
struct ldb_module **_module)
{
- struct ldb_module *module;
-
if (getenv("LDB_WARN_UNINDEXED")) {
ltdb->warn_unindexed = true;
}
@@ -2150,23 +2241,25 @@ int init_store(struct ltdb_private *ltdb,
ltdb->sequence_number = 0;
- module = ldb_module_new(ldb, ldb, name, &ltdb_ops);
- if (!module) {
+ ltdb->pid = getpid();
+
+ ltdb->module = ldb_module_new(ldb, ldb, name, &ltdb_ops);
+ if (!ltdb->module) {
ldb_oom(ldb);
talloc_free(ltdb);
return LDB_ERR_OPERATIONS_ERROR;
}
- ldb_module_set_private(module, ltdb);
- talloc_steal(module, ltdb);
+ ldb_module_set_private(ltdb->module, ltdb);
+ talloc_steal(ltdb->module, ltdb);
- if (ltdb_cache_load(module) != 0) {
+ if (ltdb_cache_load(ltdb->module) != 0) {
ldb_asprintf_errstring(ldb, "Unable to load ltdb cache "
"records for backend '%s'", name);
- talloc_free(module);
+ talloc_free(ltdb->module);
return LDB_ERR_OPERATIONS_ERROR;
}
- *_module = module;
+ *_module = ltdb->module;
/*
* Set or override the maximum key length
*
diff --git a/lib/ldb/ldb_tdb/ldb_tdb.h b/lib/ldb/ldb_tdb/ldb_tdb.h
index 4d531208da6..caaa67a98e1 100644
--- a/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -36,6 +36,7 @@ struct kv_db_ops {
ldb_context */
struct ltdb_private {
const struct kv_db_ops *kv_ops;
+ struct ldb_module *module;
TDB_CONTEXT *tdb;
unsigned int connect_flags;
@@ -75,6 +76,12 @@ struct ltdb_private {
* greater than this length will be rejected.
*/
unsigned max_key_length;
+
+ /*
+ * The PID that opened this database so we don't work in a
+ * fork()ed child.
+ */
+ pid_t pid;
};
struct ltdb_context {