]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:smbd: allow close_file() with a non-fsa fsp for {SHUTDOWN,ERROR}_CLOSE
authorStefan Metzmacher <metze@samba.org>
Wed, 23 Dec 2020 11:10:37 +0000 (12:10 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 14 Jan 2021 11:30:38 +0000 (11:30 +0000)
Such an fsp was typically created via create_internal_fsp() and
opened via fd_openat() without going through SMB_VFS_CREATE_FILE(),
so they should be closed via fd_close().

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/close.c

index 83b75677d9296d56695f19d3363ae333955d108b..97d1347308245cda3d7042747779ecb39ed2262e 100644 (file)
@@ -1337,15 +1337,28 @@ NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
                }
        }
 
-       if (fsp->fsp_flags.is_directory) {
-               status = close_directory(req, fsp, close_type);
-       } else if (fsp->fake_file_handle != NULL) {
+       if (fsp->fake_file_handle != NULL) {
                status = close_fake_file(req, fsp);
        } else if (fsp->print_file != NULL) {
                /* FIXME: return spool errors */
                print_spool_end(fsp, close_type);
                file_free(req, fsp);
                status = NT_STATUS_OK;
+       } else if (!fsp->fsp_flags.is_fsa) {
+               if (close_type == NORMAL_CLOSE) {
+                       DBG_ERR("unexpected NORMAL_CLOSE for [%s] "
+                               "is_fsa[%u] is_pathref[%u] is_directory[%u]\n",
+                               fsp_str_dbg(fsp),
+                               fsp->fsp_flags.is_fsa,
+                               fsp->fsp_flags.is_pathref,
+                               fsp->fsp_flags.is_directory);
+               }
+               SMB_ASSERT(close_type != NORMAL_CLOSE);
+               fd_close(fsp);
+               file_free(req, fsp);
+               status = NT_STATUS_OK;
+       } else if (fsp->fsp_flags.is_directory) {
+               status = close_directory(req, fsp, close_type);
        } else {
                status = close_normal_file(req, fsp, close_type);
        }