[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