diff options
author | Jeremy Allison <jra@samba.org> | 2013-07-10 12:38:41 -0700 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2013-07-19 17:52:39 +1000 |
commit | 50a288cb6a9bfff1d16cf488bbc0eedcb6ad4602 (patch) | |
tree | 25a7ec2194e8ef0da7415907c68212ee8903b2bc | |
parent | 21c92969b8d0ad7a77028d24c5b3fea63264e473 (diff) | |
download | samba-50a288cb6a9bfff1d16cf488bbc0eedcb6ad4602.tar.gz samba-50a288cb6a9bfff1d16cf488bbc0eedcb6ad4602.tar.xz samba-50a288cb6a9bfff1d16cf488bbc0eedcb6ad4602.zip |
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 <jra@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-rw-r--r-- | source3/smbd/blocking.c | 2 | ||||
-rw-r--r-- | source3/smbd/proto.h | 1 | ||||
-rw-r--r-- | 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 4bd7a5732fc..5f6dda318e6 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 38707d50ffe..9c766096ed6 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 8532240fb98..7f0aaf982b2 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; } |