[SCM] Samba Shared Repository - branch master updated

David Disseldorp ddiss at samba.org
Tue Apr 2 13:55:02 MDT 2013


The branch, master has been updated
       via  b986a3a Ensure EA value is allocated on the right context.
       via  9b94de1 Final fix for bug #9130 - Certain xattrs cause Windows error 0x800700FF
       via  43becd6 Ensure we don't return uninitialized memory in the pad bytes.
       via  7bee3ef Add a test to show that zero-length EA's are never returned over SMB2.
       via  b96bc9fa Fix bug #9130 - Certain xattrs cause Windows error 0x800700FF
       via  875bedd Fix bug #9130 - Certain xattrs cause Windows error 0x800700FF
       via  15fa043 Change estimate_ea_size() to correctly estimate the EA size over SMB2.
       via  d9e7c82 Modify fill_ea_chained_buffer() to be able to do size calculation only, no marshalling.
       via  1e8bcce Ensure we can never return an uninitialized EA list.
      from  50e0060 Add a comment about why we are removing the INHERITED bit so people understand.

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


- Log -----------------------------------------------------------------
commit b986a3a9c988c6ec29c0e0a2f8609d5132e952f4
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 28 08:55:11 2013 -0700

    Ensure EA value is allocated on the right context.
    
    Ensure we free on error condition (tidyup, not a leak).
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: David Disseldorp <ddiss at suse.de>
    
    Autobuild-User(master): David Disseldorp <ddiss at samba.org>
    Autobuild-Date(master): Tue Apr  2 21:54:33 CEST 2013 on sn-devel-104

commit 9b94de161f30bb34c666c0cf0cc94250e6a7b863
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Mar 27 11:54:34 2013 -0700

    Final fix for bug #9130 - Certain xattrs cause Windows error 0x800700FF
    
    The spec lies when it says that NextEntryOffset is the only value
    considered when finding the next EA. We were adding 4 more extra
    pad bytes than needed (i.e. if the next entry already was on a 4
    byte boundary, then we were adding 4 additional pad bytes).
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: David Disseldorp <ddiss at suse.de>

commit 43becd6f305bd5d21d886027d38a92d4dff22d75
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Mar 26 16:46:51 2013 -0700

    Ensure we don't return uninitialized memory in the pad bytes.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: David Disseldorp <ddiss at suse.de>

commit 7bee3ef68490bb38942d717e03e203d00be32f9f
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Mar 26 13:26:49 2013 -0700

    Add a test to show that zero-length EA's are never returned over SMB2.
    
    Zero length EA's only delete an EA, never store. Proves we should
    never return zero-length EA's even if they have been set on the
    POSIX side.
    
    ntvfs server doesn't implement the FULL_EA_INFORMATION setinfo
    call, so add to selftest/knownfail.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: David Disseldorp <ddiss at suse.de>

commit b96bc9fa260c397887ba6199181f3b8bca7046a6
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Mar 26 16:38:00 2013 -0700

    Fix bug #9130 - Certain xattrs cause Windows error 0x800700FF
    
    Ensure ntvfs server never returns zero length EA's.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: David Disseldorp <ddiss at suse.de>

commit 875bedddddc51df59f85ae7bbd7db52fbfb5ffef
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Mar 26 16:37:22 2013 -0700

    Fix bug #9130 - Certain xattrs cause Windows error 0x800700FF
    
    Ensure we never return any zero-length EA's.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: David Disseldorp <ddiss at suse.de>

commit 15fa043b7d362ee197835c0a72a936684c774472
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Mar 26 15:54:31 2013 -0700

    Change estimate_ea_size() to correctly estimate the EA size over SMB2.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: David Disseldorp <ddiss at suse.de>

commit d9e7c8219fd8b3d770301a87bc1cd62b07b989ca
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Mar 26 15:46:06 2013 -0700

    Modify fill_ea_chained_buffer() to be able to do size calculation only, no marshalling.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: David Disseldorp <ddiss at suse.de>

commit 1e8bcce52f233722fad5c25f2467b86d97cadfa0
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Mar 29 10:07:20 2013 -0700

    Ensure we can never return an uninitialized EA list.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: David Disseldorp <ddiss at suse.de>

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

