diff options
Diffstat (limited to 'source3/rpc_client')
-rw-r--r-- | source3/rpc_client/cli_pipe.c | 206 |
1 files changed, 127 insertions, 79 deletions
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 132bae42e1..12100c3449 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1208,7 +1208,7 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, NTSTATUS ret = NT_STATUS_OK; switch (auth->auth_type) { - case PIPE_AUTH_TYPE_SCHANNEL: + case DCERPC_AUTH_TYPE_SCHANNEL: ret = create_schannel_auth_rpc_bind_req(cli, auth->auth_level, &auth_info); @@ -1217,7 +1217,7 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, } break; - case PIPE_AUTH_TYPE_NTLMSSP: + case DCERPC_AUTH_TYPE_NTLMSSP: ret = create_ntlmssp_auth_rpc_bind_req(cli, auth->auth_level, &auth_info); @@ -1226,7 +1226,11 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, } break; - case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + case DCERPC_AUTH_TYPE_SPNEGO: + if (auth->spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { + /* "Can't" happen. */ + return NT_STATUS_INVALID_INFO_CLASS; + } ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth->auth_level, &auth_info); @@ -1235,7 +1239,7 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, } break; - case PIPE_AUTH_TYPE_KRB5: + case DCERPC_AUTH_TYPE_KRB5: ret = create_krb5_auth_bind_req(cli, auth->auth_level, &auth_info); @@ -1244,7 +1248,7 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, } break; - case PIPE_AUTH_TYPE_NONE: + case DCERPC_AUTH_TYPE_NONE: break; default: @@ -1282,51 +1286,59 @@ static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, #endif switch (cli->auth->auth_level) { - case DCERPC_AUTH_LEVEL_NONE: - case DCERPC_AUTH_LEVEL_CONNECT: - 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; - - case DCERPC_AUTH_LEVEL_INTEGRITY: - case DCERPC_AUTH_LEVEL_PRIVACY: - /* Treat the same for all authenticated rpc requests. */ - switch(cli->auth->auth_type) { - case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: - case PIPE_AUTH_TYPE_NTLMSSP: - *p_auth_len = NTLMSSP_SIG_SIZE; - break; - case PIPE_AUTH_TYPE_SCHANNEL: - *p_auth_len = NL_AUTH_SIGNATURE_SIZE; - break; - default: - smb_panic("bad auth type"); - break; + case DCERPC_AUTH_LEVEL_NONE: + case DCERPC_AUTH_LEVEL_CONNECT: + 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; + + case DCERPC_AUTH_LEVEL_INTEGRITY: + case DCERPC_AUTH_LEVEL_PRIVACY: + /* Treat the same for all authenticated rpc requests. */ + switch(cli->auth->auth_type) { + case DCERPC_AUTH_TYPE_SPNEGO: + switch (cli->auth->spnego_type) { + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + *p_auth_len = NTLMSSP_SIG_SIZE; + break; + default: + smb_panic("bad auth type"); + break; } + case DCERPC_AUTH_TYPE_NTLMSSP: + *p_auth_len = NTLMSSP_SIG_SIZE; + break; + case DCERPC_AUTH_TYPE_SCHANNEL: + *p_auth_len = NL_AUTH_SIGNATURE_SIZE; + break; + default: + smb_panic("bad auth type"); + break; + } - data_space = cli->max_xmit_frag - - DCERPC_REQUEST_LENGTH - - DCERPC_AUTH_TRAILER_LENGTH - - *p_auth_len; + data_space = cli->max_xmit_frag + - DCERPC_REQUEST_LENGTH + - DCERPC_AUTH_TRAILER_LENGTH + - *p_auth_len; - data_len = MIN(data_space, data_left); - *p_ss_padding = 0; - if (data_len % CLIENT_NDR_PADDING_SIZE) { - *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE); - } - *p_frag_len = DCERPC_REQUEST_LENGTH - + data_len + *p_ss_padding - + DCERPC_AUTH_TRAILER_LENGTH - + *p_auth_len; - return data_len; + data_len = MIN(data_space, data_left); + *p_ss_padding = 0; + if (data_len % CLIENT_NDR_PADDING_SIZE) { + *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE); + } + *p_frag_len = DCERPC_REQUEST_LENGTH + + data_len + *p_ss_padding + + DCERPC_AUTH_TRAILER_LENGTH + + *p_auth_len; + return data_len; - default: - smb_panic("bad auth level"); - /* Notreached. */ - return 0; + default: + smb_panic("bad auth level"); + /* Notreached. */ + return 0; } } @@ -1662,7 +1674,7 @@ static bool check_bind_response(const struct dcerpc_bind_ack *r, static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, uint32 rpc_call_id, - enum pipe_auth_type auth_type, + enum dcerpc_AuthType auth_type, enum dcerpc_AuthLevel auth_level, DATA_BLOB *pauth_blob, DATA_BLOB *rpc_out) @@ -1673,7 +1685,7 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, u.auth3._pad = 0; status = dcerpc_push_dcerpc_auth(mem_ctx, - map_pipe_auth_type_to_rpc_auth_type(auth_type), + auth_type, auth_level, 0, /* auth_pad_length */ 1, /* auth_context_id */ @@ -1774,9 +1786,10 @@ struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, return NULL; } - DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n", + DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n", rpccli_pipe_txt(talloc_tos(), cli), (unsigned int)auth->auth_type, + (unsigned int)auth->spnego_type, (unsigned int)auth->auth_level )); state->ev = ev; @@ -1788,7 +1801,7 @@ struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, /* Marshall the outgoing data. */ status = create_rpc_bind_req(state, cli, - &cli->auth, + cli->auth, state->rpc_call_id, &cli->abstract_syntax, &cli->transfer_syntax, @@ -1849,37 +1862,45 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) switch(state->cli->auth->auth_type) { - case PIPE_AUTH_TYPE_NONE: - case PIPE_AUTH_TYPE_SCHANNEL: + case DCERPC_AUTH_TYPE_NONE: + case DCERPC_AUTH_TYPE_SCHANNEL: /* Bind complete. */ tevent_req_done(req); - break; + return; - case PIPE_AUTH_TYPE_NTLMSSP: + 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); } - break; + return; - case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + case DCERPC_AUTH_TYPE_SPNEGO: + if (state->cli->auth->spnego_type != + PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { + break; + } /* 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); } - break; + return; - case PIPE_AUTH_TYPE_KRB5: + case DCERPC_AUTH_TYPE_KRB5: /* */ + break; default: - DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n", - (unsigned int)state->cli->auth->auth_type)); - tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + break; } + + 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)); + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); } static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req, @@ -2163,8 +2184,9 @@ bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16]) { struct cli_state *cli; - if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP) - || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) { + if ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) + || ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO + && rpc_cli->auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16); return true; } @@ -2187,7 +2209,8 @@ NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - result->auth_type = PIPE_AUTH_TYPE_NONE; + result->auth_type = DCERPC_AUTH_TYPE_NONE; + result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE; result->auth_level = DCERPC_AUTH_LEVEL_NONE; result->user_name = talloc_strdup(result, ""); @@ -2208,7 +2231,8 @@ static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth) } static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx, - enum pipe_auth_type auth_type, + enum dcerpc_AuthType auth_type, + enum pipe_auth_type_spnego spnego_type, enum dcerpc_AuthLevel auth_level, const char *domain, const char *username, @@ -2224,6 +2248,7 @@ static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx, } result->auth_type = auth_type; + result->spnego_type = spnego_type; result->auth_level = auth_level; result->user_name = talloc_strdup(result, username); @@ -2298,7 +2323,8 @@ NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain, return NT_STATUS_NO_MEMORY; } - result->auth_type = PIPE_AUTH_TYPE_SCHANNEL; + result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL; + result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE; result->auth_level = auth_level; result->user_name = talloc_strdup(result, ""); @@ -2355,7 +2381,8 @@ static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - result->auth_type = PIPE_AUTH_TYPE_KRB5; + result->auth_type = DCERPC_AUTH_TYPE_KRB5; + result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE; result->auth_level = auth_level; /* @@ -2924,7 +2951,7 @@ NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli, static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli, const struct ndr_syntax_id *interface, enum dcerpc_transport_t transport, - enum pipe_auth_type auth_type, + bool use_spnego, enum dcerpc_AuthLevel auth_level, const char *domain, const char *username, @@ -2933,6 +2960,8 @@ static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli, { struct rpc_pipe_client *result; struct pipe_auth_data *auth; + enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP; + enum pipe_auth_type_spnego spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE; NTSTATUS status; status = cli_rpc_pipe_open(cli, transport, interface, &result); @@ -2940,9 +2969,15 @@ static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli, return status; } - status = rpccli_ntlmssp_bind_data( - result, auth_type, auth_level, domain, username, - password, &auth); + if (use_spnego) { + auth_type = DCERPC_AUTH_TYPE_SPNEGO; + spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP; + } + + status = rpccli_ntlmssp_bind_data(result, + auth_type, spnego_type, auth_level, + domain, username, password, + &auth); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n", nt_errstr(status))); @@ -2987,7 +3022,7 @@ NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli, return cli_rpc_pipe_open_ntlmssp_internal(cli, interface, transport, - PIPE_AUTH_TYPE_NTLMSSP, + false, auth_level, domain, username, @@ -3012,7 +3047,7 @@ NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli, return cli_rpc_pipe_open_ntlmssp_internal(cli, interface, transport, - PIPE_AUTH_TYPE_SPNEGO_NTLMSSP, + true, auth_level, domain, username, @@ -3341,20 +3376,33 @@ NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx, } switch (cli->auth->auth_type) { - case PIPE_AUTH_TYPE_SCHANNEL: + case DCERPC_AUTH_TYPE_SCHANNEL: sk = data_blob_const(a->a_u.schannel_auth->creds->session_key, 16); break; - case PIPE_AUTH_TYPE_NTLMSSP: - case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + case DCERPC_AUTH_TYPE_SPNEGO: + switch (cli->auth->spnego_type) { + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + sk = auth_ntlmssp_get_session_key( + 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); + break; + default: + return NT_STATUS_NO_USER_SESSION_KEY; + } + break; + case DCERPC_AUTH_TYPE_NTLMSSP: sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state); break; - case PIPE_AUTH_TYPE_KRB5: - case PIPE_AUTH_TYPE_SPNEGO_KRB5: + 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); break; - case PIPE_AUTH_TYPE_NONE: + case DCERPC_AUTH_TYPE_NONE: sk = data_blob_const(a->user_session_key.data, a->user_session_key.length); break; |