summaryrefslogtreecommitdiff
path: root/source3/smbd/close.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2006-02-02 20:44:50 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:06:21 -0500
commitd14af63e6ab600eb3ac705f2f425c860e927553a (patch)
tree9be5b1da9836c61c7b1bf2df72df7014944b8599 /source3/smbd/close.c
parent206cbff8b72a2ccc41e52b45097976f4511bfdec (diff)
downloadsamba-d14af63e6ab600eb3ac705f2f425c860e927553a.tar.gz
samba-d14af63e6ab600eb3ac705f2f425c860e927553a.tar.bz2
samba-d14af63e6ab600eb3ac705f2f425c860e927553a.zip
r13293: Rather a big patch I'm afraid, but this should fix bug #3347
by saving the UNIX token used to set a delete on close flag, and using it when doing the delete. libsmbsharemodes.so still needs updating to cope with this change. Samba4 torture tests to follow. Jeremy. (This used to be commit 23f16cbc2e8cde97c486831e26bcafd4ab4a9654)
Diffstat (limited to 'source3/smbd/close.c')
-rw-r--r--source3/smbd/close.c66
1 files changed, 51 insertions, 15 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index d284c82f44..059b88ecc8 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -145,13 +145,12 @@ static void notify_deferred_opens(struct share_mode_lock *lck)
/****************************************************************************
Close a file.
- If normal_close is 1 then this came from a normal SMBclose (or equivalent)
- operation otherwise it came as the result of some other operation such as
- the closing of the connection. In the latter case printing and
- magic scripts are not run.
+ close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
+ printing and magic scripts are only run on normal close.
+ delete on close is done on normal and shutdown close.
****************************************************************************/
-static int close_normal_file(files_struct *fsp, BOOL normal_close)
+static int close_normal_file(files_struct *fsp, enum file_close_type close_type)
{
BOOL delete_file = False;
connection_struct *conn = fsp->conn;
@@ -187,7 +186,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
}
if (fsp->print_file) {
- print_fsp_end(fsp, normal_close);
+ print_fsp_end(fsp, close_type);
file_free(fsp);
return 0;
}
@@ -232,12 +231,26 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
* reference to a file.
*/
- if (normal_close && delete_file) {
+ if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
+ delete_file &&
+ lck->delete_token) {
SMB_STRUCT_STAT sbuf;
DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
fsp->fsp_name));
+ /* Become the user who requested the delete. */
+
+ if (!push_sec_ctx()) {
+ smb_panic("close_file: 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);
+
/* We can only delete the file if the name we have
is still valid and hasn't been renamed. */
@@ -268,8 +281,11 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
"and unlink failed with error %s\n",
fsp->fsp_name, strerror(errno) ));
}
- process_pending_change_notify_queue((time_t)0);
}
+ /* unbecome user. */
+ pop_sec_ctx();
+
+ process_pending_change_notify_queue((time_t)0);
}
talloc_free(lck);
@@ -288,7 +304,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
}
/* check for magic scripts */
- if (normal_close) {
+ if (close_type == NORMAL_CLOSE) {
check_magic(fsp,conn);
}
@@ -324,7 +340,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
Close a directory opened by an NT SMB call.
****************************************************************************/
-static int close_directory(files_struct *fsp, BOOL normal_close)
+static int close_directory(files_struct *fsp, enum file_close_type close_type)
{
struct share_mode_lock *lck = 0;
BOOL delete_dir = False;
@@ -349,11 +365,31 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
talloc_free(lck);
- if (normal_close && delete_dir) {
- BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
+ if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
+ delete_dir &&
+ lck->delete_token) {
+ BOOL ok;
+
+ /* Become the user who requested the delete. */
+
+ if (!push_sec_ctx()) {
+ smb_panic("close_directory: 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);
+
+ ok = rmdir_internals(fsp->conn, fsp->fsp_name);
+
DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
fsp->fsp_name, ok ? "succeeded" : "failed" ));
+ /* unbecome user. */
+ pop_sec_ctx();
+
/*
* Ensure we remove any change notify requests that would
* now fail as the directory has been deleted.
@@ -404,12 +440,12 @@ static int close_stat(files_struct *fsp)
Close a files_struct.
****************************************************************************/
-int close_file(files_struct *fsp, BOOL normal_close)
+int close_file(files_struct *fsp, enum file_close_type close_type)
{
if(fsp->is_directory)
- return close_directory(fsp, normal_close);
+ return close_directory(fsp, close_type);
else if (fsp->is_stat)
return close_stat(fsp);
else
- return close_normal_file(fsp, normal_close);
+ return close_normal_file(fsp, close_type);
}