From bda0b905c72d1a79c78eb6182c1c7928142fe280 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 23 Nov 2009 17:05:43 -0800 Subject: [PATCH] Fix bug #6898 - Samba duplicates file content on appending. Move posix case semantics out from under the VFS. Jeremy. --- source3/smbd/nttrans.c | 43 +++++++++++++++++++++++++++++++++++++++++++ source3/smbd/open.c | 11 ----------- source3/smbd/trans2.c | 16 ++++++++++++++++ 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 9f30f06..eaf619d 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -436,6 +436,7 @@ void reply_ntcreate_and_X(struct smb_request *req) NTSTATUS status; int oplock_request; uint8_t oplock_granted = NO_OPLOCK_RETURN; + struct case_semantics_state *case_state = NULL; TALLOC_CTX *ctx = talloc_tos(); START_PROFILE(SMBntcreateX); @@ -509,6 +510,25 @@ void reply_ntcreate_and_X(struct smb_request *req) ? BATCH_OPLOCK : 0; } + /* + * Check if POSIX semantics are wanted. + */ + + if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) { + case_state = set_posix_case_semantics(ctx, conn); + if (!case_state) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + END_PROFILE(SMBntcreateX); + return; + } + /* + * Bug #6898 - clients using Windows opens should + * never be able to set this attribute into the + * VFS. + */ + file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS; + } + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ @@ -528,6 +548,8 @@ void reply_ntcreate_and_X(struct smb_request *req) &info, /* pinfo */ &sbuf); /* psbuf */ + TALLOC_FREE(case_state); + if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { /* We have re-scheduled this call, no error. */ @@ -864,6 +886,7 @@ static void call_nt_transact_create(connection_struct *conn, uint64_t allocation_size; int oplock_request; uint8_t oplock_granted; + struct case_semantics_state *case_state = NULL; TALLOC_CTX *ctx = talloc_tos(); SET_STAT_INVALID(sbuf); @@ -983,6 +1006,24 @@ static void call_nt_transact_create(connection_struct *conn, ? BATCH_OPLOCK : 0; } + /* + * Check if POSIX semantics are wanted. + */ + + if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) { + case_state = set_posix_case_semantics(ctx, conn); + if (!case_state) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + /* + * Bug #6898 - clients using Windows opens should + * never be able to set this attribute into the + * VFS. + */ + file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS; + } + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ @@ -1002,6 +1043,8 @@ static void call_nt_transact_create(connection_struct *conn, &info, /* pinfo */ &sbuf); /* psbuf */ + TALLOC_FREE(case_state); + if(!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { /* We have re-scheduled this call, no error. */ diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 16cad8a..ab3bf1e 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -3344,7 +3344,6 @@ NTSTATUS create_file_default(connection_struct *conn, int *pinfo, SMB_STRUCT_STAT *psbuf) { - struct case_semantics_state *case_state = NULL; SMB_STRUCT_STAT sbuf; int info = FILE_WAS_OPENED; files_struct *fsp = NULL; @@ -3443,14 +3442,6 @@ NTSTATUS create_file_default(connection_struct *conn, } } - /* - * Check if POSIX semantics are wanted. - */ - - if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) { - case_state = set_posix_case_semantics(talloc_tos(), conn); - } - if (create_file_flags & CFF_DOS_PATH) { char *converted_fname; @@ -3473,8 +3464,6 @@ NTSTATUS create_file_default(connection_struct *conn, } - TALLOC_FREE(case_state); - /* All file access must go through check_name() */ status = check_name(conn, fname); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index bf3808e..8738f0f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -6328,6 +6328,7 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, uint16 info_level_return = 0; int info; char *pdata = *ppdata; + struct case_semantics_state *case_state = NULL; if (total_data < 18) { return NT_STATUS_INVALID_PARAMETER; @@ -6346,6 +6347,11 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n", fname, (unsigned int)unixmode )); + case_state = set_posix_case_semantics(talloc_tos(), conn); + if (!case_state) { + return NT_STATUS_NO_MEMORY; + } + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ @@ -6365,6 +6371,8 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, &info, /* pinfo */ psbuf); /* psbuf */ + TALLOC_FREE(case_state); + if (NT_STATUS_IS_OK(status)) { close_file(req, fsp, NORMAL_CLOSE); } @@ -6438,6 +6446,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn, int oplock_request = 0; int info = 0; uint16 info_level_return = 0; + struct case_semantics_state *case_state = NULL; if (total_data < 18) { return NT_STATUS_INVALID_PARAMETER; @@ -6522,6 +6531,11 @@ static NTSTATUS smb_posix_open(connection_struct *conn, (unsigned int)wire_open_mode, (unsigned int)unixmode )); + case_state = set_posix_case_semantics(talloc_tos(), conn); + if (!case_state) { + return NT_STATUS_NO_MEMORY; + } + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ @@ -6542,6 +6556,8 @@ static NTSTATUS smb_posix_open(connection_struct *conn, &info, /* pinfo */ psbuf); /* psbuf */ + TALLOC_FREE(case_state); + if (!NT_STATUS_IS_OK(status)) { return status; } -- 1.5.4.3