svn commit: samba r20883 - in branches: SAMBA_3_0/source/include SAMBA_3_0/source/libsmb SAMBA_3_0/source/locking SAMBA_3_0/source/smbd SAMBA_3_0_24/source/include SAMBA_3_0_24/source/libsmb SAMBA_3_0_24/source/locking SAMBA_3_0_24/source/smbd

jra at samba.org jra at samba.org
Thu Jan 18 21:51:54 GMT 2007


Author: jra
Date: 2007-01-18 21:51:52 +0000 (Thu, 18 Jan 2007)
New Revision: 20883

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=20883

Log:
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.

Modified:
   branches/SAMBA_3_0/source/include/smb.h
   branches/SAMBA_3_0/source/libsmb/smb_share_modes.c
   branches/SAMBA_3_0/source/locking/locking.c
   branches/SAMBA_3_0/source/smbd/close.c
   branches/SAMBA_3_0/source/smbd/open.c
   branches/SAMBA_3_0_24/source/include/smb.h
   branches/SAMBA_3_0_24/source/libsmb/smb_share_modes.c
   branches/SAMBA_3_0_24/source/locking/locking.c
   branches/SAMBA_3_0_24/source/smbd/close.c
   branches/SAMBA_3_0_24/source/smbd/open.c


Changeset:
Modified: branches/SAMBA_3_0/source/include/smb.h
===================================================================
--- branches/SAMBA_3_0/source/include/smb.h	2007-01-18 21:50:46 UTC (rev 20882)
+++ branches/SAMBA_3_0/source/include/smb.h	2007-01-18 21:51:52 UTC (rev 20883)
@@ -506,6 +506,7 @@
 	BOOL is_stat;
 	BOOL aio_write_behind;
 	BOOL lockdb_clean;
+	BOOL initial_delete_on_close; /* Only set at NTCreateX if file was created. */
 	char *fsp_name;
 
 	struct vfs_fsp_data *vfs_extension;
@@ -773,7 +774,6 @@
 	struct share_mode_entry *share_modes;
 	UNIX_USER_TOKEN *delete_token;
 	BOOL delete_on_close;
-	BOOL initial_delete_on_close;
 	BOOL fresh;
 	BOOL modified;
 };
@@ -788,7 +788,6 @@
 		struct {
 			int num_share_mode_entries;
 			BOOL delete_on_close;
-			BOOL initial_delete_on_close; /* Only set at NTCreateX if file was created. */
 			uint32 delete_token_size; /* Only valid if either of
 						     the two previous fields
 						     are True. */

Modified: branches/SAMBA_3_0/source/libsmb/smb_share_modes.c
===================================================================
--- branches/SAMBA_3_0/source/libsmb/smb_share_modes.c	2007-01-18 21:50:46 UTC (rev 20882)
+++ branches/SAMBA_3_0/source/libsmb/smb_share_modes.c	2007-01-18 21:51:52 UTC (rev 20883)
@@ -274,7 +274,6 @@
 		memset(ld, '\0', sizeof(struct locking_data));
 		ld->u.s.num_share_mode_entries = 1;
 		ld->u.s.delete_on_close = 0;
-		ld->u.s.initial_delete_on_close = 0;
 		ld->u.s.delete_token_size = 0;
 		shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
 		create_share_mode_entry(shares, new_entry);

Modified: branches/SAMBA_3_0/source/locking/locking.c
===================================================================
--- branches/SAMBA_3_0/source/locking/locking.c	2007-01-18 21:50:46 UTC (rev 20882)
+++ branches/SAMBA_3_0/source/locking/locking.c	2007-01-18 21:51:52 UTC (rev 20883)
@@ -473,14 +473,11 @@
 	data = (struct locking_data *)dbuf.dptr;
 
 	lck->delete_on_close = data->u.s.delete_on_close;
-	lck->initial_delete_on_close = data->u.s.initial_delete_on_close;
 	lck->num_share_modes = data->u.s.num_share_mode_entries;
 
 	DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
-		   "initial_delete_on_close: %d, "
 		   "num_share_modes: %d\n",
 		lck->delete_on_close,
-		lck->initial_delete_on_close,
 		lck->num_share_modes));
 
 	if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
