smbd: remove redundant conn arg from fd_open()
[samba.git] / source3 / smbd / open.c
index f77abca47cedd8eaea6c86c16241f54eb18cf0ec..bd4d8c3616514697e85b9228d83abb5adf1d9d19 100644 (file)
@@ -759,11 +759,11 @@ static int non_widelink_open(struct connection_struct *conn,
  fd support routines - attempt to do a dos_open.
 ****************************************************************************/
 
-NTSTATUS fd_open(struct connection_struct *conn,
-                files_struct *fsp,
+NTSTATUS fd_open(files_struct *fsp,
                 int flags,
                 mode_t mode)
 {
+       struct connection_struct *conn = fsp->conn;
        struct smb_filename *smb_fname = fsp->fsp_name;
        NTSTATUS status = NT_STATUS_OK;
        int saved_errno = 0;
@@ -1023,11 +1023,10 @@ static NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
  file was created or not.
 ****************************************************************************/
 
-static NTSTATUS fd_open_atomic(struct connection_struct *conn,
-                       files_struct *fsp,
-                       int flags,
-                       mode_t mode,
-                       bool *file_created)
+static NTSTATUS fd_open_atomic(files_struct *fsp,
+                              int flags,
+                              mode_t mode,
+                              bool *file_created)
 {
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
        NTSTATUS retry_status;
@@ -1038,7 +1037,7 @@ static NTSTATUS fd_open_atomic(struct connection_struct *conn,
                /*
                 * We're not creating the file, just pass through.
                 */
-               status = fd_open(conn, fsp, flags, mode);
+               status = fd_open(fsp, flags, mode);
                *file_created = false;
                return status;
        }
@@ -1047,7 +1046,7 @@ static NTSTATUS fd_open_atomic(struct connection_struct *conn,
                /*
                 * Fail if already exists, just pass through.
                 */
-               status = fd_open(conn, fsp, flags, mode);
+               status = fd_open(fsp, flags, mode);
 
                /*
                 * Here we've opened with O_CREAT|O_EXCL. If that went
@@ -1087,7 +1086,7 @@ static NTSTATUS fd_open_atomic(struct connection_struct *conn,
                retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
        }
 
-       status = fd_open(conn, fsp, curr_flags, mode);
+       status = fd_open(fsp, curr_flags, mode);
        if (NT_STATUS_IS_OK(status)) {
                *file_created = !file_existed;
                return NT_STATUS_OK;
@@ -1106,7 +1105,7 @@ static NTSTATUS fd_open_atomic(struct connection_struct *conn,
                        curr_flags = flags | O_EXCL;
                }
 
-               status = fd_open(conn, fsp, curr_flags, mode);
+               status = fd_open(fsp, curr_flags, mode);
        }
 
        *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
@@ -1118,7 +1117,6 @@ static NTSTATUS fd_open_atomic(struct connection_struct *conn,
 ****************************************************************************/
 
 static NTSTATUS open_file(files_struct *fsp,
-                         connection_struct *conn,
                          struct smb_request *req,
                          struct smb_filename *parent_dir,
                          int flags,
@@ -1127,6 +1125,7 @@ static NTSTATUS open_file(files_struct *fsp,
                          uint32_t open_access_mask, /* what we're actually using in the open. */
                          bool *p_file_created)
 {
+       connection_struct *conn = fsp->conn;
        struct smb_filename *smb_fname = fsp->fsp_name;
        NTSTATUS status = NT_STATUS_OK;
        int accmode = (flags & O_ACCMODE);
@@ -1290,8 +1289,10 @@ static NTSTATUS open_file(files_struct *fsp,
                 * Actually do the open - if O_TRUNC is needed handle it
                 * below under the share mode lock.
                 */
-               status = fd_open_atomic(conn, fsp, local_flags & ~O_TRUNC,
-                               unx_mode, p_file_created);
+               status = fd_open_atomic(fsp,
+                                       local_flags & ~O_TRUNC,
+                                       unx_mode,
+                                       p_file_created);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
                                 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
@@ -3332,6 +3333,8 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
        bool setup_poll = false;
        bool ok;
 
+       SMB_ASSERT(fsp->dirfsp == conn->cwd_fsp);
+
        if (conn->printer) {
                /*
                 * Printers are handled completely differently.
@@ -3677,10 +3680,14 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
                 (unsigned int)unx_mode, (unsigned int)access_mask,
                 (unsigned int)open_access_mask));
 
-       fsp_open = open_file(fsp, conn, req, parent_dir_fname,
-                            flags|flags2, unx_mode, access_mask,
-                            open_access_mask, &new_file_created);
-
+       fsp_open = open_file(fsp,
+                            req,
+                            parent_dir_fname,
+                            flags|flags2,
+                            unx_mode,
+                            access_mask,
+                            open_access_mask,
+                            &new_file_created);
        if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
                if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
                        DEBUG(10, ("FIFO busy\n"));
@@ -4111,6 +4118,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
 }
 
 static NTSTATUS mkdir_internal(connection_struct *conn,
+                              struct files_struct **dirfsp,
                               struct smb_filename *smb_dname,
                               uint32_t file_attributes)
 {
@@ -4125,6 +4133,8 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
        int ret;
        bool ok;
 
+       SMB_ASSERT(*dirfsp == conn->cwd_fsp);
+
        if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
                DEBUG(5,("mkdir_internal: failing share access "
                         "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
@@ -4150,9 +4160,9 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
        }
 
        status = check_parent_access(conn,
-                                       conn->cwd_fsp,
-                                       smb_dname,
-                                       access_mask);
+                                    *dirfsp,
+                                    smb_dname,
+                                    access_mask);
        if(!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("mkdir_internal: check_parent_access "
                        "on directory %s for path %s returned %s\n",
@@ -4163,9 +4173,9 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
        }
 
        ret = SMB_VFS_MKDIRAT(conn,
-                       conn->cwd_fsp,
-                       smb_dname,
-                       mode);
+                             *dirfsp,
+                             smb_dname,
+                             mode);
        if (ret != 0) {
                return map_nt_error_from_unix(errno);
        }
@@ -4253,6 +4263,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
 
 static NTSTATUS open_directory(connection_struct *conn,
                               struct smb_request *req,
+                              struct files_struct **dirfsp,
                               struct smb_filename *smb_dname,
                               uint32_t access_mask,
                               uint32_t share_access,
@@ -4271,6 +4282,8 @@ static NTSTATUS open_directory(connection_struct *conn,
        int flags;
        bool ok;
 
+       SMB_ASSERT(*dirfsp == conn->cwd_fsp);
+
        if (is_ntfs_stream_smb_fname(smb_dname)) {
                DEBUG(2, ("open_directory: %s is a stream name!\n",
                          smb_fname_str_dbg(smb_dname)));
@@ -4294,7 +4307,7 @@ static NTSTATUS open_directory(connection_struct *conn,
                 file_attributes);
 
        status = smbd_calculate_access_mask(conn,
-                                       conn->cwd_fsp,
+                                       *dirfsp,
                                        smb_dname,
                                        false,
                                        access_mask,
@@ -4340,7 +4353,7 @@ static NTSTATUS open_directory(connection_struct *conn,
                                return status;
                        }
 
-                       status = mkdir_internal(conn, smb_dname,
+                       status = mkdir_internal(conn, dirfsp, smb_dname,
                                                file_attributes);
 
                        if (!NT_STATUS_IS_OK(status)) {
@@ -4364,7 +4377,7 @@ static NTSTATUS open_directory(connection_struct *conn,
                                status = NT_STATUS_OK;
                                info = FILE_WAS_OPENED;
                        } else {
-                               status = mkdir_internal(conn, smb_dname,
+                               status = mkdir_internal(conn, dirfsp, smb_dname,
                                                file_attributes);
 
                                if (NT_STATUS_IS_OK(status)) {
@@ -4423,7 +4436,7 @@ static NTSTATUS open_directory(connection_struct *conn,
 
        if (info == FILE_WAS_OPENED) {
                status = smbd_check_access_rights(conn,
-                                               conn->cwd_fsp,
+                                               *dirfsp,
                                                smb_dname,
                                                false,
                                                access_mask);
@@ -4471,6 +4484,12 @@ static NTSTATUS open_directory(connection_struct *conn,
                return status;
        }
 
+       if (*dirfsp == fsp->conn->cwd_fsp) {
+               fsp->dirfsp = fsp->conn->cwd_fsp;
+       } else {
+               fsp->dirfsp = talloc_move(fsp, dirfsp);
+       }
+
        /* Don't store old timestamps for directory
           handles in the internal database. We don't
           update them in there if new objects
@@ -4486,7 +4505,7 @@ static NTSTATUS open_directory(connection_struct *conn,
        flags |= O_DIRECTORY;
 #endif
 
-       status = fd_open(conn, fsp, flags, 0);
+       status = fd_open(fsp, flags, 0);
        if (!NT_STATUS_IS_OK(status)) {
                DBG_INFO("Could not open fd for "
                        "%s (%s)\n",
@@ -5377,6 +5396,7 @@ static NTSTATUS lease_match(connection_struct *conn,
 
 static NTSTATUS create_file_unixpath(connection_struct *conn,
                                     struct smb_request *req,
+                                    struct files_struct **dirfsp,
                                     struct smb_filename *smb_fname,
                                     uint32_t access_mask,
                                     uint32_t share_access,
@@ -5399,6 +5419,8 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
        files_struct *fsp = NULL;
        NTSTATUS status;
 
+       SMB_ASSERT(*dirfsp == conn->cwd_fsp);
+
        DBG_DEBUG("create_file_unixpath: access_mask = 0x%x "
                  "file_attributes = 0x%x, share_access = 0x%x, "
                  "create_disposition = 0x%x create_options = 0x%x "
@@ -5572,15 +5594,25 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
                base_privflags = NTCREATEX_OPTIONS_PRIVATE_STREAM_BASEOPEN;
 
                /* Open the base file. */
-               status = create_file_unixpath(conn, NULL, smb_fname_base, 0,
+               status = create_file_unixpath(conn,
+                                             NULL,
+                                             dirfsp,
+                                             smb_fname_base,
+                                             0,
                                              FILE_SHARE_READ
                                              | FILE_SHARE_WRITE
                                              | FILE_SHARE_DELETE,
                                              base_create_disposition,
-                                             0, 0, 0, NULL, 0,
+                                             0,
+                                             0,
+                                             0,
+                                             NULL,
+                                             0,
                                              base_privflags,
-                                             NULL, NULL,
-                                             &base_fsp, NULL);
+                                             NULL,
+                                             NULL,
+                                             &base_fsp,
+                                             NULL);
                TALLOC_FREE(smb_fname_base);
 
                if (!NT_STATUS_IS_OK(status)) {
@@ -5618,10 +5650,17 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
                 */
 
                oplock_request = 0;
-               status = open_directory(
-                       conn, req, smb_fname, access_mask, share_access,
-                       create_disposition, create_options, file_attributes,
-                       &info, &fsp);
+               status = open_directory(conn,
+                                       req,
+                                       dirfsp,
+                                       smb_fname,
+                                       access_mask,
+                                       share_access,
+                                       create_disposition,
+                                       create_options,
+                                       file_attributes,
+                                       &info,
+                                       &fsp);
        } else {
 
                /*
@@ -5638,6 +5677,12 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
                        goto fail;
                }
 
+               if (*dirfsp == fsp->conn->cwd_fsp) {
+                       fsp->dirfsp = fsp->conn->cwd_fsp;
+               } else {
+                       fsp->dirfsp = talloc_move(fsp, dirfsp);
+               }
+
                if (base_fsp) {
                        /*
                         * We're opening the stream element of a
@@ -5690,11 +5735,17 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
                        }
 
                        oplock_request = 0;
-                       status = open_directory(
-                               conn, req, smb_fname, access_mask,
-                               share_access, create_disposition,
-                               create_options, file_attributes,
-                               &info, &fsp);
+                       status = open_directory(conn,
+                                               req,
+                                               dirfsp,
+                                               smb_fname,
+                                               access_mask,
+                                               share_access,
+                                               create_disposition,
+                                               create_options,
+                                               file_attributes,
+                                               &info,
+                                               &fsp);
                }
        }
 
@@ -5974,13 +6025,23 @@ NTSTATUS create_file_default(connection_struct *conn,
                file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
        }
 
-       status = create_file_unixpath(
-               conn, req, smb_fname, access_mask, share_access,
-               create_disposition, create_options, file_attributes,
-               oplock_request, lease, allocation_size, private_flags,
-               sd, ea_list,
-               &fsp, &info);
-
+       status = create_file_unixpath(conn,
+                                     req,
+                                     _dirfsp,
+                                     smb_fname,
+                                     access_mask,
+                                     share_access,
+                                     create_disposition,
+                                     create_options,
+                                     file_attributes,
+                                     oplock_request,
+                                     lease,
+                                     allocation_size,
+                                     private_flags,
+                                     sd,
+                                     ea_list,
+                                     &fsp,
+                                     &info);
        if (!NT_STATUS_IS_OK(status)) {
                goto fail;
        }