From: Volker Lendecke Date: Tue, 10 Dec 2019 09:56:44 +0000 (+0100) Subject: smbd: Fix a leases.tdb record leak X-Git-Tag: ldb-2.1.0~293 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fbd97ee822337534006ffcd14e08c8068e178266;p=thirdparty%2Fsamba.git smbd: Fix a leases.tdb record leak If we set e->stale=true in the share_mode_forall_entries() callback, the share entry will be removed directly. Thus further down share_mode_forall_leases() won't find anything anymore. Only find possibly still connected entries in the first walk, and then remove the share_entries.tdb record straight away after the leases and brlocks have been removed. Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Tue Dec 10 21:57:05 UTC 2019 on sn-devel-184 --- diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c index dacb5efab85..cf972fc4b61 100644 --- a/source3/locking/share_mode_lock.c +++ b/source3/locking/share_mode_lock.c @@ -1217,7 +1217,7 @@ static bool cleanup_disconnected_lease(struct share_mode_entry *e, return false; } -static bool share_mode_cleanup_disconnected_fn( +static bool share_mode_find_connected_fn( struct share_mode_entry *e, bool *modified, void *private_data) @@ -1265,8 +1265,6 @@ static bool share_mode_cleanup_disconnected_fn( return true; } - e->stale = true; - return false; } @@ -1280,6 +1278,7 @@ bool share_mode_cleanup_disconnected(struct file_id fid, bool ret = false; TALLOC_CTX *frame = talloc_stackframe(); struct file_id_buf idbuf; + NTSTATUS status; bool ok; state.lck = get_existing_share_mode_lock(frame, fid); @@ -1291,7 +1290,7 @@ bool share_mode_cleanup_disconnected(struct file_id fid, data = state.lck->data; ok = share_mode_forall_entries( - state.lck, share_mode_cleanup_disconnected_fn, &state); + state.lck, share_mode_find_connected_fn, &state); if (!ok) { DBG_DEBUG("share_mode_forall_entries failed\n"); goto done; @@ -1349,6 +1348,16 @@ bool share_mode_cleanup_disconnected(struct file_id fid, ? "" : data->stream_name, open_persistent_id); + /* + * No connected share entries left, wipe them all + */ + status = dbwrap_delete(share_entries_db, locking_key(&fid)); + if (!NT_STATUS_IS_OK(status)) { + DBG_DEBUG("dbwrap_delete failed: %s\n", + nt_errstr(status)); + goto done; + } + data->num_share_modes = 0; data->modified = true;