@@ -635,11 +632,9 @@
 	ZERO_STRUCTP(data);
 	data->u.s.num_share_mode_entries = lck->num_share_modes;
 	data->u.s.delete_on_close = lck->delete_on_close;
-	data->u.s.initial_delete_on_close = lck->initial_delete_on_close;
 	data->u.s.delete_token_size = delete_token_size;
-	DEBUG(10, ("unparse_share_modes: del: %d, initial del %d, tok = %u, num: %d\n",
+	DEBUG(10, ("unparse_share_modes: del: %d, tok = %u, num: %d\n",
 		data->u.s.delete_on_close,
-		data->u.s.initial_delete_on_close,
 		(unsigned int)data->u.s.delete_token_size,
 		data->u.s.num_share_mode_entries));
 	memcpy(result.dptr + sizeof(*data), lck->share_modes,
@@ -734,7 +729,6 @@
 	lck->share_modes = NULL;
 	lck->delete_token = NULL;
 	lck->delete_on_close = False;
-	lck->initial_delete_on_close = False;
 	lck->fresh = False;
 	lck->modified = False;
 
@@ -1251,11 +1245,22 @@
  changed the delete on close flag. This will be noticed
  in the close code, the last closer will delete the file
  if flag is set.
- Note that setting this to any value clears the initial_delete_on_close flag.
- If delete_on_close is True this makes a copy of any UNIX_USER_TOKEN into the
- lck entry.
+ This makes a copy of any UNIX_USER_TOKEN into the
+ lck entry. This function is used when the lock is already granted.
 ****************************************************************************/
 
+void set_delete_on_close_lck(struct share_mode_lock *lck, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
+{
+	if (lck->delete_on_close != delete_on_close) {
+		set_delete_on_close_token(lck, tok);
+		lck->delete_on_close = delete_on_close;
+		if (delete_on_close) {
+			SMB_ASSERT(lck->delete_token != NULL);
+		}
+		lck->modified = True;
+	}
+}
+
 BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
 {
 	struct share_mode_lock *lck;
@@ -1274,20 +1279,8 @@
 		return False;
 	}
 
-	if (lck->delete_on_close != delete_on_close) {
-		set_delete_on_close_token(lck, tok);
-		lck->delete_on_close = delete_on_close;
-		if (delete_on_close) {
-			SMB_ASSERT(lck->delete_token != NULL);
-		}
-		lck->modified = True;
-	}
+	set_delete_on_close_lck(lck, delete_on_close, tok);
 
-	if (lck->initial_delete_on_close) {
-		lck->initial_delete_on_close = False;
-		lck->modified = True;
-	}
-
 	TALLOC_FREE(lck);
 	return True;
 }

Modified: branches/SAMBA_3_0/source/smbd/close.c
===================================================================
--- branches/SAMBA_3_0/source/smbd/close.c	2007-01-18 21:50:46 UTC (rev 20882)
+++ branches/SAMBA_3_0/source/smbd/close.c	2007-01-18 21:51:52 UTC (rev 20883)
@@ -22,6 +22,8 @@
 
 #include "includes.h"
 
+extern struct current_user current_user;
+
 /****************************************************************************
  Run a file if it is a magic script.
 ****************************************************************************/
@@ -172,8 +174,24 @@
 			  "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;
 		/* See if others still have the file open. If this is the
@@ -402,8 +420,25 @@
 		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;
 		/* See if others still have the dir open. If this is the

Modified: branches/SAMBA_3_0/source/smbd/open.c
===================================================================
--- branches/SAMBA_3_0/source/smbd/open.c	2007-01-18 21:50:46 UTC (rev 20882)
+++ branches/SAMBA_3_0/source/smbd/open.c	2007-01-18 21:51:52 UTC (rev 20883)
@@ -1761,10 +1761,8 @@
 				return status;
 			}
 			/* Note that here we set the *inital* delete on close flag,
-			   not the regular one. */
-			set_delete_on_close_token(lck, &current_user.ut);
-			lck->initial_delete_on_close = True;
-			lck->modified = True;
+			   not the regular one. The magic gets handled in close. */
+			fsp->initial_delete_on_close = True;
 		}
 	
 		/* Files should be initially set as archive */
@@ -2117,9 +2115,9 @@
 		}
 
 		if (NT_STATUS_IS_OK(status)) {
-			set_delete_on_close_token(lck, &current_user.ut);
-			lck->initial_delete_on_close = True;
-			lck->modified = True;
+			/* Note that here we set the *inital* delete on close flag,
+			   not the regular one. The magic gets handled in close. */
+			fsp->initial_delete_on_close = True;
 		}
 	}
 

