The branch, master has been updated
       via  6e3650e torture: Add buffercheck tests
       via  1b1935b smbd: Correctly return INFO_LENGTH_MISMATCH for smb1
       via  5634f24 smbd: Fix error return for STREAM_INFO
       via  b37edda smbd: Revert a93f9c3
       via  40f6002 smbd: Correctly return BUFFER_OVERFLOW in smb2_getinfo
       via  9193961 smbd: Correctly return INFO_LENGTH_MISMATCH in smb2_getinfo
       via  ac41df9 smbd: qfsinfo has fixed/variable buffers
       via  5312399 smbd: qfilepathinfo has fixed/variable buffers
       via  e1843cd torture3: add clipathinfo-bufsize
       via  1cae59c dbwrap_ctdb: Treat empty records as non-existing
      from  91186fc s3: fix missing braces in nfs4_acls.c

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 6e3650edd3cbdd9f29be4e8fa9ec9cd307f178e7
Author: Volker Lendecke <[email protected]>
Date:   Tue Aug 27 09:41:13 2013 +0000

    torture: Add buffercheck tests
    
    Make sure we get the smb2 infolevel fixed portions right
    
    I could not find correct #defines for the infolevels
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    
    Autobuild-User(master): Jeremy Allison <[email protected]>
    Autobuild-Date(master): Thu Aug 29 01:27:11 CEST 2013 on sn-devel-104

commit 1b1935b876a14154ef74e447bf53eb7cd0a5dde9
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 5634f240fd4273cb7327111140ccbea0fd41e3fc
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit b37edda32930fec372d6467d442f67532c3fbd33
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 40f60024ca19e33cbbe9825b42692f386a8f1dd9
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 91939614760837b2ac2c6bb8b5daac108a4f4670
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit ac41df91a5a425633fc716ca02187e753879d795
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 53123996033594f68a3fc9037474aada3aef0750
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit e1843cd33274a3d790a4214b3d50a584d3d3fc95
Author: Volker Lendecke <[email protected]>
Date:   Fri Aug 23 13:57:03 2013 +0000

    torture3: add clipathinfo-bufsize
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 1cae59ce112ccb51b45357a52b902f80fce1eef1
Author: Volker Lendecke <[email protected]>
Date:   Wed Aug 28 11:34:08 2013 +0000

    dbwrap_ctdb: Treat empty records as non-existing
    
    This is a patch implementing the workaround Christian mentioned in
    https://bugzilla.samba.org/show_bug.cgi?id=10008#c5
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10008
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Christian Ambach <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 selftest/knownfail                |    3 +
 source3/lib/ctdbd_conn.c          |    8 ++
 source3/lib/dbwrap/dbwrap_ctdb.c  |   10 ++
 source3/smbd/globals.h            |    2 +
 source3/smbd/smb2_getinfo.c       |   31 ++++-
 source3/smbd/trans2.c             |   40 ++++++
 source3/torture/proto.h           |    1 +
 source3/torture/test_buffersize.c |   56 +++++++++
 source3/torture/torture.c         |    1 +
 source3/wscript_build             |    1 +
 source4/torture/smb2/getinfo.c    |  244 ++++++++++++++++++++++++++++++++++---
 11 files changed, 374 insertions(+), 23 deletions(-)
 create mode 100644 source3/torture/test_buffersize.c


Changeset truncated at 500 lines:

diff --git a/selftest/knownfail b/selftest/knownfail
index dd536df..6fe7ce5 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -171,6 +171,9 @@
 ^samba4.smb2.oplock.batch20\(.*\)$ # samba 4 oplocks are a mess
 ^samba4.smb2.oplock.stream1 # samba 4 oplocks are a mess
 ^samba4.smb2.getinfo.complex # streams on directories does not work
+^samba4.smb2.getinfo.qfs_buffercheck # S4 does not do the 
INFO_LENGTH_MISMATCH/BUFFER_OVERFLOW thingy
+^samba4.smb2.getinfo.qfile_buffercheck # S4 does not do the 
INFO_LENGTH_MISMATCH/BUFFER_OVERFLOW thingy
+^samba4.smb2.getinfo.qsec_buffercheck # S4 does not do the BUFFER_TOO_SMALL 
thingy
 ^samba4.ntvfs.cifs.krb5.base.createx_access.createx_access\(.*\)$
 ^samba4.rpc.lsa.forest.trust #Not fully provided by Samba4
 ^samba4.blackbox.kinit\(.*\).kinit with user password for expired 
password\(.*\) # We need to work out why this fails only during the pw change
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index 4f5dce0..f960541 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -1474,6 +1474,14 @@ NTSTATUS ctdbd_parse(struct ctdbd_connection *conn, 
uint32_t db_id,
                goto fail;
        }
 
+       if (reply->datalen == 0) {
+               /*
+                * Treat an empty record as non-existing
+                */
+               status = NT_STATUS_NOT_FOUND;
+               goto fail;
+       }
+
        parser(key, make_tdb_data(&reply->data[0], reply->datalen),
               private_data);
 
diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c
index f90e7b8..5a473f9 100644
--- a/source3/lib/dbwrap/dbwrap_ctdb.c
+++ b/source3/lib/dbwrap/dbwrap_ctdb.c
@@ -103,6 +103,16 @@ static int db_ctdb_ltdb_parser(TDB_DATA key, TDB_DATA data,
        if (data.dsize < sizeof(struct ctdb_ltdb_header)) {
                return -1;
        }
+       if (data.dsize == sizeof(struct ctdb_ltdb_header)) {
+               /*
+                * Making this a separate case that needs fixing
+                * separately. This is an empty record. ctdbd does not
+                * distinguish between empty and deleted records. Samba right
+                * now can live without empty records, so lets treat zero-size
+                * (i.e. deleted) records as non-existing.
+                */
+               return -1;
+       }
        state->parser(
                key, (struct ctdb_ltdb_header *)data.dptr,
                make_tdb_data(data.dptr + sizeof(struct ctdb_ltdb_header),
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index d618aea..9ea5e25 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -138,6 +138,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);
 
@@ -155,6 +156,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 4420f94..449aeb3 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -293,6 +293,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);
 
@@ -380,6 +381,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)) {
@@ -390,6 +392,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,
@@ -398,6 +406,11 @@ 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;
@@ -408,6 +421,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX 
*mem_ctx,
                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;
@@ -416,6 +430,7 @@ 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);
@@ -430,6 +445,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,
@@ -438,6 +459,11 @@ 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;
@@ -504,11 +530,6 @@ static struct tevent_req 
*smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-       if (state->out_output_buffer.length > in_output_buffer_length) {
-               tevent_req_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH);
-               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 b6cb3cc..aaf0e62 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -3068,6 +3068,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)
@@ -3124,6 +3125,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:
                {
@@ -3222,6 +3225,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", 
(unsigned int)st.st_ex_dev, (u
                                data_len = max_data_bytes;
                                status = STATUS_BUFFER_OVERFLOW;
                        }
+                       *fixed_portion = 16;
                        break;
 
                case SMB_QUERY_FS_LABEL_INFO:
@@ -3258,6 +3262,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", 
(unsigned int)st.st_ex_dev, (u
                                data_len = max_data_bytes;
                                status = STATUS_BUFFER_OVERFLOW;
                        }
+                       *fixed_portion = 24;
                        break;
 
                case SMB_QUERY_FS_SIZE_INFO:
@@ -3290,6 +3295,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;
                }
 
@@ -3323,6 +3329,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;
                }
 
@@ -3337,6 +3344,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;
                }
 
@@ -3645,6 +3653,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) {
@@ -3670,6 +3679,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)) {
@@ -4233,6 +4243,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;
@@ -4388,6 +4402,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)
 {
@@ -4528,6 +4543,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"));
@@ -4674,6 +4691,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:
@@ -4687,6 +4705,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:
@@ -4696,6 +4715,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                            estimate_ea_size(conn, fsp, smb_fname);
                        DEBUG(10,("smbd_do_qfilepathinfo: 
SMB_FILE_EA_INFORMATION\n"));
                        data_size = 4;
+                       *fixed_portion = 4;
                        SIVAL(pdata,0,ea_size);
                        break;
                }
@@ -4717,6 +4737,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                                          STR_UNICODE);
                        data_size = 4 + len;
                        SIVAL(pdata,0,len);
+                       *fixed_portion = 8;
                        break;
                }
 
@@ -4780,6 +4801,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;
                }
 
@@ -4817,6 +4839,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:
@@ -4824,12 +4847,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:
@@ -4847,24 +4872,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;
 
                /*
@@ -4909,6 +4938,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
 
                        TALLOC_FREE(streams);
 
+                       *fixed_portion = 32;
+
                        break;
                }
                case SMB_QUERY_COMPRESSION_INFO:
@@ -4918,6 +4949,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:
@@ -4931,6 +4963,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:
@@ -4938,6 +4971,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                        SIVAL(pdata,0,mode);
                        SIVAL(pdata,4,0);
                        data_size = 8;
+                       *fixed_portion = 8;
                        break;
 
                /*
@@ -5211,6 +5245,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) {
@@ -5570,11 +5605,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, NT_STATUS_OK, params, param_size, 
*ppdata, data_size,
                            max_data_bytes);
diff --git a/source3/torture/proto.h b/source3/torture/proto.h
index 4f4c9e2..f6453fd 100644
--- a/source3/torture/proto.h
+++ b/source3/torture/proto.h
@@ -111,5 +111,6 @@ bool run_notify_bench3(int dummy);
 bool run_dbwrap_watch1(int dummy);
 bool run_idmap_tdb_common_test(int dummy);
 bool run_local_dbwrap_ctdb(int dummy);
+bool run_qpathinfo_bufsize(int dummy);
 
 #endif /* __TORTURE_H__ */
diff --git a/source3/torture/test_buffersize.c 
b/source3/torture/test_buffersize.c
new file mode 100644
index 0000000..6e86374
--- /dev/null
+++ b/source3/torture/test_buffersize.c
@@ -0,0 +1,56 @@
+/*
+   Unix SMB/CIFS implementation.
+   Test buffer sizes in cli_qpathinfo
+   Copyright (C) Volker Lendecke 2012
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/proto.h"
+#include "libsmb/libsmb.h"
+#include "libcli/security/dom_sid.h"
+#include "libcli/security/secdesc.h"
+#include "libcli/security/security.h"
+#include "trans2.h"
+#include "source3/libsmb/clirap.h"
+
+bool run_qpathinfo_bufsize(int dummy)
+{
+       struct cli_state *cli = NULL;
+       NTSTATUS status, status2;
+       bool ret = false;
+       int i;
+
+       printf("Starting qpathinfo_bufsize\n");
+
+       if (!torture_open_connection(&cli, 0)) {
+               printf("torture_open_connection failed\n");
+               goto fail;
+       }
+
+       for (i=0; i<500; i++) {
+               uint8_t *rdata;
+               uint32_t num_rdata;
+               cli_qpathinfo(cli, cli, "\\", SMB_FILE_ALL_INFORMATION,
+                             0, i, &rdata, &num_rdata);
+       }
+
+       ret = true;
+fail:
+       if (cli != NULL) {
+               torture_close_connection(cli);
+       }
+       return ret;
+}


-- 
Samba Shared Repository

Reply via email to