The branch, v3-6-test has been updated via 41a7d66 smbd: Correctly return INFO_LENGTH_MISMATCH for smb1 via a63ca3e smbd: Fix error return for STREAM_INFO via c8e7244 smbd: Revert a93f9c3 via f5dfa2a smbd: Correctly return BUFFER_OVERFLOW in smb2_getinfo via 9818b31 smbd: Correctly return INFO_LENGTH_MISMATCH in smb2_getinfo via a3d0414 smbd: qfsinfo has fixed/variable buffers via d0f6c38 smbd: qfilepathinfo has fixed/variable buffers via 5efd0ca smbd: Use #defines in smb2_getinfo_send via 65d4f0b s3:smbd: allow info class SMB_QUERY_FS_ATTRIBUTE_INFO to return partial data via 84eabf7 s3:smbd: allow info class SMB_QUERY_FS_VOLUME_INFO to return partial data via a410c51 s3:smbd: allow status code in smbd_do_qfsinfo() to be set by information class handler via 331a0e8 s3:smbd: allow GetInfo responses with STATUS_BUFFER_OVERFLOW to return partial, but valid data via f351fbe s3:smbd: return NT_STATUS_INFO_LENGTH_MISMATCH for GetInfo in case output_buffer_length is too small from 0150086 smbd: Simplify dropbox special case in unix_convert
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test - Log ----------------------------------------------------------------- commit 41a7d66a399c3e1ad999dce5d14570d60c4d53d2 Author: Volker Lendecke <v...@samba.org> Date: Tue Aug 27 09:40:19 2013 +0000 smbd: Correctly return INFO_LENGTH_MISMATCH for smb1 This is required if the client offered less buffer than the fixed portion of the info level data requires Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 1b1935b876a14154ef74e447bf53eb7cd0a5dde9) commit a63ca3ed840ca4ab19b4b4bd9238b663228ac2a6 Author: Volker Lendecke <v...@samba.org> Date: Tue Aug 27 09:39:17 2013 +0000 smbd: Fix error return for STREAM_INFO The stream_info marshalling follows its own rules. This needs unifying eventually... Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 5634f240fd4273cb7327111140ccbea0fd41e3fc) commit c8e72447345bb5b737e8383cba069098f387de0a Author: Volker Lendecke <v...@samba.org> Date: Tue Aug 27 09:38:29 2013 +0000 smbd: Revert a93f9c3 This was too broad and has been replaced by finer-grained error checks Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit b37edda32930fec372d6467d442f67532c3fbd33) commit f5dfa2ac931d52b4517f4e5e07cf9730e6939967 Author: Volker Lendecke <v...@samba.org> Date: Tue Aug 27 09:37:34 2013 +0000 smbd: Correctly return BUFFER_OVERFLOW in smb2_getinfo Also, don't overflow the client buffer Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 40f60024ca19e33cbbe9825b42692f386a8f1dd9) commit 9818b31167531f41cbf08fccf89d60ca128c3d4d Author: Volker Lendecke <v...@samba.org> Date: Tue Aug 27 09:36:03 2013 +0000 smbd: Correctly return INFO_LENGTH_MISMATCH in smb2_getinfo We have to return this error if the client offered less than the fixed portion of the infolevel data requires Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 91939614760837b2ac2c6bb8b5daac108a4f4670) commit a3d041438f2f0fde9644ec27b89f19ded3146f50 Author: Volker Lendecke <v...@samba.org> Date: Tue Aug 27 09:06:27 2013 +0000 smbd: qfsinfo has fixed/variable buffers The error message will have to change depending whether the buffer is too small for the fixed or variable buffers Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit ac41df91a5a425633fc716ca02187e753879d795) commit d0f6c38f9638173b34e1a174b8811df83e045f5c Author: Volker Lendecke <v...@samba.org> Date: Tue Aug 27 09:06:27 2013 +0000 smbd: qfilepathinfo has fixed/variable buffers The error message will have to change depending whether the buffer is too small for the fixed or variable buffers Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 53123996033594f68a3fc9037474aada3aef0750) commit 5efd0ca590670a142631db1c2133450a1020ba60 Author: Volker Lendecke <v...@samba.org> Date: Mon Aug 26 08:36:14 2013 +0000 smbd: Use #defines in smb2_getinfo_send Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: David Disseldorp <dd...@samba.org> Autobuild-User(master): David Disseldorp <dd...@samba.org> Autobuild-Date(master): Tue Aug 27 15:08:08 CEST 2013 on sn-devel-104 (cherry picked from commit 323cccd35d06c7327c19dc5cb891043507624d7d) commit 65d4f0b5125ebea659d0277916bb74db2c3b9cc0 Author: Ralph Wuerthner <ralph.wuerth...@de.ibm.com> Date: Wed Jul 10 16:43:39 2013 +0200 s3:smbd: allow info class SMB_QUERY_FS_ATTRIBUTE_INFO to return partial data Reviewed-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <volker.lende...@sernet.de> (cherry picked from commit 270d29a743a030653037cb176f3764bec3c79b6c) commit 84eabf7b012fba624e900f2cc0294f2f1c598a46 Author: Ralph Wuerthner <ralph.wuerth...@de.ibm.com> Date: Wed Jul 10 15:52:06 2013 +0200 s3:smbd: allow info class SMB_QUERY_FS_VOLUME_INFO to return partial data Reviewed-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <volker.lende...@sernet.de> (cherry picked from commit ec46f6b91941e38dd92f8e0fb0f278592e3157b6) commit a410c51fca3644ebf7a32512dc1075a23bfc8d38 Author: Ralph Wuerthner <ralph.wuerth...@de.ibm.com> Date: Fri Jul 5 11:32:27 2013 +0200 s3:smbd: allow status code in smbd_do_qfsinfo() to be set by information class handler Reviewed-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <volker.lende...@sernet.de> (cherry picked from commit 616777f029e462f53c5118d79de8c6405a5fb7c1) commit 331a0e8e85727724466d7a795435b8eca36b3e17 Author: Ralph Wuerthner <ralph.wuerth...@de.ibm.com> Date: Fri Jul 5 11:03:16 2013 +0200 s3:smbd: allow GetInfo responses with STATUS_BUFFER_OVERFLOW to return partial, but valid data Reviewed-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <volker.lende...@sernet.de> (cherry picked from commit a91d2b05bab329a8a9772c2c79a3b1e02933182e) commit f351fbe1fc9236ddbf52afecf872cdf7e53cae85 Author: Ralph Wuerthner <ralph.wuerth...@de.ibm.com> Date: Wed Jul 10 08:59:58 2013 +0200 s3:smbd: return NT_STATUS_INFO_LENGTH_MISMATCH for GetInfo in case output_buffer_length is too small Reviewed-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <volker.lende...@sernet.de> (cherry picked from commit a93f9c3d33e442c84d0c9da7eb5d25ca4b54fc33) ----------------------------------------------------------------------- Summary of changes: source3/smbd/globals.h | 2 + source3/smbd/smb2_getinfo.c | 45 ++++++++++++++++++++++++++++++---- source3/smbd/trans2.c | 56 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 96 insertions(+), 7 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index ce5b18d..8cec74c 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -162,6 +162,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, char *lock_data, uint16_t flags2, unsigned int max_data_bytes, + size_t *fixed_portion, char **ppdata, unsigned int *pdata_size); @@ -179,6 +180,7 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, uint16_t info_level, uint16_t flags2, unsigned int max_data_bytes, + size_t *fixed_portion, struct smb_filename *smb_fname, char **ppdata, int *ret_data_len); diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 55071e8..9ad2847 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -148,7 +148,10 @@ static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq) return; } - if (!NT_STATUS_IS_OK(call_status)) { + /* some GetInfo responses set STATUS_BUFFER_OVERFLOW and return partial, + but valid data */ + if (!(NT_STATUS_IS_OK(call_status) || + NT_STATUS_EQUAL(call_status, STATUS_BUFFER_OVERFLOW))) { /* Return a specific error with data. */ error = smbd_smb2_request_error_ex(req, call_status, @@ -185,7 +188,7 @@ static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq) outdyn = out_output_buffer; - error = smbd_smb2_request_done(req, outbody, &outdyn); + error = smbd_smb2_request_done_ex(req, call_status, outbody, &outdyn, __location__); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(req->sconn, nt_errstr(error)); @@ -270,7 +273,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, } switch (in_info_type) { - case 0x01:/* SMB2_GETINFO_FILE */ + case SMB2_GETINFO_FILE: { uint16_t file_info_level; char *data = NULL; @@ -281,6 +284,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, struct ea_list *ea_list = NULL; int lock_data_count = 0; char *lock_data = NULL; + size_t fixed_portion; ZERO_STRUCT(write_time_ts); @@ -368,6 +372,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, lock_data, STR_UNICODE, in_output_buffer_length, + &fixed_portion, &data, &data_size); if (!NT_STATUS_IS_OK(status)) { @@ -378,6 +383,12 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, tevent_req_nterror(req, status); return tevent_req_post(req, ev); } + if (in_output_buffer_length < fixed_portion) { + SAFE_FREE(data); + tevent_req_nterror( + req, NT_STATUS_INFO_LENGTH_MISMATCH); + return tevent_req_post(req, ev); + } if (data_size > 0) { state->out_output_buffer = data_blob_talloc(state, data, @@ -386,16 +397,22 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(state->out_output_buffer.data, req)) { return tevent_req_post(req, ev); } + if (data_size > in_output_buffer_length) { + state->out_output_buffer.length = + in_output_buffer_length; + status = STATUS_BUFFER_OVERFLOW; + } } SAFE_FREE(data); break; } - case 0x02:/* SMB2_GETINFO_FS */ + case SMB2_GETINFO_FS: { uint16_t file_info_level; char *data = NULL; int data_size = 0; + size_t fixed_portion; /* the levels directly map to the passthru levels */ file_info_level = in_file_info_class + 1000; @@ -404,10 +421,14 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, file_info_level, STR_UNICODE, in_output_buffer_length, + &fixed_portion, fsp->fsp_name, &data, &data_size); - if (!NT_STATUS_IS_OK(status)) { + /* some responses set STATUS_BUFFER_OVERFLOW and return + partial, but valid data */ + if (!(NT_STATUS_IS_OK(status) || + NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW))) { SAFE_FREE(data); if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) { status = NT_STATUS_INVALID_INFO_CLASS; @@ -415,6 +436,12 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, tevent_req_nterror(req, status); return tevent_req_post(req, ev); } + if (in_output_buffer_length < fixed_portion) { + SAFE_FREE(data); + tevent_req_nterror( + req, NT_STATUS_INFO_LENGTH_MISMATCH); + return tevent_req_post(req, ev); + } if (data_size > 0) { state->out_output_buffer = data_blob_talloc(state, data, @@ -423,12 +450,17 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(state->out_output_buffer.data, req)) { return tevent_req_post(req, ev); } + if (data_size > in_output_buffer_length) { + state->out_output_buffer.length = + in_output_buffer_length; + status = STATUS_BUFFER_OVERFLOW; + } } SAFE_FREE(data); break; } - case 0x03:/* SMB2_GETINFO_SEC */ + case SMB2_GETINFO_SECURITY: { uint8_t *p_marshalled_sd = NULL; size_t sd_size = 0; @@ -485,6 +517,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + state->status = status; tevent_req_done(req); return tevent_req_post(req, ev); } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index ccce7b8..26b6523 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2971,6 +2971,7 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, uint16_t info_level, uint16_t flags2, unsigned int max_data_bytes, + size_t *fixed_portion, struct smb_filename *fname, char **ppdata, int *ret_data_len) @@ -2984,6 +2985,7 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, uint32 additional_flags = 0; struct smb_filename smb_fname; SMB_STRUCT_STAT st; + NTSTATUS status = NT_STATUS_OK; if (fname == NULL || fname->base_name == NULL) { filename = "."; @@ -3022,6 +3024,8 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1; + *fixed_portion = 0; + switch (info_level) { case SMB_INFO_ALLOCATION: { @@ -3114,6 +3118,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u STR_UNICODE); SIVAL(pdata,8,len); data_len = 12 + len; + if (max_data_bytes >= 16 && data_len > max_data_bytes) { + /* the client only requested a portion of the + file system name */ + data_len = max_data_bytes; + status = STATUS_BUFFER_OVERFLOW; + } + *fixed_portion = 16; break; case SMB_QUERY_FS_LABEL_INFO: @@ -3143,6 +3154,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", (int)strlen(vname),vname, lp_servicename(snum))); + if (max_data_bytes >= 24 && data_len > max_data_bytes) { + /* the client only requested a portion of the + volume label */ + data_len = max_data_bytes; + status = STATUS_BUFFER_OVERFLOW; + } + break; case SMB_QUERY_FS_SIZE_INFO: @@ -3175,6 +3193,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned SBIG_UINT(pdata,8,dfree); SIVAL(pdata,16,sectors_per_unit); SIVAL(pdata,20,bytes_per_sector); + *fixed_portion = 24; break; } @@ -3208,6 +3227,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */ SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */ SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */ + *fixed_portion = 32; break; } @@ -3222,6 +3242,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned data_len = 8; SIVAL(pdata,0,FILE_DEVICE_DISK); /* dev type */ SIVAL(pdata,4,characteristics); + *fixed_portion = 8; break; } @@ -3396,6 +3417,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn)))); return NT_STATUS_DOS(ERRSRV, ERRerror); } + *fixed_portion = 24; break; } @@ -3526,7 +3548,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned } *ret_data_len = data_len; - return NT_STATUS_OK; + return status; } /**************************************************************************** @@ -3542,6 +3564,7 @@ static void call_trans2qfsinfo(connection_struct *conn, char *params = *pparams; uint16_t info_level; int data_len = 0; + size_t fixed_portion; NTSTATUS status; if (total_params < 2) { @@ -3568,6 +3591,7 @@ static void call_trans2qfsinfo(connection_struct *conn, info_level, req->flags2, max_data_bytes, + &fixed_portion, NULL, ppdata, &data_len); if (!NT_STATUS_IS_OK(status)) { @@ -4121,6 +4145,10 @@ static NTSTATUS marshall_stream_info(unsigned int num_streams, unsigned int i; unsigned int ofs = 0; + if (max_data_bytes < 32) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + for (i = 0; i < num_streams; i++) { unsigned int next_offset; size_t namelen; @@ -4272,6 +4300,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, char *lock_data, uint16_t flags2, unsigned int max_data_bytes, + size_t *fixed_portion, char **ppdata, unsigned int *pdata_size) { @@ -4407,6 +4436,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, BasicFileInformationTest. -tpot */ file_index = get_FileIndex(conn, psbuf); + *fixed_portion = 0; + switch (info_level) { case SMB_INFO_STANDARD: DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n")); @@ -4544,6 +4575,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, DEBUG(5,("write: %s ", ctime(&mtime))); DEBUG(5,("change: %s ", ctime(&c_time))); DEBUG(5,("mode: %x\n", mode)); + *fixed_portion = data_size; break; case SMB_FILE_STANDARD_INFORMATION: @@ -4557,6 +4589,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SCVAL(pdata,20,delete_pending?1:0); SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0); SSVAL(pdata,22,0); /* Padding. */ + *fixed_portion = 24; break; case SMB_FILE_EA_INFORMATION: @@ -4566,6 +4599,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, estimate_ea_size(conn, fsp, smb_fname->base_name); DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); data_size = 4; + *fixed_portion = 4; SIVAL(pdata,0,ea_size); break; } @@ -4587,6 +4621,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, STR_UNICODE); data_size = 4 + len; SIVAL(pdata,0,len); + *fixed_portion = 8; break; } @@ -4650,6 +4685,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SIVAL(pdata,0,len); pdata += 4 + len; data_size = PTR_DIFF(pdata,(*ppdata)); + *fixed_portion = 10; break; } @@ -4687,6 +4723,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SIVAL(pdata,0,len); pdata += 4 + len; data_size = PTR_DIFF(pdata,(*ppdata)); + *fixed_portion = 104; break; } case SMB_FILE_INTERNAL_INFORMATION: @@ -4694,12 +4731,14 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); SBVAL(pdata, 0, file_index); data_size = 8; + *fixed_portion = 8; break; case SMB_FILE_ACCESS_INFORMATION: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n")); SIVAL(pdata, 0, access_mask); data_size = 4; + *fixed_portion = 4; break; case SMB_FILE_NAME_INFORMATION: @@ -4717,24 +4756,28 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n")); data_size = 1; SCVAL(pdata,0,delete_pending); + *fixed_portion = 1; break; case SMB_FILE_POSITION_INFORMATION: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n")); data_size = 8; SOFF_T(pdata,0,pos); + *fixed_portion = 8; break; case SMB_FILE_MODE_INFORMATION: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n")); SIVAL(pdata,0,mode); data_size = 4; + *fixed_portion = 4; break; case SMB_FILE_ALIGNMENT_INFORMATION: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n")); SIVAL(pdata,0,0); /* No alignment needed. */ data_size = 4; + *fixed_portion = 4; break; /* @@ -4779,6 +4822,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, TALLOC_FREE(streams); + *fixed_portion = 32; + break; } case SMB_QUERY_COMPRESSION_INFO: @@ -4788,6 +4833,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SIVAL(pdata,8,0); /* ??? */ SIVAL(pdata,12,0); /* ??? */ data_size = 16; + *fixed_portion = 16; break; case SMB_FILE_NETWORK_OPEN_INFORMATION: @@ -4801,6 +4847,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SIVAL(pdata,48,mode); SIVAL(pdata,52,0); /* ??? */ data_size = 56; + *fixed_portion = 56; break; case SMB_FILE_ATTRIBUTE_TAG_INFORMATION: @@ -4808,6 +4855,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SIVAL(pdata,0,mode); SIVAL(pdata,4,0); data_size = 8; + *fixed_portion = 8; break; /* @@ -5077,6 +5125,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, struct ea_list *ea_list = NULL; int lock_data_count = 0; char *lock_data = NULL; + size_t fixed_portion; NTSTATUS status = NT_STATUS_OK; if (!params) { @@ -5438,11 +5487,16 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd ea_list, lock_data_count, lock_data, req->flags2, max_data_bytes, + &fixed_portion, ppdata, &data_size); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); return; } + if (fixed_portion > max_data_bytes) { + reply_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH); + return; + } send_trans2_replies(conn, req, params, param_size, *ppdata, data_size, max_data_bytes); -- Samba Shared Repository