summaryrefslogtreecommitdiff
path: root/source3/smbd/close.c
diff options
context:
space:
mode:
authorTim Prouty <tprouty@samba.org>2009-07-02 09:27:44 -0700
committerTim Prouty <tprouty@samba.org>2009-07-06 15:38:36 -0700
commit258952aa85f2a68e2d2362522f6114c6a439f1e3 (patch)
tree696d8f4425cb6d82c95c0923ba1b0405d39a1f5e /source3/smbd/close.c
parent133e915a81510f543f6458f377857d4f1b680970 (diff)
downloadsamba-258952aa85f2a68e2d2362522f6114c6a439f1e3.tar.gz
samba-258952aa85f2a68e2d2362522f6114c6a439f1e3.tar.bz2
samba-258952aa85f2a68e2d2362522f6114c6a439f1e3.zip
s3: Plumb smb_filename through SMB_VFS_UNLINK
Diffstat (limited to 'source3/smbd/close.c')
-rw-r--r--source3/smbd/close.c102
1 files changed, 67 insertions, 35 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index ad21cf1d40..537394c481 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -217,31 +217,32 @@ NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
for (i=0; i<num_streams; i++) {
int res;
- char *streamname;
+ struct smb_filename *smb_fname_stream = NULL;
if (strequal(stream_info[i].name, "::$DATA")) {
continue;
}
- streamname = talloc_asprintf(talloc_tos(), "%s%s", fname,
- stream_info[i].name);
+ status = create_synthetic_smb_fname(talloc_tos(), fname,
+ stream_info[i].name, NULL,
+ &smb_fname_stream);
- if (streamname == NULL) {
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("talloc_aprintf failed\n"));
- status = NT_STATUS_NO_MEMORY;
goto fail;
}
- res = SMB_VFS_UNLINK(conn, streamname);
-
- TALLOC_FREE(streamname);
+ res = SMB_VFS_UNLINK(conn, smb_fname_stream);
if (res == -1) {
status = map_nt_error_from_unix(errno);
DEBUG(10, ("Could not delete stream %s: %s\n",
- streamname, strerror(errno)));
+ smb_fname_str_dbg(smb_fname_stream),
+ strerror(errno)));
+ TALLOC_FREE(smb_fname_stream);
break;
}
+ TALLOC_FREE(smb_fname_stream);
}
fail:
@@ -259,12 +260,19 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
connection_struct *conn = fsp->conn;
bool delete_file = false;
bool changed_user = false;
- struct share_mode_lock *lck;
- SMB_STRUCT_STAT sbuf;
+ 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.
@@ -276,8 +284,9 @@ 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", fsp->fsp_name));
- return NT_STATUS_INVALID_PARAMETER;
+ "lock for file %s\n", smb_fname_str_dbg(smb_fname)));
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
}
if (fsp->write_time_forced) {
@@ -286,7 +295,8 @@ 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", fsp->fsp_name));
+ "entry for file %s\n",
+ smb_fname_str_dbg(smb_fname)));
}
if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) {
@@ -344,7 +354,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", fsp->fsp_name));
+ "- deleting file.\n", smb_fname_str_dbg(smb_fname)));
/*
* Don't try to update the write time when we delete the file
@@ -356,7 +366,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
DEBUG(5,("close_remove_share_mode: file %s. "
"Change user to uid %u\n",
- fsp->fsp_name,
+ smb_fname_str_dbg(smb_fname),
(unsigned int)lck->delete_token->uid));
if (!push_sec_ctx()) {
@@ -377,30 +387,30 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
hasn't been renamed. */
if (fsp->posix_open) {
- ret = vfs_lstat_smb_fname(conn,fsp->fsp_name,&sbuf);
+ ret = SMB_VFS_LSTAT(conn, smb_fname);
} else {
- ret = vfs_stat_smb_fname(conn,fsp->fsp_name,&sbuf);
+ ret = SMB_VFS_STAT(conn, smb_fname);
}
if (ret != 0) {
DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
"was set and stat failed with error %s\n",
- fsp->fsp_name, strerror(errno) ));
+ smb_fname_str_dbg(smb_fname), strerror(errno)));
/*
* Don't save the errno here, we ignore this error
*/
goto done;
}
- id = vfs_file_id_from_sbuf(conn, &sbuf);
+ id = vfs_file_id_from_sbuf(conn, &smb_fname->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",
- fsp->fsp_name ));
+ smb_fname_str_dbg(smb_fname)));
DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
"stat file_id %s\n",
- fsp->fsp_name,
+ smb_fname_str_dbg(smb_fname),
file_id_string_tos(&fsp->file_id),
file_id_string_tos(&id)));
/*
@@ -410,9 +420,9 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
}
if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
- && !is_ntfs_stream_name(fsp->fsp_name)) {
+ && !is_ntfs_stream_smb_fname(smb_fname)) {
- status = delete_all_streams(conn, fsp->fsp_name);
+ status = delete_all_streams(conn, smb_fname->base_name);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("delete_all_streams failed: %s\n",
@@ -422,7 +432,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
}
- if (SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
+ if (SMB_VFS_UNLINK(conn, smb_fname) != 0) {
/*
* This call can potentially fail as another smbd may
* have had the file open with delete on close set and
@@ -433,14 +443,21 @@ 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",
- fsp->fsp_name, strerror(errno) ));
+ smb_fname_str_dbg(smb_fname), 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,
- fsp->fsp_name);
+ fname);
+
+ TALLOC_FREE(fname);
/* As we now have POSIX opens which can unlink
* with other open files we may have taken
@@ -459,6 +476,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
}
TALLOC_FREE(lck);
+ TALLOC_FREE(smb_fname);
return status;
}
@@ -637,10 +655,17 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
enum file_close_type close_type)
{
- struct share_mode_lock *lck = 0;
+ 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.
@@ -650,12 +675,15 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
NULL);
if (lck == NULL) {
- DEBUG(0, ("close_directory: Could not get share mode lock for %s\n", fsp->fsp_name));
- return NT_STATUS_INVALID_PARAMETER;
+ DEBUG(0, ("close_directory: Could not get share mode lock for "
+ "%s\n", smb_fname_str_dbg(smb_dname)));
+ 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", fsp->fsp_name));
+ DEBUG(0, ("close_directory: Could not delete share entry for "
+ "%s\n", smb_fname_str_dbg(smb_dname)));
}
if (fsp->initial_delete_on_close) {
@@ -712,12 +740,11 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
TALLOC_FREE(lck);
- status = rmdir_internals(talloc_tos(),
- fsp->conn, fsp->fsp_name);
+ status = rmdir_internals(talloc_tos(), fsp->conn, smb_dname);
DEBUG(5,("close_directory: %s. Delete on close was set - "
"deleting directory returned %s.\n",
- fsp->fsp_name, nt_errstr(status)));
+ smb_fname_str_dbg(smb_dname), nt_errstr(status)));
/* unbecome user. */
pop_sec_ctx();
@@ -740,7 +767,8 @@ 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",
- fsp->fsp_name, fsp->fh->fd, errno, strerror(errno)));
+ smb_fname_str_dbg(smb_dname), fsp->fh->fd, errno,
+ strerror(errno)));
}
/*
@@ -748,6 +776,10 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
*/
close_filestruct(fsp);
file_free(req, fsp);
+
+ out:
+ TALLOC_FREE(lck);
+ TALLOC_FREE(smb_dname);
return status;
}