X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source3%2Frpc_client%2Fcli_pipe.c;h=85888755069da4b85363ea4dc72827ef036de612;hb=7eaa15af2c5b544946bfb2b8c522ba9677527972;hp=12100c344955ea1682b70cefe47ec09be89674e4;hpb=2463a871776bb4de8653d6a44469d2adb3ec9418;p=kai%2Fsamba.git diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 12100c34495..85888755069 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -30,6 +30,7 @@ #include "rpc_client/cli_netlogon.h" #include "librpc/gen_ndr/ndr_dcerpc.h" #include "librpc/rpc/dcerpc.h" +#include "librpc/rpc/dcerpc_gssapi.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_CLI @@ -947,61 +948,40 @@ static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, Creates krb5 auth bind. ********************************************************************/ -static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli, - enum dcerpc_AuthLevel auth_level, - DATA_BLOB *auth_info) +static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx, + struct pipe_auth_data *auth, + DATA_BLOB *auth_info) { -#ifdef HAVE_KRB5 - int ret; + DATA_BLOB in_token = data_blob_null; + DATA_BLOB auth_token = data_blob_null; NTSTATUS status; - struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth; - DATA_BLOB tkt = data_blob_null; - DATA_BLOB tkt_wrapped = data_blob_null; - - DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n", - a->service_principal )); - - /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */ - - ret = cli_krb5_get_ticket(a, a->service_principal, 0, - &tkt, &a->session_key, - AP_OPTS_MUTUAL_REQUIRED, NULL, - NULL, NULL); - if (ret) { - DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s " - "failed with %s\n", - a->service_principal, - error_message(ret) )); - - data_blob_free(&tkt); - return NT_STATUS_INVALID_PARAMETER; + /* Negotiate the initial auth token */ + status = gse_get_client_auth_token(mem_ctx, + auth->a_u.gssapi_state, + &in_token, + &auth_token); + if (!NT_STATUS_IS_OK(status)) { + return status; } - /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(talloc_tos(), tkt, TOK_ID_KRB_AP_REQ); - - data_blob_free(&tkt); - - status = dcerpc_push_dcerpc_auth(cli, - DCERPC_AUTH_TYPE_KRB5, - auth_level, + status = dcerpc_push_dcerpc_auth(mem_ctx, + auth->auth_type, + auth->auth_level, 0, /* auth_pad_length */ 1, /* auth_context_id */ - &tkt_wrapped, + &auth_token, auth_info); if (!NT_STATUS_IS_OK(status)) { - data_blob_free(&tkt_wrapped); + data_blob_free(&auth_token); return status; } - DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n")); - dump_data(5, tkt_wrapped.data, tkt_wrapped.length); + DEBUG(5, ("Created GSS Authentication Token:\n")); + dump_data(5, auth_token.data, auth_token.length); + data_blob_free(&auth_token); return NT_STATUS_OK; -#else - return NT_STATUS_INVALID_PARAMETER; -#endif } /******************************************************************* @@ -1240,9 +1220,7 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, break; case DCERPC_AUTH_TYPE_KRB5: - ret = create_krb5_auth_bind_req(cli, - auth->auth_level, - &auth_info); + ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_info); if (!NT_STATUS_IS_OK(ret)) { return ret; } @@ -1271,32 +1249,34 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, work out any sign/seal padding length. ********************************************************************/ -static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, - uint32 data_left, - uint16 *p_frag_len, - uint16 *p_auth_len, - uint32 *p_ss_padding) +static NTSTATUS calculate_data_len_tosend(struct rpc_pipe_client *cli, + uint32_t data_left, + uint32_t *data_to_send, + uint16_t *p_frag_len, + uint16_t *p_auth_len, + uint32_t *p_ss_padding) { - uint32 data_space, data_len; - -#if 0 - if ((data_left > 0) && (sys_random() % 2)) { - data_left = MAX(data_left/2, 1); - } -#endif + uint32_t data_space, data_len; + size_t max_len; switch (cli->auth->auth_level) { case DCERPC_AUTH_LEVEL_NONE: case DCERPC_AUTH_LEVEL_CONNECT: + case DCERPC_AUTH_LEVEL_PACKET: data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH; data_len = MIN(data_space, data_left); *p_ss_padding = 0; *p_auth_len = 0; *p_frag_len = DCERPC_REQUEST_LENGTH + data_len; - return data_len; + *data_to_send = data_len; + return NT_STATUS_OK; case DCERPC_AUTH_LEVEL_INTEGRITY: case DCERPC_AUTH_LEVEL_PRIVACY: + max_len = cli->max_xmit_frag + - DCERPC_REQUEST_LENGTH + - DCERPC_AUTH_TRAILER_LENGTH; + /* Treat the same for all authenticated rpc requests. */ switch(cli->auth->auth_type) { case DCERPC_AUTH_TYPE_SPNEGO: @@ -1304,9 +1284,11 @@ static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: *p_auth_len = NTLMSSP_SIG_SIZE; break; - default: - smb_panic("bad auth type"); + case PIPE_AUTH_TYPE_SPNEGO_KRB5: + *p_auth_len = 0; /* TODO */ break; + default: + return NT_STATUS_INVALID_PARAMETER; } case DCERPC_AUTH_TYPE_NTLMSSP: *p_auth_len = NTLMSSP_SIG_SIZE; @@ -1314,15 +1296,18 @@ static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, case DCERPC_AUTH_TYPE_SCHANNEL: *p_auth_len = NL_AUTH_SIGNATURE_SIZE; break; - default: - smb_panic("bad auth type"); + case DCERPC_AUTH_TYPE_KRB5: + *p_auth_len = gse_get_signature_length( + cli->auth->a_u.gssapi_state, + (cli->auth->auth_level == + DCERPC_AUTH_LEVEL_PRIVACY), + max_len); break; + default: + return NT_STATUS_INVALID_PARAMETER; } - data_space = cli->max_xmit_frag - - DCERPC_REQUEST_LENGTH - - DCERPC_AUTH_TRAILER_LENGTH - - *p_auth_len; + data_space = max_len - *p_auth_len; data_len = MIN(data_space, data_left); *p_ss_padding = 0; @@ -1333,13 +1318,14 @@ static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, + data_len + *p_ss_padding + DCERPC_AUTH_TRAILER_LENGTH + *p_auth_len; - return data_len; + *data_to_send = data_len; + return NT_STATUS_OK; default: - smb_panic("bad auth level"); - /* Notreached. */ - return 0; + break; } + + return NT_STATUS_INVALID_PARAMETER; } /******************************************************************* @@ -1437,15 +1423,20 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, uint16_t auth_len; uint16_t frag_len; uint8_t flags = 0; - uint32_t ss_padding; + uint32_t pad_len; uint32_t data_left; NTSTATUS status; union dcerpc_payload u; data_left = state->req_data->length - state->req_data_sent; - data_sent_thistime = calculate_data_len_tosend( - state->cli, data_left, &frag_len, &auth_len, &ss_padding); + status = calculate_data_len_tosend(state->cli, data_left, + &data_sent_thistime, + &frag_len, &auth_len, + &pad_len); + if (!NT_STATUS_IS_OK(status)) { + return status; + } if (state->req_data_sent == 0) { flags = DCERPC_PFC_FLAG_FIRST; @@ -1486,10 +1477,21 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, return NT_STATUS_NO_MEMORY; } - status = dcerpc_add_auth_footer(state->cli->auth, ss_padding, - &state->rpc_out); - if (!NT_STATUS_IS_OK(status)) { - return status; + switch (state->cli->auth->auth_level) { + case DCERPC_AUTH_LEVEL_NONE: + case DCERPC_AUTH_LEVEL_CONNECT: + case DCERPC_AUTH_LEVEL_PACKET: + break; + case DCERPC_AUTH_LEVEL_INTEGRITY: + case DCERPC_AUTH_LEVEL_PRIVACY: + status = dcerpc_add_auth_footer(state->cli->auth, pad_len, + &state->rpc_out); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + break; + default: + return NT_STATUS_INVALID_PARAMETER; } state->req_data_sent += data_sent_thistime; @@ -1718,10 +1720,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) { @@ -1729,7 +1732,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 */ @@ -1764,13 +1767,18 @@ 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); +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, @@ -1833,8 +1841,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); @@ -1856,6 +1867,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 +1915,46 @@ 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); + status = rpc_finish_spnego_ntlmssp_bind_send(req, state, + &auth.credentials); + break; + + case DCERPC_AUTH_TYPE_KRB5: + status = gse_get_client_auth_token(state, + pauth->a_u.gssapi_state, + &auth.credentials, + &auth_token); if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + break; } - return; - case DCERPC_AUTH_TYPE_KRB5: - /* */ + 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: - 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 +1963,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 +1983,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 +2020,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 +2045,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); @@ -2045,10 +2068,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, - state->cli->auth->auth_level, &client_reply, &state->rpc_out); data_blob_free(&client_reply); @@ -2108,6 +2132,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); @@ -2351,74 +2437,6 @@ NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain, return NT_STATUS_NO_MEMORY; } -#ifdef HAVE_KRB5 -static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth) -{ - data_blob_free(&auth->session_key); - return 0; -} -#endif - -static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx, - enum dcerpc_AuthLevel auth_level, - const char *service_princ, - const char *username, - const char *password, - struct pipe_auth_data **presult) -{ -#ifdef HAVE_KRB5 - struct pipe_auth_data *result; - - if ((username != NULL) && (password != NULL)) { - int ret = kerberos_kinit_password(username, password, 0, NULL); - if (ret != 0) { - return NT_STATUS_ACCESS_DENIED; - } - } - - result = talloc(mem_ctx, struct pipe_auth_data); - if (result == NULL) { - return NT_STATUS_NO_MEMORY; - } - - result->auth_type = DCERPC_AUTH_TYPE_KRB5; - result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE; - result->auth_level = auth_level; - - /* - * Username / domain need fixing! - */ - result->user_name = talloc_strdup(result, ""); - result->domain = talloc_strdup(result, ""); - if ((result->user_name == NULL) || (result->domain == NULL)) { - goto fail; - } - - result->a_u.kerberos_auth = TALLOC_ZERO_P( - result, struct kerberos_auth_struct); - if (result->a_u.kerberos_auth == NULL) { - goto fail; - } - talloc_set_destructor(result->a_u.kerberos_auth, - cli_auth_kerberos_data_destructor); - - result->a_u.kerberos_auth->service_principal = talloc_strdup( - result, service_princ); - if (result->a_u.kerberos_auth->service_principal == NULL) { - goto fail; - } - - *presult = result; - return NT_STATUS_OK; - - fail: - TALLOC_FREE(result); - return NT_STATUS_NO_MEMORY; -#else - return NT_STATUS_NOT_SUPPORTED; -#endif -} - /** * Create an rpc pipe client struct, connecting to a tcp port. */ @@ -3319,26 +3337,29 @@ NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli, NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli, const struct ndr_syntax_id *interface, + enum dcerpc_transport_t transport, enum dcerpc_AuthLevel auth_level, - const char *service_princ, + const char *server, const char *username, const char *password, struct rpc_pipe_client **presult) { -#ifdef HAVE_KRB5 +#ifdef HAVE_GSSAPI_H struct rpc_pipe_client *result; struct pipe_auth_data *auth; NTSTATUS status; - status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result); + status = cli_rpc_pipe_open(cli, transport, interface, &result); if (!NT_STATUS_IS_OK(status)) { return status; } - status = rpccli_kerberos_bind_data(result, auth_level, service_princ, - username, password, &auth); + status = gse_init_client(result, DCERPC_AUTH_TYPE_KRB5, auth_level, + NULL, server, "cifs", username, password, + GSS_C_DCE_STYLE, &auth); + if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n", + DEBUG(0, ("gse_init_client returned %s\n", nt_errstr(status))); TALLOC_FREE(result); return status; @@ -3387,9 +3408,7 @@ NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx, a->a_u.auth_ntlmssp_state); break; case PIPE_AUTH_TYPE_SPNEGO_KRB5: - sk = data_blob_const( - a->a_u.kerberos_auth->session_key.data, - a->a_u.kerberos_auth->session_key.length); + sk = gse_get_session_key(a->a_u.gssapi_state); break; default: return NT_STATUS_NO_USER_SESSION_KEY; @@ -3399,8 +3418,7 @@ NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx, sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state); break; case DCERPC_AUTH_TYPE_KRB5: - sk = data_blob_const(a->a_u.kerberos_auth->session_key.data, - a->a_u.kerberos_auth->session_key.length); + sk = gse_get_session_key(a->a_u.gssapi_state); break; case DCERPC_AUTH_TYPE_NONE: sk = data_blob_const(a->user_session_key.data,