1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

s3-dcerpc: Pull packet in the caller, before validation

This commit is contained in:
Simo Sorce 2010-08-02 10:03:04 -04:00
parent 558320cf58
commit 72a0098415
2 changed files with 38 additions and 31 deletions

View File

@ -93,6 +93,7 @@ NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
* elements
* @param blob The blob of data to decode
* @param r An empty ncacn_packet, must not be NULL
* @param bigendian Whether the packet is bignedian encoded
*
* @return a NTSTATUS error code
*/

View File

@ -380,21 +380,10 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
DATA_BLOB *rdata,
DATA_BLOB *reply_pdu)
{
struct dcerpc_response *r;
NTSTATUS ret = NT_STATUS_OK;
size_t pad_len = 0;
ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt, false);
if (!NT_STATUS_IS_OK(ret)) {
return ret;
}
if (pdu->length != pkt->frag_length) {
DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
(unsigned int)pdu->length,
(unsigned int)pkt->frag_length));
return NT_STATUS_INVALID_PARAMETER;
}
/*
* Point the return values at the real data including the RPC
* header. Just in case the caller wants it.
@ -406,38 +395,39 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
case DCERPC_PKT_ALTER_RESP:
case DCERPC_PKT_BIND_ACK:
/* Alter context and bind ack share the same packet definitions. */
/* Client code never receives this kind of packets */
break;
case DCERPC_PKT_RESPONSE:
r = &pkt->u.response;
/* Here's where we deal with incoming sign/seal. */
ret = dcerpc_check_auth(cli->auth, pkt,
&pkt->u.response.stub_and_verifier,
&r->stub_and_verifier,
DCERPC_RESPONSE_LENGTH,
pdu, &pad_len);
if (!NT_STATUS_IS_OK(ret)) {
return ret;
}
if (pdu->length < DCERPC_RESPONSE_LENGTH + pad_len) {
if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
return NT_STATUS_BUFFER_TOO_SMALL;
}
/* Point the return values at the NDR data. */
rdata->data = pdu->data + DCERPC_RESPONSE_LENGTH;
rdata->data = r->stub_and_verifier.data;
if (pkt->auth_length) {
/* We've already done integer wrap tests in
* dcerpc_check_auth(). */
rdata->length = pdu->length
- DCERPC_RESPONSE_LENGTH
rdata->length = r->stub_and_verifier.length
- pad_len
- DCERPC_AUTH_TRAILER_LENGTH
- pkt->auth_length;
} else {
rdata->length = pdu->length - DCERPC_RESPONSE_LENGTH;
rdata->length = r->stub_and_verifier.length;
}
DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
@ -452,13 +442,12 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
*/
if ((reply_pdu->length == 0) &&
pkt->u.response.alloc_hint &&
(pkt->u.response.alloc_hint < 15*1024*1024)) {
r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
if (!data_blob_realloc(mem_ctx, reply_pdu,
pkt->u.response.alloc_hint)) {
r->alloc_hint)) {
DEBUG(0, ("reply alloc hint %d too "
"large to allocate\n",
(int)pkt->u.response.alloc_hint));
(int)r->alloc_hint));
return NT_STATUS_NO_MEMORY;
}
}
@ -478,7 +467,7 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
"code %s received from %s!\n",
dcerpc_errstr(talloc_tos(),
pkt->u.fault.status),
rpccli_pipe_txt(talloc_tos(), cli)));
rpccli_pipe_txt(talloc_tos(), cli)));
if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
return NT_STATUS_UNSUCCESSFUL;
@ -488,17 +477,17 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
default:
DEBUG(0, ("Unknown packet type %u received from %s!\n",
(unsigned int)pkt->ptype,
rpccli_pipe_txt(talloc_tos(), cli)));
(unsigned int)pkt->ptype,
rpccli_pipe_txt(talloc_tos(), cli)));
return NT_STATUS_INVALID_INFO_CLASS;
}
if (pkt->ptype != expected_pkt_type) {
DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
"got an unexpected RPC packet type - %u, not %u\n",
rpccli_pipe_txt(talloc_tos(), cli),
pkt->ptype,
expected_pkt_type));
rpccli_pipe_txt(talloc_tos(), cli),
pkt->ptype,
expected_pkt_type));
return NT_STATUS_INVALID_INFO_CLASS;
}
@ -508,8 +497,8 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
"setting fragment first/last ON.\n"));
DEBUG(5, ("cli_pipe_validate_current_pdu: bug in server "
"(AS/U?), setting fragment first/last ON.\n"));
pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST |
DCERPC_PFC_FLAG_LAST;
}
@ -840,6 +829,23 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
return;
}
status = dcerpc_pull_ncacn_packet(state,
&state->incoming_frag,
state->pkt,
!state->endianess);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return;
}
if (state->incoming_frag.length != state->pkt->frag_length) {
DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
(unsigned int)state->incoming_frag.length,
(unsigned int)state->pkt->frag_length));
tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
status = cli_pipe_validate_current_pdu(state,
state->cli, state->pkt,
&state->incoming_frag,