diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/trans2.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 2892e26c77..5f50b64f4f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -5538,7 +5538,8 @@ static NTSTATUS smb_set_file_size(connection_struct *conn, files_struct *fsp, const struct smb_filename *smb_fname, const SMB_STRUCT_STAT *psbuf, - SMB_OFF_T size) + SMB_OFF_T size, + bool fail_after_createfile) { NTSTATUS status = NT_STATUS_OK; struct smb_filename *smb_fname_tmp = NULL; @@ -5598,6 +5599,12 @@ static NTSTATUS smb_set_file_size(connection_struct *conn, return status; } + /* See RAW-SFILEINFO-END-OF-FILE */ + if (fail_after_createfile) { + close_file(req, new_fsp,NORMAL_CLOSE); + return NT_STATUS_INVALID_LEVEL; + } + if (vfs_set_filelen(new_fsp, size) == -1) { status = map_nt_error_from_unix(errno); close_file(req, new_fsp,NORMAL_CLOSE); @@ -6474,7 +6481,8 @@ static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn, const char *pdata, int total_data, files_struct *fsp, - const struct smb_filename *smb_fname) + const struct smb_filename *smb_fname, + bool fail_after_createfile) { SMB_OFF_T size; @@ -6499,7 +6507,8 @@ static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn, fsp, smb_fname, &smb_fname->st, - size); + size, + fail_after_createfile); } /**************************************************************************** @@ -6785,7 +6794,8 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn, fsp, smb_fname, &sbuf, - size); + size, + false); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -7381,11 +7391,22 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, case SMB_FILE_END_OF_FILE_INFORMATION: case SMB_SET_FILE_END_OF_FILE_INFO: { + /* + * XP/Win7 both fail after the createfile with + * SMB_SET_FILE_END_OF_FILE_INFO but not + * SMB_FILE_END_OF_FILE_INFORMATION (pass-through). + * The level is known here, so pass it down + * appropriately. + */ + bool should_fail = + (info_level == SMB_SET_FILE_END_OF_FILE_INFO); + status = smb_set_file_end_of_file_info(conn, req, pdata, total_data, fsp, - smb_fname); + smb_fname, + should_fail); break; } |