From e47520f2221ea34a2264a3cc03fe1c5fcc5bf5c5 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 22 Dec 2007 02:01:26 +0100 Subject: Remove redundant connection_struct from fd_close() parameter list. Michael (This used to be commit 3611cc8561cf837adea83fc7c16ca7535f188466) --- source3/smbd/close.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/close.c') diff --git a/source3/smbd/close.c b/source3/smbd/close.c index eb610f7d1a..ff96c99712 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -389,7 +389,7 @@ static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_ locking_close_file(smbd_messaging_context(), fsp); - status = fd_close(conn, fsp); + status = fd_close(fsp); /* check for magic scripts */ if (close_type == NORMAL_CLOSE) { -- cgit From a000fa4ee5491ae32c60881b28b3536e88e82e27 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 22 Dec 2007 02:13:02 +0100 Subject: Remove redundant connection_struct from check_magic() parameter list. Michael (This used to be commit cebaa483e62910ac3f87cd135b2aff18dc880416) --- source3/smbd/close.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/smbd/close.c') diff --git a/source3/smbd/close.c b/source3/smbd/close.c index ff96c99712..5d30e467d0 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -27,7 +27,7 @@ extern struct current_user current_user; Run a file if it is a magic script. ****************************************************************************/ -static void check_magic(files_struct *fsp,connection_struct *conn) +static void check_magic(struct files_struct *fsp) { int ret; const char *magic_output = NULL; @@ -35,6 +35,7 @@ static void check_magic(files_struct *fsp,connection_struct *conn) int tmp_fd, outfd; TALLOC_CTX *ctx = NULL; const char *p; + struct connection_struct *conn = fsp->conn; if (!*lp_magicscript(SNUM(conn))) { return; @@ -393,7 +394,7 @@ static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_ /* check for magic scripts */ if (close_type == NORMAL_CLOSE) { - check_magic(fsp,conn); + check_magic(fsp); } /* -- cgit From 3cc3b9e1879d3d9714ac2914364418a140e8389c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 6 Jan 2008 14:21:25 +0100 Subject: use talloc_tos in a few more places (This used to be commit 65dd869bea351010c67f02046ae4134bdada1a4c) --- source3/smbd/close.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/close.c') diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 5d30e467d0..c74e13348e 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -176,7 +176,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, * This prevents race conditions with the file being created. JRA. */ - lck = get_share_mode_lock(NULL, fsp->file_id, NULL, NULL); + lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL); if (lck == NULL) { DEBUG(0, ("close_remove_share_mode: Could not get share mode " @@ -441,7 +441,7 @@ static NTSTATUS close_directory(files_struct *fsp, enum file_close_type close_ty * reference to a directory also. */ - lck = get_share_mode_lock(NULL, fsp->file_id, NULL, NULL); + lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL); if (lck == NULL) { DEBUG(0, ("close_directory: Could not get share mode lock for %s\n", fsp->fsp_name)); -- cgit From f33f4ef4a24fcbf09eeba0d51e7db74e9b13b432 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 10 Jan 2008 16:35:54 -0800 Subject: Don't switch user contexts unless you have to. Saves a bunch of syscalls on close. Noticed by Volker. Jeremy. (This used to be commit 3caeeaea162e2083a087c242b850c107a3be1bf9) --- source3/smbd/close.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) (limited to 'source3/smbd/close.c') diff --git a/source3/smbd/close.c b/source3/smbd/close.c index c74e13348e..f67a4ad668 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -163,7 +163,8 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, enum file_close_type close_type) { connection_struct *conn = fsp->conn; - bool delete_file = False; + bool delete_file = false; + bool changed_user = false; struct share_mode_lock *lck; SMB_STRUCT_STAT sbuf; NTSTATUS status = NT_STATUS_OK; @@ -246,18 +247,26 @@ 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)); - /* Become the user who requested the delete. */ + if (!unix_token_equal(lck->delete_token, ¤t_user.ut)) { + /* Become the user who requested the delete. */ - if (!push_sec_ctx()) { - smb_panic("close_remove_share_mode: file %s. failed to push " - "sec_ctx.\n"); - } + DEBUG(5,("close_remove_share_mode: file %s. " + "Change user to uid %u\n", + (unsigned int)lck->delete_token->uid)); - set_sec_ctx(lck->delete_token->uid, - lck->delete_token->gid, - lck->delete_token->ngroups, - lck->delete_token->groups, - NULL); + if (!push_sec_ctx()) { + smb_panic("close_remove_share_mode: file %s. failed to push " + "sec_ctx.\n"); + } + + set_sec_ctx(lck->delete_token->uid, + lck->delete_token->gid, + lck->delete_token->ngroups, + lck->delete_token->groups, + NULL); + + changed_user = true; + } /* We can only delete the file if the name we have is still valid and hasn't been renamed. */ @@ -326,9 +335,11 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, done: - /* unbecome user. */ - pop_sec_ctx(); - + if (changed_user) { + /* unbecome user. */ + pop_sec_ctx(); + } + TALLOC_FREE(lck); return status; } -- cgit From 2539cf073915c481ae449e2eb11f501c29276688 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 Jan 2008 18:46:41 +0100 Subject: Fix a build warning. Guenther (This used to be commit 88874a501d0c086f796e4838af8c9399d3cccc1f) --- source3/smbd/close.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/close.c') diff --git a/source3/smbd/close.c b/source3/smbd/close.c index f67a4ad668..4c385d7611 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -252,6 +252,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, (unsigned int)lck->delete_token->uid)); if (!push_sec_ctx()) { -- cgit From 1069cfe4ade88a032164c1242c9480a544584655 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 23:25:36 +0100 Subject: Add streams support This is the core of the streams support. The main change is that in files_struct there is now a base_fsp pointer that holds the main file open while a stream is open. This is necessary to get the rather strange delete semantics right: You can't delete the main file while a stream is open without FILE_SHARE_DELETE, and while a stream is open a successful unlink of the main file leads to DELETE_PENDING for all further access on the main file or any stream. (This used to be commit 6022873cc155bdbbd3fb620689715f07a24d6ed1) --- source3/smbd/close.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 4 deletions(-) (limited to 'source3/smbd/close.c') diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 4c385d7611..4bd23a35fc 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -155,6 +155,75 @@ static void notify_deferred_opens(struct share_mode_lock *lck) } } +/**************************************************************************** + Delete all streams +****************************************************************************/ + +static NTSTATUS delete_all_streams(connection_struct *conn, const char *fname) +{ + struct stream_struct *stream_info; + int i; + unsigned int num_streams; + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status; + + status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(), + &num_streams, &stream_info); + + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { + DEBUG(10, ("no streams around\n")); + TALLOC_FREE(frame); + return NT_STATUS_OK; + } + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n", + nt_errstr(status))); + goto fail; + } + + DEBUG(10, ("delete_all_streams found %d streams\n", + num_streams)); + + if (num_streams == 0) { + TALLOC_FREE(frame); + return NT_STATUS_OK; + } + + for (i=0; ifs_capabilities & FILE_NAMED_STREAMS) + && !is_ntfs_stream_name(fsp->fsp_name)) { + + status = delete_all_streams(conn, fsp->fsp_name); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(5, ("delete_all_streams failed: %s\n", + nt_errstr(status))); + goto done; + } + } + + if (SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) { /* * This call can potentially fail as another smbd may @@ -570,12 +652,37 @@ static NTSTATUS close_stat(files_struct *fsp) NTSTATUS close_file(files_struct *fsp, enum file_close_type close_type) { + NTSTATUS status; + struct files_struct *base_fsp = fsp->base_fsp; + if(fsp->is_directory) { - return close_directory(fsp, close_type); + status = close_directory(fsp, close_type); } else if (fsp->is_stat) { - return close_stat(fsp); + status = close_stat(fsp); } else if (fsp->fake_file_handle != NULL) { - return close_fake_file(fsp); + status = close_fake_file(fsp); + } else { + status = close_normal_file(fsp, close_type); + } + + if (!NT_STATUS_IS_OK(status)) { + return status; } - return close_normal_file(fsp, close_type); + + if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) { + + /* + * fsp was a stream, the base fsp can't be a stream as well + * + * For SHUTDOWN_CLOSE this is not possible here, because + * SHUTDOWN_CLOSE only happens from files.c which walks the + * complete list of files. If we mess with more than one fsp + * those loops will become confused. + */ + + SMB_ASSERT(base_fsp->base_fsp == NULL); + close_file(base_fsp, close_type); + } + + return status; } -- cgit