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

Reply via email to