[SCM] Samba Shared Repository - branch v3-6-test updated

Karolin Seeger kseeger at samba.org
Fri Sep 6 02:49:44 MDT 2013


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 <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>
    (cherry picked from commit 1b1935b876a14154ef74e447bf53eb7cd0a5dde9)

commit a63ca3ed840ca4ab19b4b4bd9238b663228ac2a6
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>
    (cherry picked from commit 5634f240fd4273cb7327111140ccbea0fd41e3fc)

commit c8e72447345bb5b737e8383cba069098f387de0a
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>
    (cherry picked from commit b37edda32930fec372d6467d442f67532c3fbd33)

commit f5dfa2ac931d52b4517f4e5e07cf9730e6939967
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>
    (cherry picked from commit 40f60024ca19e33cbbe9825b42692f386a8f1dd9)

commit 9818b31167531f41cbf08fccf89d60ca128c3d4d
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>
    (cherry picked from commit 91939614760837b2ac2c6bb8b5daac108a4f4670)

commit a3d041438f2f0fde9644ec27b89f19ded3146f50
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>
    (cherry picked from commit ac41df91a5a425633fc716ca02187e753879d795)

commit d0f6c38f9638173b34e1a174b8811df83e045f5c
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>
    (cherry picked from commit 53123996033594f68a3fc9037474aada3aef0750)

commit 5efd0ca590670a142631db1c2133450a1020ba60
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Aug 26 08:36:14 2013 +0000

    smbd: Use #defines in smb2_getinfo_send
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: David Disseldorp <ddiss at samba.org>
    
    Autobuild-User(master): David Disseldorp <ddiss at 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.wuerthner at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <Volker.Lendecke at SerNet.DE>
    (cherry picked from commit 270d29a743a030653037cb176f3764bec3c79b6c)

commit 84eabf7b012fba624e900f2cc0294f2f1c598a46
Author: Ralph Wuerthner <ralph.wuerthner at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <Volker.Lendecke at SerNet.DE>
    (cherry picked from commit ec46f6b91941e38dd92f8e0fb0f278592e3157b6)

commit a410c51fca3644ebf7a32512dc1075a23bfc8d38
Author: Ralph Wuerthner <ralph.wuerthner at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <Volker.Lendecke at SerNet.DE>
    (cherry picked from commit 616777f029e462f53c5118d79de8c6405a5fb7c1)

commit 331a0e8e85727724466d7a795435b8eca36b3e17
Author: Ralph Wuerthner <ralph.wuerthner at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <Volker.Lendecke at SerNet.DE>
    (cherry picked from commit a91d2b05bab329a8a9772c2c79a3b1e02933182e)

commit f351fbe1fc9236ddbf52afecf872cdf7e53cae85
Author: Ralph Wuerthner <ralph.wuerthner at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <Volker.Lendecke at 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


More information about the samba-cvs mailing list