summaryrefslogtreecommitdiff
path: root/source3/smbd/close.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-01-18 21:51:52 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:17:18 -0500
commitc9a14ea19f812d86266bfa9e6ce8b32f7b4ff19f (patch)
tree25357b5866e8786e6a685163a02315d0d53921a8 /source3/smbd/close.c
parent9d19e5294042e4de2c0eb70ee8b17993ebce211d (diff)
downloadsamba-c9a14ea19f812d86266bfa9e6ce8b32f7b4ff19f.tar.gz
samba-c9a14ea19f812d86266bfa9e6ce8b32f7b4ff19f.tar.bz2
samba-c9a14ea19f812d86266bfa9e6ce8b32f7b4ff19f.zip
r20883: W00t! I now understand how "delete on close" really
works - even with the strange "initial delete on close" semantics. The "initial delete on close" flag isn't committed to the share mode db until the handle is closed, and is discarded if any real "delete on close" was set. This allows me to remove the "initial_delete_on_close" flag from the share db, and move it into a BOOL in files_struct. Warning ! You must do a make clean after this. Cope with the wrinkle in directory delete on close which is done differently from files. We now pass all Samba4 smbtortute BASE-DELETE tests except for the one checking that files can't be created in a directory which has the delete on close set (possibly expensive to fix). Jeremy. (This used to be commit f2df77a1497958c1ea791f1d2f4446b5fc3389b3)
Diffstat (limited to 'source3/smbd/close.c')
-rw-r--r--source3/smbd/close.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index fe5e5eccf2..8958878433 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -22,6 +22,8 @@
#include "includes.h"
+extern struct current_user current_user;
+
/****************************************************************************
Run a file if it is a magic script.
****************************************************************************/
@@ -172,7 +174,23 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
"entry for file %s\n", fsp->fsp_name));
}
- delete_file = (lck->delete_on_close | lck->initial_delete_on_close);
+ if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) {
+ BOOL became_user = False;
+
+ /* Initial delete on close was set and no one else
+ * wrote a real delete on close. */
+
+ if (current_user.vuid != fsp->vuid) {
+ become_user(conn, fsp->vuid);
+ became_user = True;
+ }
+ set_delete_on_close_lck(lck, True, &current_user.ut);
+ if (became_user) {
+ unbecome_user();
+ }
+ }
+
+ delete_file = lck->delete_on_close;
if (delete_file) {
int i;
@@ -402,7 +420,24 @@ static int close_directory(files_struct *fsp, enum file_close_type close_type)
DEBUG(0, ("close_directory: Could not delete share entry for %s\n", fsp->fsp_name));
}
- delete_dir = (lck->delete_on_close | lck->initial_delete_on_close);
+ if (fsp->initial_delete_on_close) {
+ BOOL became_user = False;
+
+ /* Initial delete on close was set - for
+ * directories we don't care if anyone else
+ * wrote a real delete on close. */
+
+ if (current_user.vuid != fsp->vuid) {
+ become_user(fsp->conn, fsp->vuid);
+ became_user = True;
+ }
+ set_delete_on_close_lck(lck, True, &current_user.ut);
+ if (became_user) {
+ unbecome_user();
+ }
+ }
+
+ delete_dir = lck->delete_on_close;
if (delete_dir) {
int i;