Summary of changes:
 selftest/knownfail                   |    1 +
 source3/smbd/trans2.c                |   70 +++++++++++++++----
 source4/ntvfs/posix/pvfs_qfileinfo.c |    6 ++
 source4/torture/smb2/setinfo.c       |  121 ++++++++++++++++++++++++++++++++++
 4 files changed, 183 insertions(+), 15 deletions(-)


Changeset truncated at 500 lines:

diff --git a/selftest/knownfail b/selftest/knownfail
index 61a0a0e..e4b4694 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -162,6 +162,7 @@
 ^samba4.blackbox.upgradeprovision.alpha13.ldapcmp_sd\(none\) # Due to something rewriting the NT ACL on DNS objects
 ^samba4.blackbox.upgradeprovision.alpha13.ldapcmp_full_sd\(none\) # Due to something rewriting the NT ACL on DNS objects
 ^samba4.blackbox.upgradeprovision.release-4-0-0.ldapcmp_sd\(none\) # Due to something rewriting the NT ACL on DNS objects
+^samba4.smb2.setinfo.setinfo # ntvfs doesn't support FULL_EA_INFORMATION set.
 ^samba3.smb2.create.gentest
 ^samba3.smb2.create.blob
 ^samba3.smb2.create.open
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index fae9e1f..5781c61 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -323,6 +323,7 @@ static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx, connection_struc
 	NTSTATUS status;
 
 	*pea_total_len = 0;
+	*ea_list = NULL;
 
 	status = get_ea_names_from_file(talloc_tos(), conn, fsp, fname,
 					&names, &num_names);
@@ -349,14 +350,24 @@ static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx, connection_struc
 			return NT_STATUS_NO_MEMORY;
 		}
 
