The branch, v3-5-test has been updated
via 3782315 Fix bug 8111 - CIFS VFS: unexpected error on SMB posix open
from 80078cb Fix is_myname_or_ipaddr() to be robust against strange DNS
setups.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-5-test
- Log -----------------------------------------------------------------
commit 37823155157d735356e1f223b425252c956d8c04
Author: Jeremy Allison <[email protected]>
Date: Fri Apr 29 14:22:54 2011 -0700
Fix bug 8111 - CIFS VFS: unexpected error on SMB posix open
We are conflating the O_CREAT|O_EXCL with the O_TRUNC
processing, they need to be separate. We need to chose
using (O_CREAT|O_EXCL) first, then modify if O_TRUNC is
set. This needs two separate switch statements.
Jeremy
-----------------------------------------------------------------------
Summary of changes:
source3/smbd/trans2.c | 61 +++++++++++++++++++++++++++++++++++++++---------
1 files changed, 49 insertions(+), 12 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 1a171d8..0d14421 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -7045,18 +7045,55 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
wire_open_mode &= ~SMB_ACCMODE;
- if((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) == (SMB_O_CREAT |
SMB_O_EXCL)) {
- create_disp = FILE_CREATE;
- } else if((wire_open_mode & (SMB_O_CREAT | SMB_O_TRUNC)) ==
(SMB_O_CREAT | SMB_O_TRUNC)) {
- create_disp = FILE_OVERWRITE_IF;
- } else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) {
- create_disp = FILE_OPEN_IF;
- } else if ((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL | SMB_O_TRUNC))
== 0) {
- create_disp = FILE_OPEN;
- } else {
- DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
- (unsigned int)wire_open_mode ));
- return NT_STATUS_INVALID_PARAMETER;
+ /* First take care of O_CREAT|O_EXCL interactions. */
+ switch (wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) {
+ case (SMB_O_CREAT | SMB_O_EXCL):
+ /* File exists fail. File not exist create. */
+ create_disp = FILE_CREATE;
+ break;
+ case SMB_O_CREAT:
+ /* File exists open. File not exist create. */
+ create_disp = FILE_OPEN_IF;
+ break;
+ case 0:
+ /* File exists open. File not exist fail. */
+ create_disp = FILE_OPEN;
+ break;
+ case SMB_O_EXCL:
+ /* O_EXCL on its own without O_CREAT is undefined. */
+ default:
+ DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
+ (unsigned int)wire_open_mode ));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* Next factor in the effects of O_TRUNC. */
+ wire_open_mode &= ~(SMB_O_CREAT | SMB_O_EXCL);
+
+ if (wire_open_mode & SMB_O_TRUNC) {
+ switch (create_disp) {
+ case FILE_CREATE:
+ /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
+ /* Leave create_disp alone as
+ (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
+ */
+ /* File exists fail. File not exist create. */
+ break;
+ case FILE_OPEN_IF:
+ /* SMB_O_CREAT | SMB_O_TRUNC */
+ /* File exists overwrite. File not exist
create. */
+ create_disp = FILE_OVERWRITE_IF;
+ break;
+ case FILE_OPEN:
+ /* SMB_O_TRUNC */
+ /* File exists overwrite. File not exist fail.
*/
+ create_disp = FILE_OVERWRITE;
+ break;
+ default:
+ /* Cannot get here. */
+ smb_panic("smb_posix_open: logic error");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
}
raw_unixmode = IVAL(pdata,8);
--
Samba Shared Repository