]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Fix a leases.tdb record leak
authorVolker Lendecke <vl@samba.org>
Tue, 10 Dec 2019 09:56:44 +0000 (10:56 +0100)
committerJeremy Allison <jra@samba.org>
Tue, 10 Dec 2019 21:57:05 +0000 (21:57 +0000)
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 <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Tue Dec 10 21:57:05 UTC 2019 on sn-devel-184

source3/locking/share_mode_lock.c

index dacb5efab8519788ad95dcaea43793236003dc32..cf972fc4b618fa98cdfba986dc542ea8975ae7a7 100644 (file)
@@ -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;