Remove lots of duplicate code and move it into one
authorJeremy Allison <jra@samba.org>
Fri, 2 Oct 2009 20:45:38 +0000 (13:45 -0700)
committerJeremy Allison <jra@samba.org>
Fri, 2 Oct 2009 20:45:38 +0000 (13:45 -0700)
function vfs_stat_fsp(). Stops code looking at fsp->posix_open
except for exceptional circumstances.
Jeremy.

source3/include/proto.h
source3/modules/vfs_acl_common.c
source3/modules/vfs_acl_tdb.c
source3/smbd/close.c
source3/smbd/posix_acls.c
source3/smbd/reply.c
source3/smbd/vfs.c

index c9f57b46a66f43b10359a069496bdd8808a410db..c8e4fe1916ff270eb02ff71469d3114fa23185b2 100644 (file)
@@ -7116,6 +7116,7 @@ int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
                       SMB_STRUCT_STAT *psbuf);
 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
                        SMB_STRUCT_STAT *psbuf);
+NTSTATUS vfs_stat_fsp(files_struct *fsp);
 
 /* The following definitions come from torture/denytest.c  */
 
index 5fdd2b4725c0b7f61e6ccae8e8bbb6177c7d626d..39fd2ad0ed881170fd7aae757c12c772a2128b83 100644 (file)
@@ -380,21 +380,26 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
        }
 
        if (!psd || psd->dacl == NULL) {
-               int ret;
 
                TALLOC_FREE(psd);
-               if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
-                       ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
+               if (fsp) {
+                       status = vfs_stat_fsp(fsp);
+                       smb_fname->st = fsp->fsp_name->st;
                } else {
-                       if (fsp && fsp->posix_open) {
+                       int ret;
+                       if (lp_posix_pathnames()) {
                                ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
                        } else {
                                ret = SMB_VFS_STAT(handle->conn, smb_fname);
                        }
+                       if (ret == -1) {
+                               status = map_nt_error_from_unix(errno);
+                       }
                }
-               if (ret == -1) {
-                       return map_nt_error_from_unix(errno);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
                }
+
                psd = default_file_sd(ctx, &smb_fname->st);
                if (!psd) {
                        return NT_STATUS_NO_MEMORY;
@@ -580,23 +585,14 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
 
        /* Ensure owner and group are set. */
        if (!psd->owner_sid || !psd->group_sid) {
-               int ret;
                DOM_SID owner_sid, group_sid;
                struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
 
                if (!nc_psd) {
                        return NT_STATUS_OK;
                }
-               if (fsp->is_directory || fsp->fh->fd == -1) {
-                       if (fsp->posix_open) {
-                               ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
-                       } else {
-                               ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
-                       }
-               } else {
-                       ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
-               }
-               if (ret == -1) {
+               status = vfs_stat_fsp(fsp);
+               if (!NT_STATUS_IS_OK(status)) {
                        /* Lower level acl set succeeded,
                         * so still return OK. */
                        return NT_STATUS_OK;
index 285c58ed9d19f00731d1d11f7c6400963912c6ff..424ecbf65b80c4af7489b0d18c58593c6e8b2731 100644 (file)
@@ -147,24 +147,26 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
        TDB_DATA data;
        struct file_id id;
        struct db_context *db;
-       int ret = -1;
+       NTSTATUS status;
        SMB_STRUCT_STAT sbuf;
 
        SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
                return NT_STATUS_INTERNAL_DB_CORRUPTION);
 
-       if (fsp && fsp->fh->fd != -1) {
-               ret = SMB_VFS_FSTAT(fsp, &sbuf);
+       ZERO_STRUCT(sbuf);
+
+       if (fsp) {
+               status = vfs_stat_fsp(fsp);
+               sbuf = fsp->fsp_name->st;
        } else {
-               if (fsp && fsp->posix_open) {
-                       ret = vfs_lstat_smb_fname(handle->conn, name, &sbuf);
-               } else {
-                       ret = vfs_stat_smb_fname(handle->conn, name, &sbuf);
+               int ret = vfs_stat_smb_fname(handle->conn, name, &sbuf);
+               if (ret == -1) {
+                       status = map_nt_error_from_unix(errno);
                }
        }
 
-       if (ret == -1) {
-               return map_nt_error_from_unix(errno);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
        id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
@@ -204,7 +206,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
        TDB_DATA data;
        struct db_context *db;
        struct db_record *rec;
-       int ret = -1;
+       NTSTATUS status;
 
        DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n",
                  (unsigned int)pblob->length, fsp_str_dbg(fsp)));
@@ -212,18 +214,9 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
        SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
                return NT_STATUS_INTERNAL_DB_CORRUPTION);
 
-       if (fsp->fh->fd != -1) {
-               ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
-       } else {
-               if (fsp->posix_open) {
-                       ret = SMB_VFS_LSTAT(handle->conn, fsp->fsp_name);
-               } else {
-                       ret = SMB_VFS_STAT(handle->conn, fsp->fsp_name);
-               }
-       }
-
-       if (ret == -1) {
-               return map_nt_error_from_unix(errno);
+       status = vfs_stat_fsp(fsp);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
        id = vfs_file_id_from_sbuf(handle->conn, &fsp->fsp_name->st);
@@ -438,20 +431,13 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle,
                             SMB_ACL_T theacl)
 {
        struct db_context *db;
+       NTSTATUS status;
        int ret;
 
        SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
 
-       if (fsp->is_directory || fsp->fh->fd == -1) {
-               if (fsp->posix_open) {
-                       ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
-               } else {
-                       ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
-               }
-       } else {
-               ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
-       }
-       if (ret == -1) {
+       status = vfs_stat_fsp(fsp);
+       if (!NT_STATUS_IS_OK(status)) {
                return -1;
        }
 
index 1f2e4604c228f23722a0707b27ebbf872e1bf668..642864f27e81ae40546c7f99cc6ffa9446674224 100644 (file)
@@ -271,7 +271,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
        bool changed_user = false;
        struct share_mode_lock *lck = NULL;
        NTSTATUS status = NT_STATUS_OK;
-       int ret;
+       NTSTATUS tmp_status;
        struct file_id id;
 
        /*
@@ -387,16 +387,11 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
        /* We can only delete the file if the name we have is still valid and
           hasn't been renamed. */
 
-       if (fsp->posix_open) {
-               ret = SMB_VFS_LSTAT(conn, fsp->fsp_name);
-       } else {
-               ret = SMB_VFS_STAT(conn, fsp->fsp_name);
-       }
-
-       if (ret != 0) {
+       tmp_status = vfs_stat_fsp(fsp);
+       if (!NT_STATUS_IS_OK(tmp_status)) {
                DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
                         "was set and stat failed with error %s\n",
-                        fsp_str_dbg(fsp), strerror(errno)));
+                        fsp_str_dbg(fsp), nt_errstr(tmp_status)));
                /*
                 * Don't save the errno here, we ignore this error
                 */
@@ -494,7 +489,6 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
 {
        struct smb_file_time ft;
        NTSTATUS status;
-       int ret = -1;
 
        ZERO_STRUCT(ft);
 
@@ -507,18 +501,9 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
        }
 
        /* Ensure we have a valid stat struct for the source. */
-       if (fsp->fh->fd != -1) {
-               ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
-       } else {
-               if (fsp->posix_open) {
-                       ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
-               } else {
-                       ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
-               }
-       }
-
-       if (ret == -1) {
-               return map_nt_error_from_unix(errno);
+       status = vfs_stat_fsp(fsp);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
        if (!VALID_STAT(fsp->fsp_name->st)) {
index 6b5a9af45bd687522b0a71bcfd094840dcdf38b3..32a04c51e4ef7b02c77829925a7ae7b75d104e8e 100644 (file)
@@ -3739,7 +3739,6 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
        bool set_acl_as_root = false;
        bool acl_set_support = false;
        bool ret = false;
-       int sret;
 
        DEBUG(10,("set_nt_acl: called for file %s\n",
                  fsp_str_dbg(fsp)));
@@ -3753,19 +3752,9 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
         * Get the current state of the file.
         */
 
-       if(fsp->is_directory || fsp->fh->fd == -1) {
-               if (fsp->posix_open) {
-                       sret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
-               } else {
-                       sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
-               }
-               if (sret == -1) {
-                       return map_nt_error_from_unix(errno);
-               }
-       } else {
-               if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
-                       return map_nt_error_from_unix(errno);
-               }
+       status = vfs_stat_fsp(fsp);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
        /* Save the original element we check against. */
@@ -3809,18 +3798,9 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                 * (suid/sgid bits, for instance)
                 */
 
-               if(fsp->is_directory || fsp->fh->fd == -1) {
-                       if (fsp->posix_open) {
-                               sret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
-                       } else {
-                               sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
-                       }
-               } else {
-                       sret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
-               }
-
-               if(sret == -1) {
-                       return map_nt_error_from_unix(errno);
+               status = vfs_stat_fsp(fsp);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
                }
 
                /* Save the original element we check against. */
index a3280cb9d4ae36910098cdbae9cdce41bfc09588..abc316315ae7fd4e7d2bcae8853deec3f8c5d90e 100644 (file)
@@ -5860,25 +5860,17 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
                        bool replace_if_exists)
 {
        TALLOC_CTX *ctx = talloc_tos();
-       struct smb_filename *smb_fname_src = NULL;
        struct smb_filename *smb_fname_dst = NULL;
-       SMB_STRUCT_STAT sbuf;
        NTSTATUS status = NT_STATUS_OK;
        struct share_mode_lock *lck = NULL;
        bool dst_exists, old_is_stream, new_is_stream;
 
-       ZERO_STRUCT(sbuf);
-
        status = check_name(conn, smb_fname_dst_in->base_name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       /* Make a copy of the src and dst smb_fname structs */
-       status = copy_smb_filename(ctx, fsp->fsp_name, &smb_fname_src);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
+       /* Make a copy of the dst smb_fname structs */
 
        status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst);
        if (!NT_STATUS_IS_OK(status)) {
@@ -5906,8 +5898,8 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
         * filename).
         */
        if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
-           strequal(smb_fname_src->base_name, smb_fname_dst->base_name) &&
-           strequal(smb_fname_src->stream_name, smb_fname_dst->stream_name)) {
+           strequal(fsp->fsp_name->base_name, smb_fname_dst->base_name) &&
+           strequal(fsp->fsp_name->stream_name, smb_fname_dst->stream_name)) {
                char *last_slash;
                char *fname_dst_lcomp_base_mod = NULL;
                struct smb_filename *smb_fname_orig_lcomp = NULL;
@@ -5984,8 +5976,8 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
         * don't do the rename, just return success.
         */
 
-       if (strcsequal(smb_fname_src->base_name, smb_fname_dst->base_name) &&
-           strcsequal(smb_fname_src->stream_name,
+       if (strcsequal(fsp->fsp_name->base_name, smb_fname_dst->base_name) &&
+           strcsequal(fsp->fsp_name->stream_name,
                       smb_fname_dst->stream_name)) {
                DEBUG(3, ("rename_internals_fsp: identical names in rename %s "
                          "- returning success\n",
@@ -5994,7 +5986,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
                goto out;
        }
 
-       old_is_stream = is_ntfs_stream_smb_fname(smb_fname_src);
+       old_is_stream = is_ntfs_stream_smb_fname(fsp->fsp_name);
        new_is_stream = is_ntfs_stream_smb_fname(smb_fname_dst);
 
        /* Return the correct error code if both names aren't streams. */
@@ -6012,7 +6004,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 
        if(!replace_if_exists && dst_exists) {
                DEBUG(3, ("rename_internals_fsp: dest exists doing rename "
-                         "%s -> %s\n", smb_fname_str_dbg(smb_fname_src),
+                         "%s -> %s\n", smb_fname_str_dbg(fsp->fsp_name),
                          smb_fname_str_dbg(smb_fname_dst)));
                status = NT_STATUS_OBJECT_NAME_COLLISION;
                goto out;
@@ -6031,38 +6023,23 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
        }
 
        /* Ensure we have a valid stat struct for the source. */
-       if (fsp->fh->fd != -1) {
-               if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
-                       status = map_nt_error_from_unix(errno);
-                       goto out;
-               }
-       } else {
-               int ret = -1;
-               if (fsp->posix_open) {
-                       ret = SMB_VFS_LSTAT(conn, smb_fname_src);
-               } else {
-
-                       ret = SMB_VFS_STAT(conn, smb_fname_src);
-               }
-               if (ret == -1) {
-                       status = map_nt_error_from_unix(errno);
-                       goto out;
-               }
-               sbuf = smb_fname_src->st;
+       status = vfs_stat_fsp(fsp);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
        }
 
-       status = can_rename(conn, fsp, attrs, &sbuf);
+       status = can_rename(conn, fsp, attrs, &fsp->fsp_name->st);
 
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(3, ("rename_internals_fsp: Error %s rename %s -> %s\n",
-                         nt_errstr(status), smb_fname_str_dbg(smb_fname_src),
+                         nt_errstr(status), smb_fname_str_dbg(fsp->fsp_name),
                          smb_fname_str_dbg(smb_fname_dst)));
                if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION))
                        status = NT_STATUS_ACCESS_DENIED;
                goto out;
        }
 
-       if (rename_path_prefix_equal(smb_fname_src, smb_fname_dst)) {
+       if (rename_path_prefix_equal(fsp->fsp_name, smb_fname_dst)) {
                status = NT_STATUS_ACCESS_DENIED;
        }
 
@@ -6076,14 +6053,14 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 
        SMB_ASSERT(lck != NULL);
 
-       if(SMB_VFS_RENAME(conn, smb_fname_src, smb_fname_dst) == 0) {
+       if(SMB_VFS_RENAME(conn, fsp->fsp_name, smb_fname_dst) == 0) {
                uint32 create_options = fsp->fh->private_options;
 
                DEBUG(3, ("rename_internals_fsp: succeeded doing rename on "
-                         "%s -> %s\n", smb_fname_str_dbg(smb_fname_src),
+                         "%s -> %s\n", smb_fname_str_dbg(fsp->fsp_name),
                          smb_fname_str_dbg(smb_fname_dst)));
 
-               notify_rename(conn, fsp->is_directory, smb_fname_src,
+               notify_rename(conn, fsp->is_directory, fsp->fsp_name,
                              smb_fname_dst);
 
                rename_open_files(conn, lck, smb_fname_dst);
@@ -6120,11 +6097,10 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
        }
 
        DEBUG(3, ("rename_internals_fsp: Error %s rename %s -> %s\n",
-                 nt_errstr(status), smb_fname_str_dbg(smb_fname_src),
+                 nt_errstr(status), smb_fname_str_dbg(fsp->fsp_name),
                  smb_fname_str_dbg(smb_fname_dst)));
 
  out:
-       TALLOC_FREE(smb_fname_src);
        TALLOC_FREE(smb_fname_dst);
 
        return status;
@@ -7707,25 +7683,10 @@ void reply_setattrE(struct smb_request *req)
         */
 
        /* Ensure we have a valid stat struct for the source. */
-       if (fsp->fh->fd != -1) {
-               if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == -1) {
-                       status = map_nt_error_from_unix(errno);
-                       reply_nterror(req, status);
-                       goto out;
-               }
-       } else {
-               int ret = -1;
-
-               if (fsp->posix_open) {
-                       ret = SMB_VFS_LSTAT(conn, fsp->fsp_name);
-               } else {
-                       ret = SMB_VFS_STAT(conn, fsp->fsp_name);
-               }
-               if (ret == -1) {
-                       status = map_nt_error_from_unix(errno);
-                       reply_nterror(req, status);
-                       goto out;
-               }
+       status = vfs_stat_fsp(fsp);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               goto out;
        }
 
        status = smb_set_file_time(conn, fsp, fsp->fsp_name, &ft, true);
index 171c8032043e4e469fdca9b740e93887090daf3c..966742a6d019b5ed4529c46552bc539c60aae6c5 100644 (file)
@@ -1049,6 +1049,31 @@ int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
        return ret;
 }
 
+/**
+ * Ensure LSTAT is called for POSIX paths.
+ */
+
+NTSTATUS vfs_stat_fsp(files_struct *fsp)
+{
+       int ret;
+
+       if(fsp->is_directory || fsp->fh->fd == -1) {
+               if (fsp->posix_open) {
+                       ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
+               } else {
+                       ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
+               }
+               if (ret == -1) {
+                       return map_nt_error_from_unix(errno);
+               }
+       } else {
+               if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
+                       return map_nt_error_from_unix(errno);
+               }
+       }
+       return NT_STATUS_OK;
+}
+
 /*
   generate a file_id from a stat structure
  */