From 1abcbd70aed327ae5233423ce74662241fa9d21a Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 24 Jul 2010 10:35:25 -0400 Subject: s3-dcerpc: Add next authentication step with gssapi --- source3/librpc/rpc/dcerpc_gssapi.c | 15 ++++++- source3/librpc/rpc/dcerpc_gssapi.h | 1 + source3/rpc_client/cli_pipe.c | 92 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 102 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/librpc/rpc/dcerpc_gssapi.c b/source3/librpc/rpc/dcerpc_gssapi.c index e3e5eedac4..d415369207 100644 --- a/source3/librpc/rpc/dcerpc_gssapi.c +++ b/source3/librpc/rpc/dcerpc_gssapi.c @@ -240,7 +240,7 @@ NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, mech_set.elements = &gse_ctx->gss_mech; gss_maj = gss_acquire_cred(&gss_min, - gse_ctx->server_name, + GSS_C_NO_NAME, GSS_C_INDEFINITE, &mech_set, GSS_C_INITIATE, @@ -296,7 +296,8 @@ NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx, case GSS_S_CONTINUE_NEEDED: /* we will need a third leg */ gse_ctx->more_processing = true; - status = NT_STATUS_MORE_PROCESSING_REQUIRED; + /* status = NT_STATUS_MORE_PROCESSING_REQUIRED; */ + status = NT_STATUS_OK; break; default: DEBUG(0, ("gss_init_sec_context failed with [%s]\n", @@ -368,6 +369,11 @@ done: return errstr; } +bool gse_require_more_processing(struct gse_context *gse_ctx) +{ + return gse_ctx->more_processing; +} + DATA_BLOB gse_get_session_key(struct gse_context *gse_ctx) { return gse_ctx->session_key; @@ -396,6 +402,11 @@ NTSTATUS gse_gen_client_auth_token(TALLOC_CTX *mem_ctx, return NT_STATUS_NOT_IMPLEMENTED; } +bool gse_require_more_processing(struct gse_context *gse_ctx) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + DATA_BLOB gse_get_session_key(struct gse_context *gse_ctx) { return data_blob_null; diff --git a/source3/librpc/rpc/dcerpc_gssapi.h b/source3/librpc/rpc/dcerpc_gssapi.h index c172cacc14..ea44e9e383 100644 --- a/source3/librpc/rpc/dcerpc_gssapi.h +++ b/source3/librpc/rpc/dcerpc_gssapi.h @@ -42,6 +42,7 @@ NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx, DATA_BLOB *token_in, DATA_BLOB *token_out); +bool gse_require_more_processing(struct gse_context *gse_ctx); DATA_BLOB gse_get_session_key(struct gse_context *gse_ctx); #endif /* _CLI_PIPE_GSSAPI_H_ */ diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2d4ee562ad..4a3229d7cc 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1714,10 +1714,11 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, ********************************************************************/ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, + enum dcerpc_AuthType auth_type, + enum dcerpc_AuthLevel auth_level, uint32 rpc_call_id, const struct ndr_syntax_id *abstract, const struct ndr_syntax_id *transfer, - enum dcerpc_AuthLevel auth_level, const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */ DATA_BLOB *rpc_out) { @@ -1725,7 +1726,7 @@ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, NTSTATUS status; status = dcerpc_push_dcerpc_auth(mem_ctx, - DCERPC_AUTH_TYPE_SPNEGO, + auth_type, auth_level, 0, /* auth_pad_length */ 1, /* auth_context_id */ @@ -1766,6 +1767,12 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, DATA_BLOB *credentials); static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq); +static NTSTATUS rpc_bind_next_send(struct tevent_req *req, + struct rpc_pipe_bind_state *state, + DATA_BLOB *credentials); +static NTSTATUS rpc_bind_finish_send(struct tevent_req *req, + struct rpc_pipe_bind_state *state, + DATA_BLOB *credentials); struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, struct event_context *ev, @@ -1828,9 +1835,11 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) subreq, struct tevent_req); struct rpc_pipe_bind_state *state = tevent_req_data( req, struct rpc_pipe_bind_state); + struct pipe_auth_data *pauth = state->cli->auth; DATA_BLOB reply_pdu; struct ncacn_packet *pkt; struct dcerpc_auth auth; + DATA_BLOB auth_token = data_blob_null; NTSTATUS status; status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu); @@ -1915,7 +1924,19 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) break; case DCERPC_AUTH_TYPE_KRB5: - status = NT_STATUS_NOT_IMPLEMENTED; + status = gse_get_client_auth_token(state, + pauth->a_u.gssapi_state, + &auth.credentials, + &auth_token); + if (!NT_STATUS_IS_OK(status)) { + break; + } + + if (gse_require_more_processing(pauth->a_u.gssapi_state)) { + status = rpc_bind_next_send(req, state, &auth_token); + } else { + status = rpc_bind_finish_send(req, state, &auth_token); + } break; default: @@ -2041,10 +2062,11 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req, data_blob_free(&state->rpc_out); status = create_rpc_alter_context(state, + auth->auth_type, + auth->auth_level, state->rpc_call_id, &state->cli->abstract_syntax, &state->cli->transfer_syntax, - auth->auth_level, &client_reply, &state->rpc_out); data_blob_free(&client_reply); @@ -2104,6 +2126,68 @@ static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq) tevent_req_done(req); } +static NTSTATUS rpc_bind_next_send(struct tevent_req *req, + struct rpc_pipe_bind_state *state, + DATA_BLOB *auth_token) +{ + struct pipe_auth_data *auth = state->cli->auth; + struct tevent_req *subreq; + NTSTATUS status; + + /* Now prepare the alter context pdu. */ + data_blob_free(&state->rpc_out); + + status = create_rpc_alter_context(state, + auth->auth_type, + auth->auth_level, + state->rpc_call_id, + &state->cli->abstract_syntax, + &state->cli->transfer_syntax, + auth_token, + &state->rpc_out); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + subreq = rpc_api_pipe_send(state, state->ev, state->cli, + &state->rpc_out, DCERPC_PKT_ALTER_RESP); + if (subreq == NULL) { + return NT_STATUS_NO_MEMORY; + } + tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req); + return NT_STATUS_OK; +} + +static NTSTATUS rpc_bind_finish_send(struct tevent_req *req, + struct rpc_pipe_bind_state *state, + DATA_BLOB *auth_token) +{ + struct pipe_auth_data *auth = state->cli->auth; + struct tevent_req *subreq; + NTSTATUS status; + + /* Now prepare the auth3 context pdu. */ + data_blob_free(&state->rpc_out); + + status = create_rpc_bind_auth3(state, state->cli, + state->rpc_call_id, + auth->auth_type, + auth->auth_level, + auth_token, + &state->rpc_out); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + subreq = rpc_write_send(state, state->ev, state->cli->transport, + state->rpc_out.data, state->rpc_out.length); + if (subreq == NULL) { + return NT_STATUS_NO_MEMORY; + } + tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req); + return NT_STATUS_OK; +} + NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req) { return tevent_req_simple_recv_ntstatus(req); -- cgit