Modified: branches/SAMBA_3_0_24/source/include/smb.h
===================================================================
--- branches/SAMBA_3_0_24/source/include/smb.h	2007-01-18 21:50:46 UTC (rev 20882)
+++ branches/SAMBA_3_0_24/source/include/smb.h	2007-01-18 21:51:52 UTC (rev 20883)
@@ -455,6 +455,7 @@
 	BOOL is_stat;
 	BOOL aio_write_behind;
 	BOOL lockdb_clean;
+	BOOL initial_delete_on_close; /* Only set at NTCreateX if file was created. */
 	char *fsp_name;
 
 	struct vfs_fsp_data *vfs_extension;
@@ -722,7 +723,6 @@
 	struct share_mode_entry *share_modes;
 	UNIX_USER_TOKEN *delete_token;
 	BOOL delete_on_close;
-	BOOL initial_delete_on_close;
 	BOOL fresh;
 	BOOL modified;
 };
@@ -737,7 +737,6 @@
 		struct {
 			int num_share_mode_entries;
 			BOOL delete_on_close;
-			BOOL initial_delete_on_close; /* Only set at NTCreateX if file was created. */
 			uint32 delete_token_size; /* Only valid if either of
 						     the two previous fields
 						     are True. */

Modified: branches/SAMBA_3_0_24/source/libsmb/smb_share_modes.c
===================================================================
--- branches/SAMBA_3_0_24/source/libsmb/smb_share_modes.c	2007-01-18 21:50:46 UTC (rev 20882)
+++ branches/SAMBA_3_0_24/source/libsmb/smb_share_modes.c	2007-01-18 21:51:52 UTC (rev 20883)
@@ -274,7 +274,6 @@
 		memset(ld, '\0', sizeof(struct locking_data));
 		ld->u.s.num_share_mode_entries = 1;
 		ld->u.s.delete_on_close = 0;
-		ld->u.s.initial_delete_on_close = 0;
 		ld->u.s.delete_token_size = 0;
 		shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
 		create_share_mode_entry(shares, new_entry);

Modified: branches/SAMBA_3_0_24/source/locking/locking.c
===================================================================
--- branches/SAMBA_3_0_24/source/locking/locking.c	2007-01-18 21:50:46 UTC (rev 20882)
+++ branches/SAMBA_3_0_24/source/locking/locking.c	2007-01-18 21:51:52 UTC (rev 20883)
@@ -473,14 +473,11 @@
 	data = (struct locking_data *)dbuf.dptr;
 
 	lck->delete_on_close = data->u.s.delete_on_close;
-	lck->initial_delete_on_close = data->u.s.initial_delete_on_close;
 	lck->num_share_modes = data->u.s.num_share_mode_entries;
 
 	DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
-		   "initial_delete_on_close: %d, "
 		   "num_share_modes: %d\n",
 		lck->delete_on_close,
-		lck->initial_delete_on_close,
 		lck->num_share_modes));
 
 	if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
@@ -635,11 +632,9 @@
 	ZERO_STRUCTP(data);
 	data->u.s.num_share_mode_entries = lck->num_share_modes;
 	data->u.s.delete_on_close = lck->delete_on_close;
-	data->u.s.initial_delete_on_close = lck->initial_delete_on_close;
 	data->u.s.delete_token_size = delete_token_size;
