diff options
Diffstat (limited to 'source3/smbd/close.c')
-rw-r--r-- | source3/smbd/close.c | 163 |
1 files changed, 70 insertions, 93 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c index a0672f3949..f878aaa056 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -36,90 +36,102 @@ static NTSTATUS check_magic(struct files_struct *fsp) TALLOC_CTX *ctx = NULL; const char *p; struct connection_struct *conn = fsp->conn; + char *fname = NULL; + NTSTATUS status; if (!*lp_magicscript(SNUM(conn))) { return NT_STATUS_OK; } - DEBUG(5,("checking magic for %s\n",fsp->fsp_name)); + DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp))); + + ctx = talloc_stackframe(); + + status = get_full_smb_filename(ctx, fsp->fsp_name, &fname); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } - if (!(p = strrchr_m(fsp->fsp_name,'/'))) { - p = fsp->fsp_name; + if (!(p = strrchr_m(fname,'/'))) { + p = fname; } else { p++; } if (!strequal(lp_magicscript(SNUM(conn)),p)) { - return NT_STATUS_OK; + status = NT_STATUS_OK; + goto out; } - ctx = talloc_stackframe(); - if (*lp_magicoutput(SNUM(conn))) { magic_output = lp_magicoutput(SNUM(conn)); } else { magic_output = talloc_asprintf(ctx, "%s.out", - fsp->fsp_name); + fname); } if (!magic_output) { - TALLOC_FREE(ctx); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto out; } /* Ensure we don't depend on user's PATH. */ - p = talloc_asprintf(ctx, "./%s", fsp->fsp_name); + p = talloc_asprintf(ctx, "./%s", fname); if (!p) { - TALLOC_FREE(ctx); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto out; } - if (chmod(fsp->fsp_name,0755) == -1) { - TALLOC_FREE(ctx); - return map_nt_error_from_unix(errno); + if (chmod(fname, 0755) == -1) { + status = map_nt_error_from_unix(errno); + goto out; } ret = smbrun(p,&tmp_fd); DEBUG(3,("Invoking magic command %s gave %d\n", p,ret)); - unlink(fsp->fsp_name); + unlink(fname); if (ret != 0 || tmp_fd == -1) { if (tmp_fd != -1) { close(tmp_fd); } - TALLOC_FREE(ctx); - return NT_STATUS_UNSUCCESSFUL; + status = NT_STATUS_UNSUCCESSFUL; + goto out; } outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600); if (outfd == -1) { int err = errno; close(tmp_fd); - TALLOC_FREE(ctx); - return map_nt_error_from_unix(err); + status = map_nt_error_from_unix(err); + goto out; } if (sys_fstat(tmp_fd,&st) == -1) { int err = errno; close(tmp_fd); close(outfd); - TALLOC_FREE(ctx); - return map_nt_error_from_unix(err); + status = map_nt_error_from_unix(err); + goto out; } if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) { int err = errno; close(tmp_fd); close(outfd); - TALLOC_FREE(ctx); - return map_nt_error_from_unix(err); + status = map_nt_error_from_unix(err); + goto out; } close(tmp_fd); if (close(outfd) == -1) { - TALLOC_FREE(ctx); - return map_nt_error_from_unix(errno); + status = map_nt_error_from_unix(errno); + goto out; } + + status = NT_STATUS_OK; + + out: TALLOC_FREE(ctx); - return NT_STATUS_OK; + return status; } /**************************************************************************** @@ -261,18 +273,10 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, bool delete_file = false; bool changed_user = false; struct share_mode_lock *lck = NULL; - struct smb_filename *smb_fname = NULL; - char *fname = NULL; NTSTATUS status = NT_STATUS_OK; int ret; struct file_id id; - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - /* * Lock the share entries, and determine if we should delete * on close. If so delete whilst the lock is still in effect. @@ -284,7 +288,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, if (lck == NULL) { DEBUG(0, ("close_remove_share_mode: Could not get share mode " - "lock for file %s\n", smb_fname_str_dbg(smb_fname))); + "lock for file %s\n", fsp_str_dbg(fsp))); status = NT_STATUS_INVALID_PARAMETER; goto done; } @@ -296,7 +300,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, if (!del_share_mode(lck, fsp)) { DEBUG(0, ("close_remove_share_mode: Could not delete share " "entry for file %s\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); } if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) { @@ -354,7 +358,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, */ DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set " - "- deleting file.\n", smb_fname_str_dbg(smb_fname))); + "- deleting file.\n", fsp_str_dbg(fsp))); /* * Don't try to update the write time when we delete the file @@ -366,7 +370,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, DEBUG(5,("close_remove_share_mode: file %s. " "Change user to uid %u\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), (unsigned int)lck->delete_token->uid)); if (!push_sec_ctx()) { @@ -387,30 +391,30 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, hasn't been renamed. */ if (fsp->posix_open) { - ret = SMB_VFS_LSTAT(conn, smb_fname); + ret = SMB_VFS_LSTAT(conn, fsp->fsp_name); } else { - ret = SMB_VFS_STAT(conn, smb_fname); + ret = SMB_VFS_STAT(conn, fsp->fsp_name); } if (ret != 0) { DEBUG(5,("close_remove_share_mode: file %s. Delete on close " "was set and stat failed with error %s\n", - smb_fname_str_dbg(smb_fname), strerror(errno))); + fsp_str_dbg(fsp), strerror(errno))); /* * Don't save the errno here, we ignore this error */ goto done; } - id = vfs_file_id_from_sbuf(conn, &smb_fname->st); + id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st); if (!file_id_equal(&fsp->file_id, &id)) { DEBUG(5,("close_remove_share_mode: file %s. Delete on close " "was set and dev and/or inode does not match\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, " "stat file_id %s\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), file_id_string_tos(&id))); /* @@ -420,9 +424,9 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, } if ((conn->fs_capabilities & FILE_NAMED_STREAMS) - && !is_ntfs_stream_smb_fname(smb_fname)) { + && !is_ntfs_stream_smb_fname(fsp->fsp_name)) { - status = delete_all_streams(conn, smb_fname->base_name); + status = delete_all_streams(conn, fsp->fsp_name->base_name); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("delete_all_streams failed: %s\n", @@ -432,7 +436,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, } - if (SMB_VFS_UNLINK(conn, smb_fname) != 0) { + if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) { /* * This call can potentially fail as another smbd may * have had the file open with delete on close set and @@ -443,21 +447,14 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, DEBUG(5,("close_remove_share_mode: file %s. Delete on close " "was set and unlink failed with error %s\n", - smb_fname_str_dbg(smb_fname), strerror(errno))); + fsp_str_dbg(fsp), strerror(errno))); status = map_nt_error_from_unix(errno); } - status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - notify_fname(conn, NOTIFY_ACTION_REMOVED, FILE_NOTIFY_CHANGE_FILE_NAME, - fname); - - TALLOC_FREE(fname); + fsp->fsp_name->base_name); /* As we now have POSIX opens which can unlink * with other open files we may have taken @@ -476,7 +473,6 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, } TALLOC_FREE(lck); - TALLOC_FREE(smb_fname); return status; } @@ -499,7 +495,6 @@ void set_close_write_time(struct files_struct *fsp, struct timespec ts) static NTSTATUS update_write_time_on_close(struct files_struct *fsp) { - struct smb_filename *smb_fname = NULL; struct smb_file_time ft; NTSTATUS status; int ret = -1; @@ -514,43 +509,32 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp) fsp->close_write_time = timespec_current(); } - /* XXX: Remove when fsp->fsp_name is converted to smb_filename. */ - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - /* Ensure we have a valid stat struct for the source. */ if (fsp->fh->fd != -1) { - ret = SMB_VFS_FSTAT(fsp, &smb_fname->st); + ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); } else { if (fsp->posix_open) { - ret = SMB_VFS_LSTAT(fsp->conn, smb_fname); + ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); } else { - ret = SMB_VFS_STAT(fsp->conn, smb_fname); + ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); } } if (ret == -1) { - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } - if (!VALID_STAT(smb_fname->st)) { + if (!VALID_STAT(fsp->fsp_name->st)) { /* if it doesn't seem to be a real file */ - status = NT_STATUS_OK; - goto out; + return NT_STATUS_OK; } ft.mtime = fsp->close_write_time; - status = smb_set_file_time(fsp->conn, fsp, smb_fname, &ft, true); + status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, true); if (!NT_STATUS_IS_OK(status)) { - goto out; + return status; } - out: - TALLOC_FREE(smb_fname); return status; } @@ -647,7 +631,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, status = ntstatus_keeperror(status, tmp); DEBUG(2,("%s closed file %s (numopen=%d) %s\n", - conn->server_info->unix_name,fsp->fsp_name, + conn->server_info->unix_name, fsp_str_dbg(fsp), conn->num_files_open - 1, nt_errstr(status) )); @@ -663,16 +647,9 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, enum file_close_type close_type) { struct share_mode_lock *lck = NULL; - struct smb_filename *smb_dname = NULL; bool delete_dir = False; NTSTATUS status = NT_STATUS_OK; - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_dname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - /* * NT can set delete_on_close of the last open * reference to a directory also. @@ -683,14 +660,14 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, if (lck == NULL) { DEBUG(0, ("close_directory: Could not get share mode lock for " - "%s\n", smb_fname_str_dbg(smb_dname))); + "%s\n", fsp_str_dbg(fsp))); status = NT_STATUS_INVALID_PARAMETER; goto out; } if (!del_share_mode(lck, fsp)) { DEBUG(0, ("close_directory: Could not delete share entry for " - "%s\n", smb_fname_str_dbg(smb_dname))); + "%s\n", fsp_str_dbg(fsp))); } if (fsp->initial_delete_on_close) { @@ -704,7 +681,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, become_user(fsp->conn, fsp->vuid); became_user = True; } - send_stat_cache_delete_message(fsp->fsp_name); + send_stat_cache_delete_message(fsp->fsp_name->base_name); set_delete_on_close_lck(lck, True, ¤t_user.ut); if (became_user) { unbecome_user(); @@ -747,11 +724,12 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, TALLOC_FREE(lck); - status = rmdir_internals(talloc_tos(), fsp->conn, smb_dname); + status = rmdir_internals(talloc_tos(), fsp->conn, + fsp->fsp_name); DEBUG(5,("close_directory: %s. Delete on close was set - " "deleting directory returned %s.\n", - smb_fname_str_dbg(smb_dname), nt_errstr(status))); + fsp_str_dbg(fsp), nt_errstr(status))); /* unbecome user. */ pop_sec_ctx(); @@ -774,7 +752,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n", - smb_fname_str_dbg(smb_dname), fsp->fh->fd, errno, + fsp_str_dbg(fsp), fsp->fh->fd, errno, strerror(errno))); } @@ -786,7 +764,6 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, out: TALLOC_FREE(lck); - TALLOC_FREE(smb_dname); return status; } |