From 05dc21ca9446f64c46cda8a6637a95ce9d699f91 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 20 Jul 2010 13:26:36 -0400 Subject: [PATCH] s3-dcerpc: Use dcerpc_AuthType in pipe_auth_data (cherry picked from commit 2463a871776bb4de8653d6a44469d2adb3ec9418) --- source3/include/ntdomain.h | 10 +- source3/include/proto.h | 1 - source3/librpc/rpc/dcerpc_helpers.c | 33 +++--- source3/librpc/rpc/rpc_common.c | 33 ------ source3/rpc_client/cli_pipe.c | 206 ++++++++++++++++++++++-------------- source3/rpc_server/rpc_handles.c | 3 +- source3/rpc_server/srv_lsa_nt.c | 4 +- source3/rpc_server/srv_netlog_nt.c | 6 +- source3/rpc_server/srv_pipe.c | 47 ++++---- source3/rpc_server/srv_samr_nt.c | 4 +- source3/rpcclient/rpcclient.c | 130 +++++++++++++---------- 11 files changed, 262 insertions(+), 215 deletions(-) diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index 5801fd3c326..c843bc9aea6 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -93,8 +93,11 @@ typedef struct pipe_rpc_fns { * Can't keep in sync with wire values as spnego wraps different auth methods. */ -enum pipe_auth_type { PIPE_AUTH_TYPE_NONE = 0, PIPE_AUTH_TYPE_NTLMSSP, PIPE_AUTH_TYPE_SCHANNEL, - PIPE_AUTH_TYPE_SPNEGO_NTLMSSP, PIPE_AUTH_TYPE_KRB5, PIPE_AUTH_TYPE_SPNEGO_KRB5 }; +enum pipe_auth_type_spnego { + PIPE_AUTH_TYPE_SPNEGO_NONE = 0, + PIPE_AUTH_TYPE_SPNEGO_NTLMSSP, + PIPE_AUTH_TYPE_SPNEGO_KRB5 +}; /* auth state for krb5. */ struct kerberos_auth_struct { @@ -105,7 +108,8 @@ struct kerberos_auth_struct { /* auth state for all bind types. */ struct pipe_auth_data { - enum pipe_auth_type auth_type; /* switch for union below. */ + enum dcerpc_AuthType auth_type; + enum pipe_auth_type_spnego spnego_type; enum dcerpc_AuthLevel auth_level; union { diff --git a/source3/include/proto.h b/source3/include/proto.h index ed826bcd7eb..b001c1e77e2 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4466,7 +4466,6 @@ const struct ndr_interface_table *get_iface_from_syntax( const struct ndr_syntax_id *syntax); const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *syntax); -enum dcerpc_AuthType map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type); struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, struct event_context *ev, diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index fc9915cf084..be076d86453 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -383,13 +383,12 @@ static NTSTATUS add_schannel_auth_footer(struct schannel_state *sas, NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, size_t pad_len, DATA_BLOB *rpc_out) { - enum dcerpc_AuthType auth_type; char pad[CLIENT_NDR_PADDING_SIZE] = { 0, }; DATA_BLOB auth_info; DATA_BLOB auth_blob; NTSTATUS status; - if (auth->auth_type == PIPE_AUTH_TYPE_NONE) { + if (auth->auth_type == DCERPC_AUTH_TYPE_NONE) { return NT_STATUS_OK; } @@ -400,14 +399,12 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, } } - auth_type = map_pipe_auth_type_to_rpc_auth_type(auth->auth_type); - /* marshall the dcerpc_auth with an actually empty auth_blob. * This is needed because the ntmlssp signature includes the * auth header. We will append the actual blob later. */ auth_blob = data_blob_null; status = dcerpc_push_dcerpc_auth(rpc_out->data, - auth_type, + auth->auth_type, auth->auth_level, pad_len, 1 /* context id. */, @@ -428,16 +425,20 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, /* Generate any auth sign/seal and add the auth footer. */ switch (auth->auth_type) { - case PIPE_AUTH_TYPE_NONE: + case DCERPC_AUTH_TYPE_NONE: status = NT_STATUS_OK; break; - case PIPE_AUTH_TYPE_NTLMSSP: - case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + case DCERPC_AUTH_TYPE_SPNEGO: + if (auth->spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { + return NT_STATUS_INVALID_PARAMETER; + } + /* fall thorugh */ + case DCERPC_AUTH_TYPE_NTLMSSP: status = add_ntlmssp_auth_footer(auth->a_u.auth_ntlmssp_state, auth->auth_level, rpc_out); break; - case PIPE_AUTH_TYPE_SCHANNEL: + case DCERPC_AUTH_TYPE_SCHANNEL: status = add_schannel_auth_footer(auth->a_u.schannel_auth, auth->auth_level, rpc_out); @@ -530,11 +531,17 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, raw_pkt->length - auth_info.credentials.length); switch (auth->auth_type) { - case PIPE_AUTH_TYPE_NONE: + case DCERPC_AUTH_TYPE_NONE: return NT_STATUS_OK; - case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: - case PIPE_AUTH_TYPE_NTLMSSP: + case DCERPC_AUTH_TYPE_SPNEGO: + if (auth->spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { + DEBUG(0, ("Currently only NTLMSSP is supported " + "with SPNEGO\n")); + return NT_STATUS_INVALID_PARAMETER; + } + /* fall through */ + case DCERPC_AUTH_TYPE_NTLMSSP: DEBUG(10, ("NTLMSSP auth\n")); @@ -575,7 +582,7 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, } break; - case PIPE_AUTH_TYPE_SCHANNEL: + case DCERPC_AUTH_TYPE_SCHANNEL: DEBUG(10, ("SCHANNEL auth\n")); diff --git a/source3/librpc/rpc/rpc_common.c b/source3/librpc/rpc/rpc_common.c index 78b88f7e334..ed0320adf09 100644 --- a/source3/librpc/rpc/rpc_common.c +++ b/source3/librpc/rpc/rpc_common.c @@ -203,36 +203,3 @@ const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx, return result; } -/******************************************************************** - Map internal value to wire value. - ********************************************************************/ - -enum dcerpc_AuthType map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type) -{ - switch (auth_type) { - - case PIPE_AUTH_TYPE_NONE: - return DCERPC_AUTH_TYPE_NONE; - - case PIPE_AUTH_TYPE_NTLMSSP: - return DCERPC_AUTH_TYPE_NTLMSSP; - - case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: - case PIPE_AUTH_TYPE_SPNEGO_KRB5: - return DCERPC_AUTH_TYPE_SPNEGO; - - case PIPE_AUTH_TYPE_SCHANNEL: - return DCERPC_AUTH_TYPE_SCHANNEL; - - case PIPE_AUTH_TYPE_KRB5: - return DCERPC_AUTH_TYPE_KRB5; - - default: - DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe " - "auth type %u\n", - (unsigned int)auth_type )); - break; - } - return -1; -} - diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 24ccfef51c7..b8c03dbda2f 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1209,7 +1209,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); @@ -1218,7 +1218,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); @@ -1227,7 +1227,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); @@ -1236,7 +1240,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); @@ -1245,7 +1249,7 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, } break; - case PIPE_AUTH_TYPE_NONE: + case DCERPC_AUTH_TYPE_NONE: break; default: @@ -1283,51 +1287,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; } } @@ -1663,7 +1675,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) @@ -1674,7 +1686,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 */ @@ -1775,9 +1787,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; @@ -1789,7 +1802,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, @@ -1850,37 +1863,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, @@ -2164,8 +2185,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; } @@ -2188,7 +2210,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, ""); @@ -2209,7 +2232,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, @@ -2225,6 +2249,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); @@ -2299,7 +2324,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, ""); @@ -2356,7 +2382,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; /* @@ -2925,7 +2952,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, @@ -2934,6 +2961,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); @@ -2941,9 +2970,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))); @@ -2988,7 +3023,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, @@ -3013,7 +3048,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, @@ -3342,20 +3377,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; diff --git a/source3/rpc_server/rpc_handles.c b/source3/rpc_server/rpc_handles.c index 57a3cd44eb9..481bb56ee7a 100644 --- a/source3/rpc_server/rpc_handles.c +++ b/source3/rpc_server/rpc_handles.c @@ -321,7 +321,8 @@ bool pipe_access_check(struct pipes_struct *p) if (lp_restrict_anonymous() > 0) { /* schannel, so we must be ok */ - if (p->pipe_bound && (p->auth.auth_type == PIPE_AUTH_TYPE_SCHANNEL)) { + if (p->pipe_bound && + (p->auth.auth_type == DCERPC_AUTH_TYPE_SCHANNEL)) { return True; } diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 7ffdba06cc9..1a0ddb18929 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -1042,7 +1042,7 @@ NTSTATUS _lsa_LookupSids3(struct pipes_struct *p, struct lsa_LookupSids2 q; /* No policy handle on this call. Restrict to crypto connections. */ - if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { + if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n", get_remote_machine_name() )); return NT_STATUS_INVALID_PARAMETER; @@ -1325,7 +1325,7 @@ NTSTATUS _lsa_LookupNames4(struct pipes_struct *p, struct lsa_LookupNames3 q; /* No policy handle on this call. Restrict to crypto connections. */ - if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { + if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n", get_remote_machine_name() )); return NT_STATUS_INVALID_PARAMETER; diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index e7b4718f01f..56b5027958a 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -961,7 +961,7 @@ static NTSTATUS schannel_check_required(struct pipe_auth_data *auth_info, const char *computer_name, bool integrity, bool privacy) { - if (auth_info && auth_info->auth_type == PIPE_AUTH_TYPE_SCHANNEL) { + if (auth_info && auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) { if (!privacy && !integrity) { return NT_STATUS_OK; } @@ -1419,7 +1419,7 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p, memcpy(pipe_session_key, creds->session_key, 16); } else { /* Get the pipe session key from the schannel. */ - if ((p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) + if ((p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) || (p->auth.a_u.schannel_auth == NULL)) { return NT_STATUS_INVALID_HANDLE; } @@ -1535,7 +1535,7 @@ NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p, } /* Only allow this if the pipe is protected. */ - if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { + if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { DEBUG(0,("_netr_LogonSamLogonEx: client %s not using schannel for netlogon\n", get_remote_machine_name() )); return NT_STATUS_INVALID_PARAMETER; diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ae6c12710ef..6f79d3c8157 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -112,8 +112,6 @@ static DATA_BLOB generic_session_key(void) ********************************************************************/ static bool create_next_packet(struct pipes_struct *p, - enum dcerpc_AuthType auth_type, - enum dcerpc_AuthLevel auth_level, size_t auth_length, size_t *_pad_len) { @@ -225,8 +223,6 @@ static bool create_next_packet(struct pipes_struct *p, bool create_next_pdu(struct pipes_struct *p) { - enum dcerpc_AuthType auth_type = - map_pipe_auth_type_to_rpc_auth_type(p->auth.auth_type); size_t auth_len = 0; size_t pad_len = 0; NTSTATUS status; @@ -255,12 +251,18 @@ bool create_next_pdu(struct pipes_struct *p) case DCERPC_AUTH_LEVEL_PRIVACY: switch(p->auth.auth_type) { - case PIPE_AUTH_TYPE_NTLMSSP: - case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + case DCERPC_AUTH_TYPE_NTLMSSP: + auth_len = NTLMSSP_SIG_SIZE; + break; + case DCERPC_AUTH_TYPE_SPNEGO: + if (p->auth.spnego_type != + PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { + goto err_out; + } auth_len = NTLMSSP_SIG_SIZE; break; - case PIPE_AUTH_TYPE_SCHANNEL: + case DCERPC_AUTH_TYPE_SCHANNEL: auth_len = NL_AUTH_SIGNATURE_SIZE; break; @@ -274,9 +276,7 @@ bool create_next_pdu(struct pipes_struct *p) goto err_out; } - ret = create_next_packet(p, auth_type, - p->auth.auth_level, - auth_len, &pad_len); + ret = create_next_packet(p, auth_len, &pad_len); if (!ret) { return false; } @@ -506,7 +506,8 @@ static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt) free_pipe_auth_data(&p->auth); p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; - p->auth.auth_type = PIPE_AUTH_TYPE_NONE; + p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; + p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE; p->pipe_bound = False; return True; @@ -709,10 +710,8 @@ static bool pipe_spnego_auth_bind_negotiate(struct pipes_struct *p, return ret; } - if (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP && p->auth.a_u.auth_ntlmssp_state) { - /* Free any previous auth type. */ - free_pipe_auth_data(&p->auth); - } + /* Free any previous auth type. */ + free_pipe_auth_data(&p->auth); if (!got_kerberos_mechanism) { /* Initialize the NTLM engine. */ @@ -770,7 +769,8 @@ static bool pipe_spnego_auth_bind_negotiate(struct pipes_struct *p, p->auth.a_u.auth_ntlmssp_state = a; p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data; - p->auth.auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP; + p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO; + p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP; data_blob_free(&secblob); data_blob_free(&chal); @@ -808,7 +808,8 @@ static bool pipe_spnego_auth_bind_continue(struct pipes_struct *p, * NB. If we've negotiated down from krb5 to NTLMSSP we'll currently * fail here as 'a' == NULL. */ - if (p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) { + if (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO || + p->auth.spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) { DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n")); goto err; } @@ -965,7 +966,7 @@ static bool pipe_schannel_auth_bind(struct pipes_struct *p, /* We're finished with this bind - no more packets. */ p->auth.auth_data_free_func = &free_pipe_schannel_auth_data; - p->auth.auth_type = PIPE_AUTH_TYPE_SCHANNEL; + p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL; p->pipe_bound = True; @@ -1026,7 +1027,7 @@ static bool pipe_ntlmssp_auth_bind(struct pipes_struct *p, p->auth.a_u.auth_ntlmssp_state = a; p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data; - p->auth.auth_type = PIPE_AUTH_TYPE_NTLMSSP; + p->auth.auth_type = DCERPC_AUTH_TYPE_NTLMSSP; DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth started\n")); @@ -1223,7 +1224,8 @@ bool api_pipe_bind_req(struct pipes_struct *p, struct ncacn_packet *pkt) if (auth_type == DCERPC_AUTH_TYPE_NONE) { /* Unauthenticated bind request. */ /* We're finished - no more packets. */ - p->auth.auth_type = PIPE_AUTH_TYPE_NONE; + p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; + p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE; /* We must set the pipe auth_level here also. */ p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; p->pipe_bound = True; @@ -1571,8 +1573,9 @@ bool api_pipe_request(struct pipes_struct *p, struct ncacn_packet *pkt) PIPE_RPC_FNS *pipe_fns; if (p->pipe_bound && - ((p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) || - (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { + ((p->auth.auth_type == DCERPC_AUTH_TYPE_NTLMSSP) || + ((p->auth.auth_type == DCERPC_AUTH_TYPE_SPNEGO) && + (p->auth.spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)))) { if(!become_authenticated_pipe_user(p)) { data_blob_free(&p->out_data.rdata); return False; diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 1394563e8a2..e101240dbee 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -2771,7 +2771,9 @@ static NTSTATUS get_user_info_18(struct pipes_struct *p, goto query; } - if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { + if ((p->auth.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) || + ((p->auth.auth_type == DCERPC_AUTH_TYPE_SPNEGO) && + (p->auth.spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index ff8e9b1cb70..418e4d25e71 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -30,7 +30,8 @@ struct dom_sid domain_sid; -static enum pipe_auth_type pipe_default_auth_type = PIPE_AUTH_TYPE_NONE; +static enum dcerpc_AuthType pipe_default_auth_type = DCERPC_AUTH_TYPE_NONE; +static enum pipe_auth_type_spnego pipe_default_auth_spnego_type = 0; static enum dcerpc_AuthLevel pipe_default_auth_level = DCERPC_AUTH_LEVEL_NONE; static unsigned int timeout = 0; static enum dcerpc_transport_t default_transport = NCACN_NP; @@ -386,7 +387,7 @@ static NTSTATUS cmd_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *type = "NTLMSSP"; pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; - pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP; + pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP; if (argc > 2) { printf("Usage: %s [NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]\n", argv[0]); @@ -396,11 +397,12 @@ static NTSTATUS cmd_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, if (argc == 2) { type = argv[1]; if (strequal(type, "NTLMSSP")) { - pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP; + pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP; } else if (strequal(type, "NTLMSSP_SPNEGO")) { - pipe_default_auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP; + pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO; + pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP; } else if (strequal(type, "SCHANNEL")) { - pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL; + pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL; } else { printf("unknown type %s\n", type); printf("Usage: %s [NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]\n", argv[0]); @@ -419,7 +421,7 @@ static NTSTATUS cmd_seal(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *type = "NTLMSSP"; pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY; - pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP; + pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP; if (argc > 2) { printf("Usage: %s [NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]\n", argv[0]); @@ -429,11 +431,12 @@ static NTSTATUS cmd_seal(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, if (argc == 2) { type = argv[1]; if (strequal(type, "NTLMSSP")) { - pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP; + pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP; } else if (strequal(type, "NTLMSSP_SPNEGO")) { - pipe_default_auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP; + pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO; + pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP; } else if (strequal(type, "SCHANNEL")) { - pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL; + pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL; } else { printf("unknown type %s\n", type); printf("Usage: %s [NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]\n", argv[0]); @@ -483,7 +486,8 @@ static NTSTATUS cmd_none(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { pipe_default_auth_level = DCERPC_AUTH_LEVEL_NONE; - pipe_default_auth_type = PIPE_AUTH_TYPE_NONE; + pipe_default_auth_type = DCERPC_AUTH_TYPE_NONE; + pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE; return cmd_set_ss_level(); } @@ -493,7 +497,7 @@ static NTSTATUS cmd_schannel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, { d_printf("Setting schannel - sign and seal\n"); pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY; - pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL; + pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL; return cmd_set_ss_level(); } @@ -503,7 +507,7 @@ static NTSTATUS cmd_schannel_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c { d_printf("Setting schannel - sign only\n"); pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; - pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL; + pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL; return cmd_set_ss_level(); } @@ -648,48 +652,58 @@ static NTSTATUS do_cmd(struct cli_state *cli, if ((cmd_entry->interface != NULL) && (cmd_entry->rpc_pipe == NULL)) { switch (pipe_default_auth_type) { - case PIPE_AUTH_TYPE_NONE: - ntresult = cli_rpc_pipe_open_noauth_transport( - cli, default_transport, - cmd_entry->interface, - &cmd_entry->rpc_pipe); - break; - case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: - ntresult = cli_rpc_pipe_open_spnego_ntlmssp( - cli, cmd_entry->interface, - default_transport, - pipe_default_auth_level, - get_cmdline_auth_info_domain(auth_info), - get_cmdline_auth_info_username(auth_info), - get_cmdline_auth_info_password(auth_info), - &cmd_entry->rpc_pipe); - break; - case PIPE_AUTH_TYPE_NTLMSSP: - ntresult = cli_rpc_pipe_open_ntlmssp( - cli, cmd_entry->interface, - default_transport, - pipe_default_auth_level, - get_cmdline_auth_info_domain(auth_info), - get_cmdline_auth_info_username(auth_info), - get_cmdline_auth_info_password(auth_info), - &cmd_entry->rpc_pipe); - break; - case PIPE_AUTH_TYPE_SCHANNEL: - ntresult = cli_rpc_pipe_open_schannel( - cli, cmd_entry->interface, - default_transport, - pipe_default_auth_level, - get_cmdline_auth_info_domain(auth_info), - &cmd_entry->rpc_pipe); - break; - default: - DEBUG(0, ("Could not initialise %s. Invalid " - "auth type %u\n", + case DCERPC_AUTH_TYPE_NONE: + ntresult = cli_rpc_pipe_open_noauth_transport( + cli, default_transport, + cmd_entry->interface, + &cmd_entry->rpc_pipe); + break; + case DCERPC_AUTH_TYPE_SPNEGO: + if (pipe_default_auth_spnego_type != + PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { + DEBUG(0, ("Could not initialise %s. " + "Currently only NTLMSSP is " + "supported for SPNEGO\n", get_pipe_name_from_syntax( - talloc_tos(), - cmd_entry->interface), - pipe_default_auth_type )); + talloc_tos(), + cmd_entry->interface))); return NT_STATUS_UNSUCCESSFUL; + } + ntresult = cli_rpc_pipe_open_spnego_ntlmssp( + cli, cmd_entry->interface, + default_transport, + pipe_default_auth_level, + get_cmdline_auth_info_domain(auth_info), + get_cmdline_auth_info_username(auth_info), + get_cmdline_auth_info_password(auth_info), + &cmd_entry->rpc_pipe); + break; + case DCERPC_AUTH_TYPE_NTLMSSP: + ntresult = cli_rpc_pipe_open_ntlmssp( + cli, cmd_entry->interface, + default_transport, + pipe_default_auth_level, + get_cmdline_auth_info_domain(auth_info), + get_cmdline_auth_info_username(auth_info), + get_cmdline_auth_info_password(auth_info), + &cmd_entry->rpc_pipe); + break; + case DCERPC_AUTH_TYPE_SCHANNEL: + ntresult = cli_rpc_pipe_open_schannel( + cli, cmd_entry->interface, + default_transport, + pipe_default_auth_level, + get_cmdline_auth_info_domain(auth_info), + &cmd_entry->rpc_pipe); + break; + default: + DEBUG(0, ("Could not initialise %s. Invalid " + "auth type %u\n", + get_pipe_name_from_syntax( + talloc_tos(), + cmd_entry->interface), + pipe_default_auth_type )); + return NT_STATUS_UNSUCCESSFUL; } if (!NT_STATUS_IS_OK(ntresult)) { DEBUG(0, ("Could not initialise %s. Error was %s\n", @@ -974,20 +988,22 @@ out_free: if (binding->flags & DCERPC_SIGN) { pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; - pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP; + pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP; } if (binding->flags & DCERPC_SEAL) { pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY; - pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP; + pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP; } if (binding->flags & DCERPC_AUTH_SPNEGO) { - pipe_default_auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP; + pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO; + pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP; } if (binding->flags & DCERPC_AUTH_NTLM) { - pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP; + pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP; } if (binding->flags & DCERPC_AUTH_KRB5) { - pipe_default_auth_type = PIPE_AUTH_TYPE_SPNEGO_KRB5; + pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO; + pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5; } if (get_cmdline_auth_info_use_kerberos(rpcclient_auth_info)) { -- 2.11.4.GIT