From 94caf7e190563423914b653d0c2fc4a4abf1f899 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 11 Sep 2013 10:06:41 +0200 Subject: s3:rpc_client: use rpccli_{create,setup}_netlogon_creds() in cli_rpc_pipe_open_schannel() Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett --- source3/rpc_client/cli_pipe.h | 7 -- source3/rpc_client/cli_pipe_schannel.c | 162 ++++++++++++++------------------- 2 files changed, 66 insertions(+), 103 deletions(-) (limited to 'source3/rpc_client') diff --git a/source3/rpc_client/cli_pipe.h b/source3/rpc_client/cli_pipe.h index 2a10a810bbb..51bf1821a3f 100644 --- a/source3/rpc_client/cli_pipe.h +++ b/source3/rpc_client/cli_pipe.h @@ -111,13 +111,6 @@ NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, DATA_BLOB *session_key); -/* The following definitions come from rpc_client/cli_pipe_schannel.c */ - -NTSTATUS get_schannel_session_key(struct cli_state *cli, - const char *domain, - uint32 *pneg_flags, - struct rpc_pipe_client **presult); - #endif /* _CLI_PIPE_H */ /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */ diff --git a/source3/rpc_client/cli_pipe_schannel.c b/source3/rpc_client/cli_pipe_schannel.c index 8f9161fc5ae..1fcf62ef867 100644 --- a/source3/rpc_client/cli_pipe_schannel.c +++ b/source3/rpc_client/cli_pipe_schannel.c @@ -23,67 +23,15 @@ #include "../libcli/auth/schannel.h" #include "rpc_client/cli_netlogon.h" #include "rpc_client/cli_pipe.h" -#include "librpc/gen_ndr/ndr_dcerpc.h" #include "librpc/rpc/dcerpc.h" #include "passdb.h" #include "libsmb/libsmb.h" -#include "auth/gensec/gensec.h" #include "../libcli/smb/smbXcli_base.h" +#include "libcli/auth/netlogon_creds_cli.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_CLI - -/**************************************************************************** - Get a the schannel session key out of an already opened netlogon pipe. - ****************************************************************************/ -static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe, - struct cli_state *cli, - const char *domain, - uint32 *pneg_flags) -{ - enum netr_SchannelType sec_chan_type = 0; - unsigned char machine_pwd[16]; - const char *machine_account; - NTSTATUS status; - - /* Get the machine account credentials from secrets.tdb. */ - if (!get_trust_pw_hash(domain, machine_pwd, &machine_account, - &sec_chan_type)) - { - DEBUG(0, ("get_schannel_session_key: could not fetch " - "trust account password for domain '%s'\n", - domain)); - return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - } - - status = rpccli_netlogon_setup_creds(netlogon_pipe, - smbXcli_conn_remote_name(cli->conn), /* server name */ - domain, /* domain */ - lp_netbios_name(), /* client name */ - machine_account, /* machine account name */ - machine_pwd, - sec_chan_type, - pneg_flags); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("get_schannel_session_key_common: " - "rpccli_netlogon_setup_creds failed with result %s " - "to server %s, domain %s, machine account %s.\n", - nt_errstr(status), smbXcli_conn_remote_name(cli->conn), domain, - machine_account )); - return status; - } - - if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) { - DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n", - smbXcli_conn_remote_name(cli->conn))); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - - return NT_STATUS_OK; -} - /**************************************************************************** Open a named pipe to an SMB server and bind using schannel (bind type 68). Fetch the session key ourselves using a temporary netlogon pipe. @@ -96,63 +44,85 @@ NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli, const char *domain, struct rpc_pipe_client **presult) { - uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | - NETLOGON_NEG_SUPPORTS_AES; - struct rpc_pipe_client *netlogon_pipe = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + struct messaging_context *msg_ctx = NULL; + const char *dc_name = smbXcli_conn_remote_name(cli->conn); struct rpc_pipe_client *result = NULL; NTSTATUS status; + struct netlogon_creds_cli_context *netlogon_creds = NULL; + struct netlogon_creds_CredentialState *creds = NULL; + uint32_t netlogon_flags = 0; + enum netr_SchannelType sec_chan_type = 0; + const char *_account_name = NULL; + const char *account_name = NULL; + struct samr_Password current_nt_hash; + struct samr_Password *previous_nt_hash = NULL; + bool ok; + + ok = get_trust_pw_hash(domain, + current_nt_hash.hash, + &_account_name, + &sec_chan_type); + if (!ok) { + TALLOC_FREE(frame); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + account_name = talloc_asprintf(frame, "%s$", _account_name); + if (account_name == NULL) { + SAFE_FREE(previous_nt_hash); + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + + status = rpccli_create_netlogon_creds(dc_name, + domain, + account_name, + sec_chan_type, + msg_ctx, + frame, + &netlogon_creds); + if (!NT_STATUS_IS_OK(status)) { + SAFE_FREE(previous_nt_hash); + TALLOC_FREE(frame); + return status; + } - status = get_schannel_session_key(cli, domain, &neg_flags, - &netlogon_pipe); + status = rpccli_setup_netlogon_creds(cli, + netlogon_creds, + false, /* force_reauth */ + current_nt_hash, + previous_nt_hash); + SAFE_FREE(previous_nt_hash); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session " - "key from server %s for domain %s.\n", - smbXcli_conn_remote_name(cli->conn), domain )); + TALLOC_FREE(frame); return status; } + status = netlogon_creds_cli_get(netlogon_creds, + frame, + &creds); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + netlogon_flags = creds->negotiate_flags; + TALLOC_FREE(creds); + + if (!(netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) { + TALLOC_FREE(frame); + return NT_STATUS_DOWNGRADE_DETECTED; + } + status = cli_rpc_pipe_open_schannel_with_key( cli, table, transport, domain, - netlogon_pipe->netlogon_creds, + netlogon_creds, &result); - /* Now we've bound using the session key we can close the netlog pipe. */ - TALLOC_FREE(netlogon_pipe); - if (NT_STATUS_IS_OK(status)) { *presult = result; } + TALLOC_FREE(frame); return status; } - -/**************************************************************************** - Open a netlogon pipe and get the schannel session key. - Now exposed to external callers. - ****************************************************************************/ - - -NTSTATUS get_schannel_session_key(struct cli_state *cli, - const char *domain, - uint32 *pneg_flags, - struct rpc_pipe_client **presult) -{ - struct rpc_pipe_client *netlogon_pipe = NULL; - NTSTATUS status; - - status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon, - &netlogon_pipe); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = get_schannel_session_key_common(netlogon_pipe, cli, domain, - pneg_flags); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(netlogon_pipe); - return status; - } - - *presult = netlogon_pipe; - return NT_STATUS_OK; -} -- cgit v1.2.1