summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/smbd/trans2.c31
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;
}