smbd: add need_fsa arg and logic to file_find_di_(first|next)
authorRalph Boehme <slow@samba.org>
Thu, 19 Nov 2020 10:35:23 +0000 (11:35 +0100)
committerRalph Boehme <slow@samba.org>
Wed, 16 Dec 2020 09:08:31 +0000 (09:08 +0000)
All callers except rename_open_files() can ignore non FSA fsps.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_acl_common.c
source3/smbd/dosmode.c
source3/smbd/files.c
source3/smbd/open.c
source3/smbd/proto.h
source3/smbd/reply.c
source3/smbd/smb1_utils.c
source3/smbd/trans2.c

index 09332a31579210f1a3fb838460ceadaaf9a700fa..14ea915d82830f30f51fe68f0f7f7ed73a31b640 100644 (file)
@@ -1235,8 +1235,8 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
 
        /* Ensure we have this file open with DELETE access. */
        id = vfs_file_id_from_sbuf(conn, &local_fname->st);
-       for (fsp = file_find_di_first(conn->sconn, id); fsp;
-                    fsp = file_find_di_next(fsp)) {
+       for (fsp = file_find_di_first(conn->sconn, id, true); fsp;
+                    fsp = file_find_di_next(fsp, true)) {
                if (fsp->access_mask & DELETE_ACCESS &&
                    fsp->fsp_flags.delete_on_close)
                {
index e66037c38a0e8b02b08c3ac183c4e000d330fc8d..b2cb83d9a94a486de5557a34fd8ec760f1ac629c 100644 (file)
@@ -1377,9 +1377,9 @@ static NTSTATUS get_file_handle_for_metadata(connection_struct *conn,
 
        file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
 
-       for(fsp = file_find_di_first(conn->sconn, file_id);
+       for(fsp = file_find_di_first(conn->sconn, file_id, true);
                        fsp;
-                       fsp = file_find_di_next(fsp)) {
+                       fsp = file_find_di_next(fsp, true)) {
                if (fsp_get_io_fd(fsp) != -1) {
                        *ret_fsp = fsp;
                        return NT_STATUS_OK;
index 4d16e7e89c2d52dd35f9ea73e5c8176f64205cdc..e12f527f3d74f724951b4e6379a77b8e1a6eae0b 100644 (file)
@@ -787,7 +787,8 @@ files_struct *file_find_dif(struct smbd_server_connection *sconn,
 ****************************************************************************/
 
 files_struct *file_find_di_first(struct smbd_server_connection *sconn,
-                                struct file_id id)
+                                struct file_id id,
+                                bool need_fsa)
 {
        files_struct *fsp;
 
@@ -799,6 +800,9 @@ files_struct *file_find_di_first(struct smbd_server_connection *sconn,
        sconn->fsp_fi_cache.id = id;
 
        for (fsp=sconn->files;fsp;fsp=fsp->next) {
+               if (need_fsa && !fsp->fsp_flags.is_fsa) {
+                       continue;
+               }
                if (file_id_equal(&fsp->file_id, &id)) {
                        /* Setup positive cache. */
                        sconn->fsp_fi_cache.fsp = fsp;
@@ -815,11 +819,15 @@ files_struct *file_find_di_first(struct smbd_server_connection *sconn,
  Find the next fsp having the same device and inode.
 ****************************************************************************/
 
-files_struct *file_find_di_next(files_struct *start_fsp)
+files_struct *file_find_di_next(files_struct *start_fsp,
+                               bool need_fsa)
 {
        files_struct *fsp;
 
        for (fsp = start_fsp->next;fsp;fsp=fsp->next) {
+               if (need_fsa && !fsp->fsp_flags.is_fsa) {
+                       continue;
+               }
                if (file_id_equal(&fsp->file_id, &start_fsp->file_id)) {
                        return fsp;
                }
index 8c3771ec9901a376dc0e978840d9e633a561831b..3fbb72572d802e898e93ebe1fb20edeaf7f191fb 100644 (file)
@@ -2118,9 +2118,9 @@ struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
         * handles...
         */
 
-       for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id);
+       for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
             fsp != NULL;
-            fsp = file_find_di_next(fsp)) {
+            fsp = file_find_di_next(fsp, true)) {
 
                if (fsp == new_fsp) {
                        continue;
index 9f9ceb1f110a3d78da8d6b1788632bb10ca7d25b..72c1df1cf26aa9b5809d0ff98b92e690e2a1c3ca 100644 (file)
@@ -419,8 +419,10 @@ files_struct *file_find_fd(struct smbd_server_connection *sconn, int fd);
 files_struct *file_find_dif(struct smbd_server_connection *sconn,
                            struct file_id id, unsigned long gen_id);
 files_struct *file_find_di_first(struct smbd_server_connection *sconn,
-                                struct file_id id);
-files_struct *file_find_di_next(files_struct *start_fsp);
+                                struct file_id id,
+                                bool need_fsa);
+files_struct *file_find_di_next(files_struct *start_fsp,
+                                bool need_fsa);
 struct files_struct *file_find_one_fsp_from_lease_key(
        struct smbd_server_connection *sconn,
        const struct smb2_lease_key *lease_key);
index be16b18a35df983ffa0c1571eee1fd75cbf51c5b..a8b3f028feafcf88aae80d57106094a270cbe6cc 100644 (file)
@@ -7365,8 +7365,8 @@ static void rename_open_files(connection_struct *conn,
        NTSTATUS status;
        uint32_t new_name_hash = 0;
 
-       for(fsp = file_find_di_first(conn->sconn, id); fsp;
-           fsp = file_find_di_next(fsp)) {
+       for(fsp = file_find_di_first(conn->sconn, id, false); fsp;
+           fsp = file_find_di_next(fsp, false)) {
                struct file_id_buf idbuf;
                /* fsp_name is a relative path under the fsp. To change this for other
                   sharepaths we need to manipulate relative paths. */
@@ -7519,8 +7519,8 @@ static NTSTATUS parent_dirname_compatible_open(connection_struct *conn,
         */
 
        id = vfs_file_id_from_sbuf(conn, &smb_fname_parent->st);
-       for (fsp = file_find_di_first(conn->sconn, id); fsp;
-                       fsp = file_find_di_next(fsp)) {
+       for (fsp = file_find_di_first(conn->sconn, id, true); fsp;
+                       fsp = file_find_di_next(fsp, true)) {
                if (fsp->access_mask & DELETE_ACCESS) {
                        return NT_STATUS_SHARING_VIOLATION;
                 }
@@ -7718,7 +7718,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
                struct file_id fileid = vfs_file_id_from_sbuf(conn,
                    &smb_fname_dst->st);
                files_struct *dst_fsp = file_find_di_first(conn->sconn,
-                                                          fileid);
+                                                          fileid, true);
                /* The file can be open when renaming a stream */
                if (dst_fsp && !new_is_stream) {
                        DEBUG(3, ("rename_internals_fsp: Target file open\n"));
index ac42b35564baf5f42692b7a05b8ac033c0c677f0..1776c50721c8779bf39ed66c906ec06e3237ee6a 100644 (file)
@@ -49,9 +49,9 @@ struct files_struct *fcb_or_dos_open(
                return NULL;
        }
 
-       for(fsp = file_find_di_first(conn->sconn, id);
+       for(fsp = file_find_di_first(conn->sconn, id, true);
            fsp != NULL;
-           fsp = file_find_di_next(fsp)) {
+           fsp = file_find_di_next(fsp, true)) {
 
                DBG_DEBUG("Checking file %s, fd = %d, vuid = %"PRIu64", "
                          "file_pid = %"PRIu16", "
index d1f75fe9d2b4f79934dd0d6b0f033a20ef51bc67..a4a246fe81a5c04610528e65f85fba7d2ad98f84 100644 (file)
@@ -5301,7 +5301,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                /* Do we have this path open ? */
                files_struct *fsp1;
                struct file_id fileid = vfs_file_id_from_sbuf(conn, psbuf);
-               fsp1 = file_find_di_first(conn->sconn, fileid);
+               fsp1 = file_find_di_first(conn->sconn, fileid, true);
                if (fsp1 && fsp1->initial_allocation_size) {
                        allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, psbuf);
                }
@@ -8383,8 +8383,8 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
        }
 
        id = vfs_file_id_from_sbuf(conn, &sbuf);
-       for(all_fsps = file_find_di_first(conn->sconn, id); all_fsps;
-                       all_fsps = file_find_di_next(all_fsps)) {
+       for(all_fsps = file_find_di_first(conn->sconn, id, true); all_fsps;
+                       all_fsps = file_find_di_next(all_fsps, true)) {
                /*
                 * We're setting the time explicitly for UNIX.
                 * Cancel any pending changes over all handles.