-		status = get_ea_value(mem_ctx, conn, fsp,
+		status = get_ea_value(listp, conn, fsp,
 				      fname, names[i],
 				      &listp->ea);
 
 		if (!NT_STATUS_IS_OK(status)) {
+			TALLOC_FREE(listp);
 			return status;
 		}
 
+		if (listp->ea.value.length == 0) {
+			/*
+			 * We can never return a zero length EA.
+			 * Windows reports the EA's as corrupted.
+			 */
+			TALLOC_FREE(listp);
+			continue;
+		}
+
 		push_ascii_fstring(dos_ea_name, listp->ea.name);
 
 		*pea_total_len +=
@@ -458,6 +469,7 @@ static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
 {
 	uint8_t *p = (uint8_t *)pdata;
 	uint8_t *last_start = NULL;
+	bool do_store_data = (pdata != NULL);
 
 	*ret_data_size = 0;
 
@@ -469,8 +481,9 @@ static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
 		size_t dos_namelen;
 		fstring dos_ea_name;
 		size_t this_size;
+		size_t pad = 0;
 
-		if (last_start) {
+		if (last_start != NULL && do_store_data) {
 			SIVAL(last_start, 0, PTR_DIFF(p, last_start));
 		}
 		last_start = p;
@@ -487,23 +500,30 @@ static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
 		this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length;
 
 		if (ea_list->next) {
-			size_t pad = 4 - (this_size % 4);
+			pad = (4 - (this_size % 4)) % 4;
 			this_size += pad;
 		}
 
-		if (this_size > total_data_size) {
-			return NT_STATUS_INFO_LENGTH_MISMATCH;
+		if (do_store_data) {
+			if (this_size > total_data_size) {
+				return NT_STATUS_INFO_LENGTH_MISMATCH;
+			}
+
+			/* We know we have room. */
+			SIVAL(p, 0x00, 0); /* next offset */
+			SCVAL(p, 0x04, ea_list->ea.flags);
+			SCVAL(p, 0x05, dos_namelen);
+			SSVAL(p, 0x06, ea_list->ea.value.length);
+			strlcpy((char *)(p+0x08), dos_ea_name, dos_namelen+1);
+			memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
+			if (pad) {
+				memset(p + 0x08 + dos_namelen + 1 + ea_list->ea.value.length,
+					'\0',
+					pad);
+			}
+			total_data_size -= this_size;
 		}
 
-		/* We know we have room. */
-		SIVAL(p, 0x00, 0); /* next offset */
-		SCVAL(p, 0x04, ea_list->ea.flags);
-		SCVAL(p, 0x05, dos_namelen);
-		SSVAL(p, 0x06, ea_list->ea.value.length);
-		strlcpy((char *)(p+0x08), dos_ea_name, dos_namelen+1);
-		memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
-
-		total_data_size -= this_size;
 		p += this_size;
 	}
 
@@ -516,7 +536,7 @@ static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp,
 {
 	size_t total_ea_len = 0;
 	TALLOC_CTX *mem_ctx;
-	struct ea_list *ea_list;
+	struct ea_list *ea_list = NULL;
 
 	if (!lp_ea_support(SNUM(conn))) {
 		return 0;
@@ -531,6 +551,26 @@ static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp,
 		fsp = NULL;
 	}
 	(void)get_ea_list_from_file_path(mem_ctx, conn, fsp, smb_fname->base_name, &total_ea_len, &ea_list);
+	if(conn->sconn->using_smb2) {
+		NTSTATUS status;
+		unsigned int ret_data_size;
+		/*
+		 * We're going to be using fill_ea_chained_buffer() to
+		 * marshall EA's - this size is significantly larger
+		 * than the SMB1 buffer. Re-calculate the size without
+		 * marshalling.
+		 */
+		status = fill_ea_chained_buffer(mem_ctx,
+						NULL,
+						0,
+						&ret_data_size,
+						conn,
+						ea_list);
+		if (!NT_STATUS_IS_OK(status)) {
+			ret_data_size = 0;
+		}
+		total_ea_len = ret_data_size;
+	}
 	TALLOC_FREE(mem_ctx);
 	return total_ea_len;
 }
diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c
index ac3e6a6..33ff9ce 100644
--- a/source4/ntvfs/posix/pvfs_qfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_qfileinfo.c
@@ -102,6 +102,9 @@ NTSTATUS pvfs_query_ea_list(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
 		for (j=0;j<ealist->num_eas;j++) {
 			if (strcasecmp_m(eas->eas[i].name.s, 
 				       ealist->eas[j].name) == 0) {
+				if (ealist->eas[j].value.length == 0) {
+					continue;
+				}
 				eas->eas[i].value = ealist->eas[j].value;
 				break;
 			}
@@ -134,6 +137,9 @@ static NTSTATUS pvfs_query_all_eas(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
 	for (i=0;i<ealist->num_eas;i++) {
 		eas->eas[eas->num_eas].flags = 0;
 		eas->eas[eas->num_eas].name.s = ealist->eas[i].name;
+		if (ealist->eas[i].value.length == 0) {
+			continue;
+		}
 		eas->eas[eas->num_eas].value = ealist->eas[i].value;
 		eas->num_eas++;
 	}
diff --git a/source4/torture/smb2/setinfo.c b/source4/torture/smb2/setinfo.c
index 719e8f0..fee7293 100644
--- a/source4/torture/smb2/setinfo.c
+++ b/source4/torture/smb2/setinfo.c
@@ -30,6 +30,36 @@
 #include "libcli/security/security.h"
 #include "librpc/gen_ndr/ndr_security.h"
 
+static bool find_returned_ea(union smb_fileinfo *finfo2,
+				const char *eaname,
+				const char *eavalue)
+{
+	unsigned int i;
+	unsigned int num_eas = finfo2->all_eas.out.num_eas;
+	struct ea_struct *eas = finfo2->all_eas.out.eas;
+
+	for (i = 0; i < num_eas; i++) {
+		if (eas[i].name.s == NULL) {
+			continue;
+		}
+		/* Windows capitalizes returned EA names. */
+		if (strcasecmp_m(eas[i].name.s, eaname)) {
+			continue;
+		}
+		if (eavalue == NULL && eas[i].value.length == 0) {
+			/* Null value, found it ! */
+			return true;
+		}
+		if (eas[i].value.length == strlen(eavalue) &&
+				memcmp(eas[i].value.data,
+					eavalue,
+					strlen(eavalue)) == 0) {
+			return true;
+		}
+	}
+	return false;
+}
+
 #define BASEDIR ""
 
 #define FAIL_UNLESS(__cond)					\
@@ -60,6 +90,7 @@ bool torture_smb2_setinfo(struct torture_context *tctx)
 	const char *call_name;
 	time_t basetime = (time(NULL) - 86400) & ~1;
 	int n = time(NULL) % 100;
+	struct ea_struct ea;
 	
 	ZERO_STRUCT(handle);
 	
@@ -276,6 +307,96 @@ bool torture_smb2_setinfo(struct torture_context *tctx)
 	CHECK_CALL(SEC_DESC, NT_STATUS_OK);
 	FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, handle, sd));
 
+	torture_comment(tctx, "Check zero length EA's behavior\n");
+
+	/* Set a new EA. */
+	sfinfo.full_ea_information.in.eas.num_eas = 1;
+	ea.flags = 0;
+	ea.name.private_length = 6;
+	ea.name.s = "NewEA";
+	ea.value = data_blob_string_const("testme");
+	sfinfo.full_ea_information.in.eas.eas = &ea;
+	CHECK_CALL(FULL_EA_INFORMATION, NT_STATUS_OK);
+
+	/* Does it still exist ? */
+	finfo2.generic.level = RAW_FILEINFO_SMB2_ALL_EAS;
+	finfo2.generic.in.file.handle = handle;
+	finfo2.all_eas.in.continue_flags = 1;
+	status2 = smb2_getinfo_file(tree, tctx, &finfo2);
+	if (!NT_STATUS_IS_OK(status2)) {
+		torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s\n", __location__,
+			"SMB2_ALL_EAS", nt_errstr(status2));
+		ret = false;
+		goto done;
+	}
+
+	/* Note on Windows EA name is returned capitalized. */
+	if (!find_returned_ea(&finfo2, "NewEA", "testme")) {
+		torture_result(tctx, TORTURE_FAIL, "(%s) Missing EA 'NewEA'\n", __location__);
+		ret = false;
+	}
+
+	/* Now zero it out (should delete it) */
+	sfinfo.full_ea_information.in.eas.num_eas = 1;
+	ea.flags = 0;
+	ea.name.private_length = 6;
+	ea.name.s = "NewEA";
+	ea.value = data_blob_null;
+	sfinfo.full_ea_information.in.eas.eas = &ea;
+	CHECK_CALL(FULL_EA_INFORMATION, NT_STATUS_OK);
+
+	/* Does it still exist ? */
+	finfo2.generic.level = RAW_FILEINFO_SMB2_ALL_EAS;
+	finfo2.generic.in.file.handle = handle;
+	finfo2.all_eas.in.continue_flags = 1;
+	status2 = smb2_getinfo_file(tree, tctx, &finfo2);
+	if (!NT_STATUS_IS_OK(status2)) {
+		torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s\n", __location__,
+			"SMB2_ALL_EAS", nt_errstr(status2));
+		ret = false;
+		goto done;
+	}
+
+	if (find_returned_ea(&finfo2, "NewEA", NULL)) {
+		torture_result(tctx, TORTURE_FAIL, "(%s) EA 'NewEA' should be deleted\n", __location__);
+		ret = false;
+	}
+
+	/* Set a zero length EA. */
+	sfinfo.full_ea_information.in.eas.num_eas = 1;
+	ea.flags = 0;
+	ea.name.private_length = 6;
+	ea.name.s = "ZeroEA";
+	ea.value = data_blob_null;
+	sfinfo.full_ea_information.in.eas.eas = &ea;
+	CHECK_CALL(FULL_EA_INFORMATION, NT_STATUS_OK);
+
+	/* Does it still exist ? */
+	finfo2.generic.level = RAW_FILEINFO_SMB2_ALL_EAS;
+	finfo2.generic.in.file.handle = handle;
+	finfo2.all_eas.in.continue_flags = 1;
+	status2 = smb2_getinfo_file(tree, tctx, &finfo2);
+	if (!NT_STATUS_IS_OK(status2)) {
+		torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s\n", __location__,
+			"SMB2_ALL_EAS", nt_errstr(status2));
+		ret = false;
+		goto done;
+	}
+
+	/* Over SMB2 ZeroEA should not exist. */
+	if (!find_returned_ea(&finfo2, "EAONE", "VALUE1")) {
+		torture_result(tctx, TORTURE_FAIL, "(%s) Missing EA 'EAONE'\n", __location__);
+		ret = false;
+	}
+	if (!find_returned_ea(&finfo2, "SECONDEA", "ValueTwo")) {
+		torture_result(tctx, TORTURE_FAIL, "(%s) Missing EA 'SECONDEA'\n", __location__);
+		ret = false;
+	}
+	if (find_returned_ea(&finfo2, "ZeroEA", NULL)) {
+		torture_result(tctx, TORTURE_FAIL, "(%s) Found null EA 'ZeroEA'\n", __location__);
+		ret = false;
+	}
+
 done:
 	status = smb2_util_close(tree, handle);
 	if (NT_STATUS_IS_ERR(status)) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list