mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r1165: fixed handling of SMBtrans replies that should return STATUS_BUFFER_OVERFLOW when more data is present.
(This used to be commit 0e557fe857
)
This commit is contained in:
parent
eca6982a95
commit
b00103dac1
@ -401,7 +401,7 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd)
|
||||
}
|
||||
|
||||
status = dcesrv_output_blob(p->dce_conn, &data);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (NT_STATUS_IS_ERR(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -418,7 +418,7 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd)
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -624,7 +624,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *t
|
||||
the error is encoded at the dcerpc level
|
||||
*/
|
||||
status = dcesrv_output_blob(p->dce_conn, &trans->out.data);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (NT_STATUS_IS_ERR(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -632,7 +632,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *t
|
||||
trans->out.setup = NULL;
|
||||
trans->out.params = data_blob(NULL, 0);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -902,6 +902,9 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data)
|
||||
will be the number of bytes to be sent.
|
||||
|
||||
write_fn() should return the number of bytes successfully written.
|
||||
|
||||
this will return STATUS_BUFFER_OVERFLOW if there is more to be read
|
||||
from the current fragment
|
||||
*/
|
||||
NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn,
|
||||
void *private,
|
||||
@ -910,6 +913,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn,
|
||||
struct dcesrv_call_state *call;
|
||||
struct dcesrv_call_reply *rep;
|
||||
ssize_t nwritten;
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
|
||||
call = dce_conn->call_list;
|
||||
if (!call || !call->replies) {
|
||||
@ -930,6 +934,8 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn,
|
||||
if (rep->data.length == 0) {
|
||||
/* we're done with this section of the call */
|
||||
DLIST_REMOVE(call->replies, rep);
|
||||
} else {
|
||||
status = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
if (call->replies == NULL) {
|
||||
@ -938,7 +944,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn,
|
||||
talloc_destroy(call->mem_ctx);
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -79,7 +79,7 @@ static void dcerpc_write_handler(struct event_context *ev, struct fd_event *fde,
|
||||
NTSTATUS status;
|
||||
|
||||
status = dcesrv_output(r->dce_conn, fde, dcerpc_write_fn);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (NT_STATUS_IS_ERR(status)) {
|
||||
/* TODO: destroy fd_event? */
|
||||
}
|
||||
|
||||
|
@ -297,12 +297,37 @@ void req_reply_dos_error(struct request_context *req, uint8_t eclass, uint16_t e
|
||||
|
||||
SCVAL(req->out.hdr, HDR_RCLS, eclass);
|
||||
SSVAL(req->out.hdr, HDR_ERR, ecode);
|
||||
|
||||
SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) & ~FLAGS2_32_BIT_ERROR_CODES);
|
||||
|
||||
SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) & ~FLAGS2_32_BIT_ERROR_CODES);
|
||||
req_send_reply(req);
|
||||
}
|
||||
|
||||
/*
|
||||
setup the header of a reply to include an NTSTATUS code
|
||||
*/
|
||||
void req_setup_error(struct request_context *req, NTSTATUS status)
|
||||
{
|
||||
if (!lp_nt_status_support() || !(req->smb->negotiate.client_caps & CAP_STATUS32)) {
|
||||
/* convert to DOS error codes */
|
||||
uint8_t eclass;
|
||||
uint32_t ecode;
|
||||
ntstatus_to_dos(status, &eclass, &ecode);
|
||||
SCVAL(req->out.hdr, HDR_RCLS, eclass);
|
||||
SSVAL(req->out.hdr, HDR_ERR, ecode);
|
||||
SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) & ~FLAGS2_32_BIT_ERROR_CODES);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NT_STATUS_IS_DOS(status)) {
|
||||
/* its a encoded DOS error, using the reserved range */
|
||||
SSVAL(req->out.hdr, HDR_RCLS, NT_STATUS_DOS_CLASS(status));
|
||||
SSVAL(req->out.hdr, HDR_ERR, NT_STATUS_DOS_CODE(status));
|
||||
SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) & ~FLAGS2_32_BIT_ERROR_CODES);
|
||||
} else {
|
||||
SIVAL(req->out.hdr, HDR_RCLS, NT_STATUS_V(status));
|
||||
SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) | FLAGS2_32_BIT_ERROR_CODES);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
construct and send an error packet, then destroy the request
|
||||
auto-converts to DOS error format when appropriate
|
||||
@ -314,25 +339,7 @@ void req_reply_error(struct request_context *req, NTSTATUS status)
|
||||
/* error returns never have any data */
|
||||
req_grow_data(req, 0);
|
||||
|
||||
if (!lp_nt_status_support() || !(req->smb->negotiate.client_caps & CAP_STATUS32)) {
|
||||
/* convert to DOS error codes */
|
||||
uint8_t eclass;
|
||||
uint32_t ecode;
|
||||
ntstatus_to_dos(status, &eclass, &ecode);
|
||||
req_reply_dos_error(req, eclass, ecode);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NT_STATUS_IS_DOS(status)) {
|
||||
/* its a encoded DOS error, using the reserved range */
|
||||
SSVAL(req->out.hdr, HDR_RCLS, NT_STATUS_DOS_CLASS(status));
|
||||
SSVAL(req->out.hdr, HDR_ERR, NT_STATUS_DOS_CODE(status));
|
||||
SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) & ~FLAGS2_32_BIT_ERROR_CODES);
|
||||
} else {
|
||||
SIVAL(req->out.hdr, HDR_RCLS, NT_STATUS_V(status));
|
||||
SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) | FLAGS2_32_BIT_ERROR_CODES);
|
||||
}
|
||||
|
||||
req_setup_error(req, status);
|
||||
req_send_reply(req);
|
||||
}
|
||||
|
||||
|
@ -1307,7 +1307,7 @@ void reply_trans_generic(struct request_context *req, uint8_t command)
|
||||
status = trans2_backend(req, &trans);
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (NT_STATUS_IS_ERR(status)) {
|
||||
req_reply_error(req, status);
|
||||
return;
|
||||
}
|
||||
@ -1326,6 +1326,10 @@ void reply_trans_generic(struct request_context *req, uint8_t command)
|
||||
uint_t align1 = 1, align2 = (params_left ? 2 : 0);
|
||||
|
||||
req_setup_reply(req, 10 + trans.out.setup_count, 0);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
req_setup_error(req, status);
|
||||
}
|
||||
|
||||
max_bytes = req_max_data(req) - (align1 + align2);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user