diff options
author | Simo Sorce <idra@samba.org> | 2010-07-21 12:12:58 -0400 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2010-07-28 12:22:31 -0400 |
commit | 866f85e31973de356c3843836d5cacdbdf245e32 (patch) | |
tree | 0bb3766d0b6c8b510eb123713e6f960da290483c | |
parent | 146af48d4887e8fa0c66bf53aa5f204366648478 (diff) | |
download | samba-866f85e31973de356c3843836d5cacdbdf245e32.tar.gz samba-866f85e31973de356c3843836d5cacdbdf245e32.tar.xz samba-866f85e31973de356c3843836d5cacdbdf245e32.zip |
s3-dcerpc: consolidate unmarshalling of dcerpc_auth
-rw-r--r-- | source3/rpc_client/cli_pipe.c | 144 |
1 files changed, 72 insertions, 72 deletions
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index ce34417cd7..9274a1da5e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1764,12 +1764,11 @@ struct rpc_pipe_bind_state { static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq); static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, - struct ncacn_packet *r); + DATA_BLOB *credentials); static void rpc_bind_auth3_write_done(struct tevent_req *subreq); static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req, - struct rpc_pipe_bind_state *state, - struct ncacn_packet *r, - DATA_BLOB *reply_pdu); + struct rpc_pipe_bind_state *state, + DATA_BLOB *credentials); static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq); struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, @@ -1835,6 +1834,7 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) req, struct rpc_pipe_bind_state); DATA_BLOB reply_pdu; struct ncacn_packet *pkt; + struct dcerpc_auth auth; NTSTATUS status; status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu); @@ -1856,6 +1856,40 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag; state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag; + switch(state->cli->auth->auth_type) { + + case DCERPC_AUTH_TYPE_NONE: + case DCERPC_AUTH_TYPE_SCHANNEL: + /* Bind complete. */ + tevent_req_done(req); + return; + + case DCERPC_AUTH_TYPE_NTLMSSP: + case DCERPC_AUTH_TYPE_SPNEGO: + case DCERPC_AUTH_TYPE_KRB5: + /* Paranoid lenght checks */ + if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH + + pkt->auth_length) { + tevent_req_nterror(req, + NT_STATUS_INFO_LENGTH_MISMATCH); + return; + } + /* get auth credentials */ + status = dcerpc_pull_dcerpc_auth(talloc_tos(), + &pkt->u.bind_ack.auth_info, + &auth, false); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to pull dcerpc auth: %s.\n", + nt_errstr(status))); + tevent_req_nterror(req, status); + return; + } + break; + + default: + goto err_out; + } + /* * For authenticated binds we may need to do 3 or 4 leg binds. */ @@ -1870,33 +1904,34 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) case DCERPC_AUTH_TYPE_NTLMSSP: /* Need to send AUTH3 packet - no reply. */ - status = rpc_finish_auth3_bind_send(req, state, pkt); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - } - return; + status = rpc_finish_auth3_bind_send(req, state, + &auth.credentials); + break; case DCERPC_AUTH_TYPE_SPNEGO: if (state->cli->auth->spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { - break; + goto err_out; } /* Need to send alter context request and reply. */ - status = rpc_finish_spnego_ntlmssp_bind_send(req, state, pkt, - &reply_pdu); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - } - return; + status = rpc_finish_spnego_ntlmssp_bind_send(req, state, + &auth.credentials); + break; case DCERPC_AUTH_TYPE_KRB5: - /* */ + status = NT_STATUS_NOT_IMPLEMENTED; break; default: - break; + goto err_out; } + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + } + return; + +err_out: DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n", (unsigned int)state->cli->auth->auth_type, (unsigned int)state->cli->auth->spnego_type)); @@ -1905,32 +1940,17 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, - struct ncacn_packet *r) + DATA_BLOB *credentials) { + struct pipe_auth_data *auth = state->cli->auth; DATA_BLOB client_reply = data_blob_null; - struct dcerpc_auth auth; struct tevent_req *subreq; NTSTATUS status; - if ((r->auth_length == 0) - || (r->frag_length < DCERPC_AUTH_TRAILER_LENGTH - + r->auth_length)) { - return NT_STATUS_INVALID_PARAMETER; - } - - status = dcerpc_pull_dcerpc_auth(talloc_tos(), - &r->u.bind_ack.auth_info, - &auth, false); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to pull dcerpc auth: %s.\n", - nt_errstr(status))); - return status; - } - /* TODO - check auth_type/auth_level match. */ - status = auth_ntlmssp_update(state->cli->auth->a_u.auth_ntlmssp_state, - auth.credentials, &client_reply); + status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state, + *credentials, &client_reply); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server " @@ -1940,11 +1960,12 @@ static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req, data_blob_free(&state->rpc_out); - status = create_rpc_bind_auth3(state, - state->cli, state->rpc_call_id, - state->cli->auth->auth_type, - state->cli->auth->auth_level, - &client_reply, &state->rpc_out); + status = create_rpc_bind_auth3(state, state->cli, + state->rpc_call_id, + auth->auth_type, + auth->auth_level, + &client_reply, + &state->rpc_out); data_blob_free(&client_reply); if (!NT_STATUS_IS_OK(status)) { @@ -1976,44 +1997,23 @@ static void rpc_bind_auth3_write_done(struct tevent_req *subreq) } static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req, - struct rpc_pipe_bind_state *state, - struct ncacn_packet *r, - DATA_BLOB *reply_pdu) + struct rpc_pipe_bind_state *state, + DATA_BLOB *credentials) { + struct pipe_auth_data *auth = state->cli->auth; DATA_BLOB server_ntlm_response = data_blob_null; DATA_BLOB client_reply = data_blob_null; DATA_BLOB tmp_blob = data_blob_null; - struct dcerpc_auth auth_info; - DATA_BLOB auth_blob; struct tevent_req *subreq; NTSTATUS status; - if ((r->auth_length == 0) - || (r->frag_length < DCERPC_AUTH_TRAILER_LENGTH - + r->auth_length)) { - return NT_STATUS_INVALID_PARAMETER; - } - - /* Process the returned NTLMSSP blob first. */ - auth_blob = data_blob_const(reply_pdu->data - + r->frag_length - - DCERPC_AUTH_TRAILER_LENGTH - - r->auth_length, - DCERPC_AUTH_TRAILER_LENGTH - + r->auth_length); - - status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info, false); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n")); - return status; - } - /* * The server might give us back two challenges - tmp_blob is for the * second. */ - if (!spnego_parse_challenge(state, auth_info.credentials, - &server_ntlm_response, &tmp_blob)) { + if (!spnego_parse_challenge(state, *credentials, + &server_ntlm_response, + &tmp_blob)) { data_blob_free(&server_ntlm_response); data_blob_free(&tmp_blob); return NT_STATUS_INVALID_PARAMETER; @@ -2022,8 +2022,8 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req, /* We're finished with the server spnego response and the tmp_blob. */ data_blob_free(&tmp_blob); - status = auth_ntlmssp_update(state->cli->auth->a_u.auth_ntlmssp_state, - server_ntlm_response, &client_reply); + status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state, + server_ntlm_response, &client_reply); /* Finished with the server_ntlm response */ data_blob_free(&server_ntlm_response); @@ -2048,7 +2048,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req, state->rpc_call_id, &state->cli->abstract_syntax, &state->cli->transfer_syntax, - state->cli->auth->auth_level, + auth->auth_level, &client_reply, &state->rpc_out); data_blob_free(&client_reply); |