-	DEBUG(10, ("unparse_share_modes: del: %d, initial del %d, tok = %u, num: %d\n",
+	DEBUG(10, ("unparse_share_modes: del: %d, tok = %u, num: %d\n",
 		data->u.s.delete_on_close,
-		data->u.s.initial_delete_on_close,
 		(unsigned int)data->u.s.delete_token_size,
 		data->u.s.num_share_mode_entries));
 	memcpy(result.dptr + sizeof(*data), lck->share_modes,
@@ -734,7 +729,6 @@
 	lck->share_modes = NULL;
 	lck->delete_token = NULL;
 	lck->delete_on_close = False;
-	lck->initial_delete_on_close = False;
 	lck->fresh = False;
 	lck->modified = False;
 
@@ -1251,11 +1245,22 @@
  changed the delete on close flag. This will be noticed
  in the close code, the last closer will delete the file
  if flag is set.
- Note that setting this to any value clears the initial_delete_on_close flag.
- If delete_on_close is True this makes a copy of any UNIX_USER_TOKEN into the
- lck entry.
+ This makes a copy of any UNIX_USER_TOKEN into the
+ lck entry. This function is used when the lock is already granted.
 ****************************************************************************/
 
+void set_delete_on_close_lck(struct share_mode_lock *lck, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
+{
+	if (lck->delete_on_close != delete_on_close) {
+		set_delete_on_close_token(lck, tok);
+		lck->delete_on_close = delete_on_close;
+		if (delete_on_close) {
+			SMB_ASSERT(lck->delete_token != NULL);
+		}
+		lck->modified = True;
+	}
+}
+
 BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
 {
 	struct share_mode_lock *lck;
@@ -1274,20 +1279,8 @@
 		return False;
 	}
 
-	if (lck->delete_on_close != delete_on_close) {
-		set_delete_on_close_token(lck, tok);
-		lck->delete_on_close = delete_on_close;
-		if (delete_on_close) {
-			SMB_ASSERT(lck->delete_token != NULL);
-		}
-		lck->modified = True;
-	}
+	set_delete_on_close_lck(lck, delete_on_close, tok);
 
-	if (lck->initial_delete_on_close) {
-		lck->initial_delete_on_close = False;
-		lck->modified = True;
-	}
-
 	TALLOC_FREE(lck);
 	return True;
 }

Modified: branches/SAMBA_3_0_24/source/smbd/close.c
===================================================================
--- branches/SAMBA_3_0_24/source/smbd/close.c	2007-01-18 21:50:46 UTC (rev 20882)
+++ branches/SAMBA_3_0_24/source/smbd/close.c	2007-01-18 21:51:52 UTC (rev 20883)
@@ -22,6 +22,8 @@
 
 #include "includes.h"
 
+extern struct current_user current_user;
+
 /****************************************************************************
  Run a file if it is a magic script.
 ****************************************************************************/
@@ -172,8 +174,24 @@
 			  "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;
 		/* See if others still have the file open. If this is the
@@ -402,8 +420,25 @@
 		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;
 		/* See if others still have the dir open. If this is the

Modified: branches/SAMBA_3_0_24/source/smbd/open.c
===================================================================
--- branches/SAMBA_3_0_24/source/smbd/open.c	2007-01-18 21:50:46 UTC (rev 20882)
+++ branches/SAMBA_3_0_24/source/smbd/open.c	2007-01-18 21:51:52 UTC (rev 20883)
@@ -1755,10 +1755,8 @@
 				return status;
 			}
 			/* Note that here we set the *inital* delete on close flag,
-			   not the regular one. */
-			set_delete_on_close_token(lck, &current_user.ut);
-			lck->initial_delete_on_close = True;
-			lck->modified = True;
+			   not the regular one. The magic gets handled in close. */
+			fsp->initial_delete_on_close = True;
 		}
 	
 		/* Files should be initially set as archive */
@@ -2108,9 +2106,9 @@
 		}
 
 		if (NT_STATUS_IS_OK(status)) {
-			set_delete_on_close_token(lck, &current_user.ut);
-			lck->initial_delete_on_close = True;
-			lck->modified = True;
+			/* Note that here we set the *inital* delete on close flag,
+			   not the regular one. The magic gets handled in close. */
+			fsp->initial_delete_on_close = True;
 		}
 	}
 



More information about the samba-cvs mailing list