[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Wed Aug 28 17:28:03 MDT 2013


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 <vl at samba.org>
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 <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Thu Aug 29 01:27:11 CEST 2013 on sn-devel-104

commit 1b1935b876a14154ef74e447bf53eb7cd0a5dde9
Author: Volker Lendecke <vl at 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 <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5634f240fd4273cb7327111140ccbea0fd41e3fc
Author: Volker Lendecke <vl at 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 <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b37edda32930fec372d6467d442f67532c3fbd33
Author: Volker Lendecke <vl at 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 <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 40f60024ca19e33cbbe9825b42692f386a8f1dd9
Author: Volker Lendecke <vl at 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 <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 91939614760837b2ac2c6bb8b5daac108a4f4670
Author: Volker Lendecke <vl at 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 <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit ac41df91a5a425633fc716ca02187e753879d795
Author: Volker Lendecke <vl at 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 <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 53123996033594f68a3fc9037474aada3aef0750
Author: Volker Lendecke <vl at 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 <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit e1843cd33274a3d790a4214b3d50a584d3d3fc95
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 23 13:57:03 2013 +0000

    torture3: add clipathinfo-bufsize
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 1cae59ce112ccb51b45357a52b902f80fce1eef1
Author: Volker Lendecke <vl at samba.org>
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 <vl at samba.org>
    Reviewed-by: Christian Ambach <ambi at samba.org>

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

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


More information about the samba-cvs mailing list