From a09949d54b546d12ebdc12e1784878f759729fbd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Jul 2013 15:50:47 -0700 Subject: [PATCH 01/11] Add ea_list_has_invalid_name() function. Invalid character list probed from Windows Server 2012. Bug 9992: Windows error 0x800700FE when copying files with xattr names containing ":" Signed-off-by: Jeremy Allison --- source3/include/proto.h | 2 ++ source3/lib/filename_util.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 83ab77a..a9270fc 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1611,6 +1611,8 @@ struct smb_filename *cp_smb_filename(TALLOC_CTX *mem_ctx, const struct smb_filename *in); bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname); bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname); +bool is_invalid_windows_ea_name(const char *name); +bool ea_list_has_invalid_name(struct ea_list *ea_list); /* The following definitions come from lib/dummyroot.c */ diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c index 656dd2a..19ffcc3 100644 --- a/source3/lib/filename_util.c +++ b/source3/lib/filename_util.c @@ -224,3 +224,37 @@ bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) return strcasecmp_m(smb_fname->stream_name, "::$DATA") == 0; } + +/**************************************************************************** + Filter out Windows invalid EA names (list probed from Windows 2012). +****************************************************************************/ + +static char bad_ea_name_chars[] = "\"*+,/:;<=>?[\\]|"; + +bool is_invalid_windows_ea_name(const char *name) +{ + int i; + /* EA name is pulled as ascii so we can examine + individual bytes here. */ + for (i = 0; name[i] != 0; i++) { + int val = (name[i] & 0xff); + if (val < ' ' || strchr(bad_ea_name_chars, val)) { + return true; + } + } + return false; +} + +bool ea_list_has_invalid_name(struct ea_list *ea_list) +{ + if (lp_posix_pathnames()) { + return false; + } + + for (;ea_list; ea_list = ea_list->next) { + if (is_invalid_windows_ea_name(ea_list->ea.name)) { + return true; + } + } + return false; +} -- 1.8.3 From 65b75b5ae195e6e6490e7b5a4d2ea5ead8286b11 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Jul 2013 15:52:47 -0700 Subject: [PATCH 02/11] Ensure set_ea cannot set invalid Windows EA names. Bug 9992 - Windows error 0x800700FE when copying files with xattr names containing ":" Signed-off-by: Jeremy Allison --- source3/smbd/trans2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 14a2e0f..7bce6ea 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -623,6 +623,15 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, return NT_STATUS_INVALID_PARAMETER; } + /* + * Filter out invalid Windows EA names - before + * we set *any* of them. + */ + + if (ea_list_has_invalid_name(ea_list)) { + return STATUS_INVALID_EA_NAME; + } + fname = smb_fname->base_name; for (;ea_list; ea_list = ea_list->next) { -- 1.8.3 From 6b8d200d8ef7452b0de81802f7c0c61b2cc549e4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Jul 2013 16:21:18 -0700 Subject: [PATCH 03/11] Ensure we never return an EA name to a Windows client it can't handle. Bug 9992 - Windows error 0x800700FE when copying files with xattr names containing ":" Signed-off-by: Jeremy Allison --- source3/smbd/trans2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 7bce6ea..8532240 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -345,6 +345,15 @@ static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx, connection_struc || samba_private_attr_name(names[i])) continue; + /* + * Filter out any underlying POSIX EA names + * that a Windows client can't handle. + */ + if (!lp_posix_pathnames() && + is_invalid_windows_ea_name(names[i])) { + continue; + } + listp = talloc(mem_ctx, struct ea_list); if (listp == NULL) { return NT_STATUS_NO_MEMORY; -- 1.8.3 From 3fbdb4ebee7aa3e031087f61dda0dab489cbc2c4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Jul 2013 16:02:50 -0700 Subject: [PATCH 04/11] Ensure we can't create a file using SMB2_CREATE with an invalid EA list. Bug 9992 - Windows error 0x800700FE when copying files with xattr names containing ":" Signed-off-by: Jeremy Allison --- source3/smbd/smb2_create.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index 6a43d27..168beac 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -584,6 +584,11 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return tevent_req_post(req, ev); } + + if (ea_list_has_invalid_name(ea_list)) { + tevent_req_nterror(req, STATUS_INVALID_EA_NAME); + return tevent_req_post(req, ev); + } } if (mxac) { -- 1.8.3 From c7eef5c01c63f5bf26e6f2e923ff37f780a85c97 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Jul 2013 12:38:41 -0700 Subject: [PATCH 05/11] Add the ability to send an NTSTATUS result back with a trans2 reply so we can return a parameter block with an error code. This is needed when returning a STATUS_INVALID_NAME result (tested from Windows 2012). Bug 9992 - Windows error 0x800700FE when copying files with xattr names containing ":" Signed-off-by: Jeremy Allison --- source3/smbd/blocking.c | 2 +- source3/smbd/proto.h | 1 + source3/smbd/trans2.c | 43 ++++++++++++++++++++++++++++++------------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 4bd7a57..5f6dda3 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -563,7 +563,7 @@ static bool process_trans2(struct blocking_lock_record *blr) SSVAL(params,0,0); /* Fake up max_data_bytes here - we know it fits. */ - send_trans2_replies(blr->fsp->conn, blr->req, params, 2, NULL, 0, 0xffff); + send_trans2_replies(blr->fsp->conn, blr->req, NT_STATUS_OK, params, 2, NULL, 0, 0xffff); return True; } diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 38707d5..9c76609 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -1071,6 +1071,7 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used); void send_trans2_replies(connection_struct *conn, struct smb_request *req, + NTSTATUS status, const char *params, int paramsize, const char *pdata, diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 8532240..7f0aaf9 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -896,6 +896,7 @@ static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list * void send_trans2_replies(connection_struct *conn, struct smb_request *req, + NTSTATUS status, const char *params, int paramsize, const char *pdata, @@ -936,6 +937,14 @@ void send_trans2_replies(connection_struct *conn, if(params_to_send == 0 && data_to_send == 0) { reply_outbuf(req, 10, 0); + if (NT_STATUS_V(status)) { + uint8_t eclass; + uint32_t ecode; + ntstatus_to_dos(status, &eclass, &ecode); + error_packet_set((char *)req->outbuf, + eclass, ecode, status, + __LINE__,__FILE__); + } show_msg((char *)req->outbuf); if (!srv_send_smb(sconn, (char *)req->outbuf, @@ -1066,6 +1075,13 @@ void send_trans2_replies(connection_struct *conn, ERRDOS,ERRbufferoverflow, STATUS_BUFFER_OVERFLOW, __LINE__,__FILE__); + } else if (NT_STATUS_V(status)) { + uint8_t eclass; + uint32_t ecode; + ntstatus_to_dos(status, &eclass, &ecode); + error_packet_set((char *)req->outbuf, + eclass, ecode, status, + __LINE__,__FILE__); } /* Send the packet */ @@ -1312,7 +1328,7 @@ static void call_trans2open(connection_struct *conn, } /* Send the required number of replies */ - send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes); + send_trans2_replies(conn, req, NT_STATUS_OK, params, 30, *ppdata, 0, max_data_bytes); out: TALLOC_FREE(smb_fname); } @@ -2676,7 +2692,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd SSVAL(params,6,0); /* Never an EA error */ SSVAL(params,8,last_entry_off); - send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata), + send_trans2_replies(conn, req, NT_STATUS_OK, params, 10, pdata, PTR_DIFF(p,pdata), max_data_bytes); if ((! *directory) && dptr_path(sconn, dptr_num)) { @@ -3027,7 +3043,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd SSVAL(params,4,0); /* Never an EA error */ SSVAL(params,6,last_entry_off); - send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata), + send_trans2_replies(conn, req, NT_STATUS_OK, params, 8, pdata, PTR_DIFF(p,pdata), max_data_bytes); return; @@ -3671,7 +3687,7 @@ static void call_trans2qfsinfo(connection_struct *conn, return; } - send_trans2_replies(conn, req, params, 0, *ppdata, data_len, + send_trans2_replies(conn, req, NT_STATUS_OK, params, 0, *ppdata, data_len, max_data_bytes); DEBUG( 4, ( "%s info_level = %d\n", @@ -3827,6 +3843,7 @@ static void call_trans2setfsinfo(connection_struct *conn, } send_trans2_replies(conn, req, + NT_STATUS_OK, *pparams, param_len, *ppdata, @@ -4359,7 +4376,7 @@ static void call_trans2qpipeinfo(connection_struct *conn, return; } - send_trans2_replies(conn, req, params, param_size, *ppdata, data_size, + send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size, max_data_bytes); return; @@ -5561,7 +5578,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd return; } - send_trans2_replies(conn, req, params, param_size, *ppdata, data_size, + send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size, max_data_bytes); return; @@ -8124,7 +8141,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, fsp_str_dbg(fsp))); SSVAL(params,0,0); - send_trans2_replies(conn, req, params, 2, + send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, 0, max_data_bytes); return; @@ -8251,7 +8268,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, return; } - send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size, + send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, data_return_size, max_data_bytes); return; @@ -8376,7 +8393,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, SSVAL(params,0,0); - send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes); + send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, 0, max_data_bytes); out: TALLOC_FREE(smb_dname); @@ -8431,7 +8448,7 @@ static void call_trans2findnotifyfirst(connection_struct *conn, if(fnf_handle == 0) fnf_handle = 257; - send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes); + send_trans2_replies(conn, req, NT_STATUS_OK, params, 6, *ppdata, 0, max_data_bytes); return; } @@ -8462,7 +8479,7 @@ static void call_trans2findnotifynext(connection_struct *conn, SSVAL(params,0,0); /* No changes */ SSVAL(params,2,0); /* No EA errors */ - send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes); + send_trans2_replies(conn, req, NT_STATUS_OK, params, 4, *ppdata, 0, max_data_bytes); return; } @@ -8512,7 +8529,7 @@ static void call_trans2getdfsreferral(connection_struct *conn, SSVAL((discard_const_p(uint8_t, req->inbuf)), smb_flg2, SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES); - send_trans2_replies(conn, req,0,0,*ppdata,reply_size, max_data_bytes); + send_trans2_replies(conn, req, NT_STATUS_OK, 0,0,*ppdata,reply_size, max_data_bytes); return; } @@ -8561,7 +8578,7 @@ static void call_trans2ioctl(connection_struct *conn, srvstr_push(pdata, req->flags2, pdata+18, lp_servicename(talloc_tos(), SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */ - send_trans2_replies(conn, req, *pparams, 0, *ppdata, 32, + send_trans2_replies(conn, req, NT_STATUS_OK, *pparams, 0, *ppdata, 32, max_data_bytes); return; } -- 1.8.3 From aa6a12596b2c1f94b47f6eb1cb59942889a5beaa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Jul 2013 12:18:36 -0700 Subject: [PATCH 06/11] Add error map of STATUS_INVALID_EA_NAME -> ERRDOS, ERRbadfile (from Windows2012 tests). Bug 9992 - Windows error 0x800700FE when copying files with xattr names containing ":" Signed-off-by: Jeremy Allison --- libcli/util/errormap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libcli/util/errormap.c b/libcli/util/errormap.c index 714e62c..3870619 100644 --- a/libcli/util/errormap.c +++ b/libcli/util/errormap.c @@ -54,6 +54,7 @@ static const struct { */ {ERRDOS, ERRmoredata, STATUS_BUFFER_OVERFLOW}, {ERRDOS, ERRnofiles, STATUS_NO_MORE_FILES}, + {ERRDOS, ERRbadfile, STATUS_INVALID_EA_NAME}, {ERRDOS, ERRnofiles, NT_STATUS_NO_MORE_ENTRIES}, {ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, -- 1.8.3 From b1a0ee5eeb5d1dc31a1c423c9ec98105c868dd67 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Jul 2013 15:59:53 -0700 Subject: [PATCH 07/11] Ensure we can't create a file using TRANS2_OPEN with an invalid EA list. Bug 9992 - Windows error 0x800700FE when copying files with xattr names containing ":" Signed-off-by: Jeremy Allison --- source3/smbd/trans2.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 7f0aaf9..916686c 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1253,6 +1253,20 @@ static void call_trans2open(connection_struct *conn, reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED); goto out; } + + if (ea_list_has_invalid_name(ea_list)) { + int param_len = 30; + *pparams = (char *)SMB_REALLOC(*pparams, param_len); + if(*pparams == NULL ) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + goto out; + } + params = *pparams; + memset(params, '\0', param_len); + send_trans2_replies(conn, req, STATUS_INVALID_EA_NAME, + params, param_len, NULL, 0, max_data_bytes); + goto out; + } } status = SMB_VFS_CREATE_FILE( -- 1.8.3 From 26f29e4a308091c861daf42d0dbc735799eebc00 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Jul 2013 15:54:39 -0700 Subject: [PATCH 08/11] Ensure we can't create a file using NTTRANS with an invalid EA list. Bug 9992 - Windows error 0x800700FE when copying files with xattr names containing ":" Signed-off-by: Jeremy Allison --- source3/smbd/nttrans.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index f5e5877..89476a8 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1141,6 +1141,26 @@ static void call_nt_transact_create(connection_struct *conn, reply_nterror(req, NT_STATUS_INVALID_PARAMETER); goto out; } + + if (ea_list_has_invalid_name(ea_list)) { + /* Realloc the size of parameters and data we will return */ + if (flags & EXTENDED_RESPONSE_REQUIRED) { + /* Extended response is 32 more byyes. */ + param_len = 101; + } else { + param_len = 69; + } + params = nttrans_realloc(ppparams, param_len); + if(params == NULL) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + goto out; + } + + memset(params, '\0', param_len); + send_nt_replies(conn, req, STATUS_INVALID_EA_NAME, + params, param_len, NULL, 0); + goto out; + } } srvstr_get_path(ctx, params, req->flags2, &fname, -- 1.8.3 From e9e4a628ce11807df0985c1de802dcbcd0ba921e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 16 Jul 2013 11:05:10 -0700 Subject: [PATCH 09/11] Ensure we do pathname processing before SD and EA processing in NTTRANS_CREATE. Bug 9992 - Windows error 0x800700FE when copying files with xattr names containing ":" Signed-off-by: Jeremy Allison --- source3/smbd/nttrans.c | 74 +++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 89476a8..72aaa7a 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1091,6 +1091,43 @@ static void call_nt_transact_create(connection_struct *conn, */ create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK; + srvstr_get_path(ctx, params, req->flags2, &fname, + params+53, parameter_count-53, + STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + goto out; + } + + if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) { + case_state = set_posix_case_semantics(ctx, conn); + if (!case_state) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + goto out; + } + } + + status = filename_convert(ctx, + conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname, + 0, + NULL, + &smb_fname); + + TALLOC_FREE(case_state); + + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + goto out; + } + reply_nterror(req, status); + goto out; + } + /* Ensure the data_len is correct for the sd and ea values given. */ if ((ea_len + sd_len > data_count) || (ea_len > data_count) || (sd_len > data_count) @@ -1163,43 +1200,6 @@ static void call_nt_transact_create(connection_struct *conn, } } - srvstr_get_path(ctx, params, req->flags2, &fname, - params+53, parameter_count-53, - STR_TERMINATE, &status); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - - if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) { - case_state = set_posix_case_semantics(ctx, conn); - if (!case_state) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - goto out; - } - } - - status = filename_convert(ctx, - conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - fname, - 0, - NULL, - &smb_fname); - - TALLOC_FREE(case_state); - - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { - reply_botherror(req, - NT_STATUS_PATH_NOT_COVERED, - ERRSRV, ERRbadpath); - goto out; - } - reply_nterror(req, status); - goto out; - } - oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; if (oplock_request) { oplock_request |= (flags & REQUEST_BATCH_OPLOCK) -- 1.8.3 From 508844888b47e14d383db7bfc4de316c8e63ce24 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 16 Jul 2013 09:14:12 -0700 Subject: [PATCH 10/11] Reply with correct trans2 message on a setpathinfo with a bad EA name. Bug 9992 - Windows error 0x800700FE when copying files with xattr names containing ":" Signed-off-by: Jeremy Allison --- source3/smbd/trans2.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 916686c..a216f15 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -8278,7 +8278,16 @@ static void call_trans2setfilepathinfo(connection_struct *conn, return; } - reply_nterror(req, status); + /* + * Invalid EA name needs to return 2 param bytes, + * not a zero-length error packet. + */ + if (NT_STATUS_EQUAL(status, STATUS_INVALID_EA_NAME)) { + send_trans2_replies(conn, req, status, params, 2, NULL, 0, + max_data_bytes); + } else { + reply_nterror(req, status); + } return; } -- 1.8.3 From 8b99c1ccae27a4d43b79a4806c4be24ffd4441ed Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Jul 2013 16:37:48 -0700 Subject: [PATCH 11/11] Add torture tests to raw.eas to check sending Windows invalid names in the middle of an EA list. Add torture tests to probe the set of invalid Windows EA names. Bug 9992 - Windows error 0x800700FE when copying files with xattr names containing ":" Signed-off-by: Jeremy Allison --- selftest/knownfail | 1 + source4/torture/raw/eas.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) diff --git a/selftest/knownfail b/selftest/knownfail index 313d6c9..4fe96f3 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -81,6 +81,7 @@ ^samba4.raw.session.expire1 ^samba4.raw.rename.*.osxrename ^samba4.raw.rename.*.directory rename +^samba4.raw.eas ^samba4.rpc.winreg.*security ^samba4.local.registry.(dir|ldb).check hive security ^samba4.local.registry.local.security diff --git a/source4/torture/raw/eas.c b/source4/torture/raw/eas.c index a0ba06f..95a55d1 100644 --- a/source4/torture/raw/eas.c +++ b/source4/torture/raw/eas.c @@ -42,6 +42,8 @@ static bool check_ea(struct smbcli_state *cli, return NT_STATUS_IS_OK(status); } +static char bad_ea_chars[] = "\"*+,/:;<=>?[\\]|"; + static bool test_eas(struct smbcli_state *cli, struct torture_context *tctx) { NTSTATUS status; @@ -49,6 +51,8 @@ static bool test_eas(struct smbcli_state *cli, struct torture_context *tctx) union smb_open io; const char *fname = BASEDIR "\\ea.txt"; bool ret = true; + char bad_ea_name[6]; + int i; int fnum = -1; torture_comment(tctx, "TESTING SETFILEINFO EA_SET\n"); @@ -131,6 +135,59 @@ static bool test_eas(struct smbcli_state *cli, struct torture_context *tctx) ret &= check_ea(cli, fname, "EAONE", NULL); ret &= check_ea(cli, fname, "SECONDEA", NULL); + /* Check EA name containing colon. All EA's set + must be ignored, not just the one with the bad + name. */ + + torture_comment(tctx, "Adding bad EA name\n"); + setfile.generic.level = RAW_SFILEINFO_EA_SET; + setfile.generic.in.file.fnum = fnum; + setfile.ea_set.in.num_eas = 3; + setfile.ea_set.in.eas = talloc_array(tctx, struct ea_struct, 3); + setfile.ea_set.in.eas[0].flags = 0; + setfile.ea_set.in.eas[0].name.s = "EAONE"; + setfile.ea_set.in.eas[0].value = data_blob_string_const("VALUE1"); + setfile.ea_set.in.eas[1].flags = 0; + setfile.ea_set.in.eas[1].name.s = "SECOND:EA"; + setfile.ea_set.in.eas[1].value = data_blob_string_const("ValueTwo"); + setfile.ea_set.in.eas[2].flags = 0; + setfile.ea_set.in.eas[2].name.s = "THIRDEA"; + setfile.ea_set.in.eas[2].value = data_blob_string_const("ValueThree"); + + status = smb_raw_setfileinfo(cli->tree, &setfile); + CHECK_STATUS(status, STATUS_INVALID_EA_NAME); + + ret &= check_ea(cli, fname, "EAONE", NULL); + ret &= check_ea(cli, fname, "THIRDEA", NULL); + + setfile.generic.level = RAW_SFILEINFO_EA_SET; + setfile.generic.in.file.fnum = fnum; + setfile.ea_set.in.num_eas = 1; + setfile.ea_set.in.eas = talloc_array(tctx, struct ea_struct, 1); + setfile.ea_set.in.eas[0].flags = 0; + strlcpy(bad_ea_name, "TEST_X", sizeof(bad_ea_name)); + setfile.ea_set.in.eas[0].name.s = bad_ea_name; + + torture_comment(tctx, "Testing bad EA name range.\n"); + + for (i = 1; i < 256; i++) { + setfile.ea_set.in.eas[0].value = data_blob_string_const("VALUE1"); + bad_ea_name[5] = (char)i; + torture_comment(tctx, "Testing bad EA name %d.\n", i); + status = smb_raw_setfileinfo(cli->tree, &setfile); + if (i < 32 || strchr(bad_ea_chars, i)) { + CHECK_STATUS(status, STATUS_INVALID_EA_NAME); + } else { + CHECK_STATUS(status, NT_STATUS_OK); + + /* Now delete the EA we just set to make + sure we don't run out of room. */ + setfile.ea_set.in.eas[0].value = data_blob(NULL, 0); + status = smb_raw_setfileinfo(cli->tree, &setfile); + CHECK_STATUS(status, NT_STATUS_OK); + } + } + done: smbcli_close(cli->tree, fnum); return ret; @@ -365,6 +422,7 @@ static bool test_nttrans_create(struct smbcli_state *cli, struct torture_context NTSTATUS status; union smb_open io; const char *fname = BASEDIR "\\ea2.txt"; + const char *fname_bad = BASEDIR "\\ea2_bad.txt"; bool ret = true; int fnum = -1; struct ea_struct eas[3]; @@ -434,6 +492,62 @@ static bool test_nttrans_create(struct smbcli_state *cli, struct torture_context ret &= check_ea(cli, fname, "and 3rd", "final value"); ret &= check_ea(cli, fname, "Fourth EA", NULL); + torture_comment(tctx, "TESTING NTTRANS CREATE WITH BAD EA NAMES\n"); + + io.generic.level = RAW_OPEN_NTTRANS_CREATE; + io.ntcreatex.in.root_fid.fnum = 0; + io.ntcreatex.in.flags = 0; + io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = fname_bad; + + ea_list.num_eas = 3; + ea_list.eas = eas; + + eas[0].flags = 0; + eas[0].name.s = "1st EA"; + eas[0].value = data_blob_string_const("Value One"); + + eas[1].flags = 0; + eas[1].name.s = "2nd:BAD:EA"; + eas[1].value = data_blob_string_const("Second Value"); + + eas[2].flags = 0; + eas[2].name.s = "and 3rd"; + eas[2].value = data_blob_string_const("final value"); + + io.ntcreatex.in.ea_list = &ea_list; + io.ntcreatex.in.sec_desc = NULL; + + status = smb_raw_open(cli->tree, tctx, &io); + CHECK_STATUS(status, STATUS_INVALID_EA_NAME); + + /* File must not exist. */ + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid.fnum = 0; + io.ntcreatex.in.flags = 0; + io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = fname_bad; + status = smb_raw_open(cli->tree, tctx, &io); + CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); + done: smbcli_close(cli->tree, fnum); return ret; -- 1.8.3