svn commit: samba r23935 - in branches: SAMBA_3_0_25/source/smbd SAMBA_3_2/source/smbd SAMBA_3_2_0/source/smbd

jra at samba.org jra at samba.org
Tue Jul 17 18:48:40 GMT 2007


Author: jra
Date: 2007-07-17 18:48:39 +0000 (Tue, 17 Jul 2007)
New Revision: 23935

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

Log:
We were lying to the client in the case of POSIX_UNLINK
if a Windows client had the file open. We were setting
delete on close and returning "ok". The POSIX client then
believed the file was gone (and it wasn't). Fix this to
return SHARING_VIOLATION if there is an existing NTcreateX
open on the file and someone calls POSIX_UNLINK. Still one
more Cthon test to fix but getting closer now. Should
be in 3.0.25c also.
Jeremy.

Modified:
   branches/SAMBA_3_0_25/source/smbd/trans2.c
   branches/SAMBA_3_2/source/smbd/trans2.c
   branches/SAMBA_3_2_0/source/smbd/trans2.c


Changeset:
Modified: branches/SAMBA_3_0_25/source/smbd/trans2.c
===================================================================
--- branches/SAMBA_3_0_25/source/smbd/trans2.c	2007-07-17 14:29:05 UTC (rev 23934)
+++ branches/SAMBA_3_0_25/source/smbd/trans2.c	2007-07-17 18:48:39 UTC (rev 23935)
@@ -5542,7 +5542,10 @@
 	NTSTATUS status = NT_STATUS_OK;
 	files_struct *fsp = NULL;
 	uint16 flags = 0;
+	char del = 1;
 	int info = 0;
+	int i;
+	struct share_mode_lock *lck = NULL;
 
 	if (total_data < 2) {
 		return NT_STATUS_INVALID_PARAMETER;
@@ -5570,12 +5573,11 @@
 					DELETE_ACCESS,
 					FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
 					FILE_OPEN,
-					FILE_DELETE_ON_CLOSE,
+					0,
 					FILE_FLAG_POSIX_SEMANTICS|0777,
-					&info,				
+					&info,
 					&fsp);
 	} else {
-		char del = 1;
 
 		status = open_file_ntcreate(conn,
 				fname,
@@ -5588,26 +5590,59 @@
 				0, /* No oplock, but break existing ones. */
 				&info,
 				&fsp);
-		/* 
-		 * For file opens we must set the delete on close
-		 * after the open.
-		 */
+	}
 
-		if (!NT_STATUS_IS_OK(status)) {
-			return status;
-		}
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
 
-		status = smb_set_file_disposition_info(conn,
-							&del,
-							1,
-							fsp,
-							fname,
-							psbuf);
+	/*
+	 * Don't lie to client. If we can't really delete due to
+	 * non-POSIX opens return SHARING_VIOLATION.
+	 */
+
+	lck = get_share_mode_lock(NULL, fsp->file_id, NULL, NULL);
+	if (lck == NULL) {
+		DEBUG(0, ("smb_posix_unlink: Could not get share mode "
+			"lock for file %s\n", fsp->fsp_name));
+		close_file(fsp, NORMAL_CLOSE);
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 
+	/*
+	 * See if others still have the file open. If this is the case, then
+	 * don't delete. If all opens are POSIX delete we can set the delete
+	 * on close disposition.
+	 */
+	for (i=0; i<lck->num_share_modes; i++) {
+		struct share_mode_entry *e = &lck->share_modes[i];
+		if (is_valid_share_mode_entry(e)) {
+			if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
+				continue;
+			}
+			/* Fail with sharing violation. */
+			close_file(fsp, NORMAL_CLOSE);
+			TALLOC_FREE(lck);
+			return NT_STATUS_SHARING_VIOLATION;
+		}
+	}
+
+	/*
+	 * Set the delete on close.
+	 */
+	status = smb_set_file_disposition_info(conn,
+						&del,
+						1,
+						fsp,
+						fname,
+						psbuf);
+
 	if (!NT_STATUS_IS_OK(status)) {
+		close_file(fsp, NORMAL_CLOSE);
+		TALLOC_FREE(lck);
 		return status;
 	}
+	TALLOC_FREE(lck);
 	return close_file(fsp, NORMAL_CLOSE);
 }
 

Modified: branches/SAMBA_3_2/source/smbd/trans2.c
===================================================================
--- branches/SAMBA_3_2/source/smbd/trans2.c	2007-07-17 14:29:05 UTC (rev 23934)
+++ branches/SAMBA_3_2/source/smbd/trans2.c	2007-07-17 18:48:39 UTC (rev 23935)
@@ -5723,7 +5723,10 @@
 	NTSTATUS status = NT_STATUS_OK;
 	files_struct *fsp = NULL;
 	uint16 flags = 0;
+	char del = 1;
 	int info = 0;
+	int i;
+	struct share_mode_lock *lck = NULL;
 
 	if (total_data < 2) {
 		return NT_STATUS_INVALID_PARAMETER;
@@ -5751,12 +5754,11 @@
 					DELETE_ACCESS,
 					FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
 					FILE_OPEN,
-					FILE_DELETE_ON_CLOSE,
+					0,
 					FILE_FLAG_POSIX_SEMANTICS|0777,
-					&info,				
+					&info,
 					&fsp);
 	} else {
-		char del = 1;
 
 		status = open_file_ntcreate(conn, req,
 				fname,
@@ -5769,26 +5771,59 @@
 				0, /* No oplock, but break existing ones. */
 				&info,
 				&fsp);
-		/* 
-		 * For file opens we must set the delete on close
-		 * after the open.
-		 */
+	}
 
