diff options
author | Stefan Metzmacher <metze@samba.org> | 2015-12-22 21:23:14 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2016-04-12 19:25:32 +0200 |
commit | 7e0b9c2f4bd25853e25a7aa4f3c1773a100be65c (patch) | |
tree | 7b0014cff6979e4a47c5e95be2af7792e541136c /source3/rpc_client | |
parent | e31d8ded956b3ca379fb31480b7f423f1bcda458 (diff) | |
download | samba-7e0b9c2f4bd25853e25a7aa4f3c1773a100be65c.tar.gz |
CVE-2015-5370: s3:rpc_client: disconnect connection on protocol errors
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
Diffstat (limited to 'source3/rpc_client')
-rw-r--r-- | source3/rpc_client/cli_pipe.c | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 00ff5303557..97f49446312 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -936,6 +936,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) state->pkt = talloc(state, struct ncacn_packet); if (!state->pkt) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -945,6 +951,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) state->pkt, !state->endianess); if (!NT_STATUS_IS_OK(status)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); tevent_req_nterror(req, status); return; } @@ -962,6 +974,28 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) (unsigned)state->reply_pdu_offset, nt_errstr(status))); + if (state->pkt->ptype != DCERPC_PKT_FAULT && !NT_STATUS_IS_OK(status)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); return; @@ -986,12 +1020,24 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) "%s\n", state->endianess?"little":"big", state->pkt->drep[0]?"little":"big")); - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); return; } if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) { - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); return; } @@ -999,6 +1045,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) { if (!data_blob_realloc(NULL, &state->reply_pdu, state->reply_pdu_offset + rdata.length)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -1027,6 +1079,14 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) subreq = get_complete_frag_send(state, state->ev, state->cli, &state->incoming_frag); + if (subreq == NULL) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } if (tevent_req_nomem(subreq, req)) { return; } @@ -2275,8 +2335,9 @@ static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx, /* * TODO: do a real async disconnect ... * - * For now the caller needs to free rpc_cli + * For now we do it sync... */ + TALLOC_FREE(hs->rpc_cli->transport); hs->rpc_cli = NULL; tevent_req_done(req); |