-		if (!NT_STATUS_IS_OK(status)) {
-			return status;
-		}
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
 
-		status = smb_set_file_disposition_info(conn,
-							&del,
-							1,
-							fsp,
-							fname,
-							psbuf);
+	/*
+	 * Don't lie to client. If we can't really delete due to
+	 * non-POSIX opens return SHARING_VIOLATION.
+	 */
+
+	lck = get_share_mode_lock(NULL, fsp->file_id, NULL, NULL);
+	if (lck == NULL) {
+		DEBUG(0, ("smb_posix_unlink: Could not get share mode "
+			"lock for file %s\n", fsp->fsp_name));
+		close_file(fsp, NORMAL_CLOSE);
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 
+	/*
+	 * See if others still have the file open. If this is the case, then
+	 * don't delete. If all opens are POSIX delete we can set the delete
+	 * on close disposition.
+	 */
+	for (i=0; i<lck->num_share_modes; i++) {
+		struct share_mode_entry *e = &lck->share_modes[i];
+		if (is_valid_share_mode_entry(e)) {
+			if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
+				continue;
+			}
+			/* Fail with sharing violation. */
+			close_file(fsp, NORMAL_CLOSE);
+			TALLOC_FREE(lck);
+			return NT_STATUS_SHARING_VIOLATION;
+		}
+	}
+
+	/*
+	 * Set the delete on close.
+	 */
+	status = smb_set_file_disposition_info(conn,
+						&del,
+						1,
+						fsp,
+						fname,
+						psbuf);
+
 	if (!NT_STATUS_IS_OK(status)) {
+		close_file(fsp, NORMAL_CLOSE);
+		TALLOC_FREE(lck);
 		return status;
 	}
+	TALLOC_FREE(lck);
 	return close_file(fsp, NORMAL_CLOSE);
 }
 

Modified: branches/SAMBA_3_2_0/source/smbd/trans2.c
===================================================================
--- branches/SAMBA_3_2_0/source/smbd/trans2.c	2007-07-17 14:29:05 UTC (rev 23934)
+++ branches/SAMBA_3_2_0/source/smbd/trans2.c	2007-07-17 18:48:39 UTC (rev 23935)
@@ -5669,7 +5669,10 @@
 	NTSTATUS status = NT_STATUS_OK;
 	files_struct *fsp = NULL;
 	uint16 flags = 0;
+	char del = 1;
 	int info = 0;
+	int i;
+	struct share_mode_lock *lck = NULL;
 
 	if (total_data < 2) {
 		return NT_STATUS_INVALID_PARAMETER;
@@ -5697,12 +5700,11 @@
 					DELETE_ACCESS,
 					FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
 					FILE_OPEN,
-					FILE_DELETE_ON_CLOSE,
+					0,
 					FILE_FLAG_POSIX_SEMANTICS|0777,
-					&info,				
+					&info,
 					&fsp);
 	} else {
-		char del = 1;
 
 		status = open_file_ntcreate(conn, req,
 				fname,
@@ -5715,26 +5717,59 @@
 				0, /* No oplock, but break existing ones. */
 				&info,
 				&fsp);
-		/* 
-		 * For file opens we must set the delete on close
-		 * after the open.
-		 */
+	}
 
-		if (!NT_STATUS_IS_OK(status)) {
-			return status;
-		}
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
 
-		status = smb_set_file_disposition_info(conn,
-							&del,
-							1,
-							fsp,
-							fname,
-							psbuf);
+	/*
+	 * Don't lie to client. If we can't really delete due to
+	 * non-POSIX opens return SHARING_VIOLATION.
+	 */
+
+	lck = get_share_mode_lock(NULL, fsp->file_id, NULL, NULL);
+	if (lck == NULL) {
+		DEBUG(0, ("smb_posix_unlink: Could not get share mode "
+			"lock for file %s\n", fsp->fsp_name));
+		close_file(fsp, NORMAL_CLOSE);
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 
+	/*
+	 * See if others still have the file open. If this is the case, then
+	 * don't delete. If all opens are POSIX delete we can set the delete
+	 * on close disposition.
+	 */
+	for (i=0; i<lck->num_share_modes; i++) {
+		struct share_mode_entry *e = &lck->share_modes[i];
+		if (is_valid_share_mode_entry(e)) {
+			if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
+				continue;
+			}
+			/* Fail with sharing violation. */
+			close_file(fsp, NORMAL_CLOSE);
+			TALLOC_FREE(lck);
+			return NT_STATUS_SHARING_VIOLATION;
+		}
+	}
+
+	/*
+	 * Set the delete on close.
+	 */
+	status = smb_set_file_disposition_info(conn,
+						&del,
+						1,
+						fsp,
+						fname,
+						psbuf);
+
 	if (!NT_STATUS_IS_OK(status)) {
+		close_file(fsp, NORMAL_CLOSE);
+		TALLOC_FREE(lck);
 		return status;
 	}
+	TALLOC_FREE(lck);
 	return close_file(fsp, NORMAL_CLOSE);
 }
 



More information about the samba-cvs mailing list