summaryrefslogtreecommitdiff
path: root/source3/rpc_client/cli_pipe_schannel.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2013-09-11 10:06:41 +0200
committerStefan Metzmacher <metze@samba.org>2014-01-07 12:47:10 +0100
commit94caf7e190563423914b653d0c2fc4a4abf1f899 (patch)
tree186e0424509bc0517ca7c474e3c044172d3e87a8 /source3/rpc_client/cli_pipe_schannel.c
parent3a89eee03a95d4b142bf0830f40debc75bfa2e26 (diff)
downloadsamba-94caf7e190563423914b653d0c2fc4a4abf1f899.tar.gz
s3:rpc_client: use rpccli_{create,setup}_netlogon_creds() in cli_rpc_pipe_open_schannel()
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source3/rpc_client/cli_pipe_schannel.c')
-rw-r--r--source3/rpc_client/cli_pipe_schannel.c162
1 files changed, 66 insertions, 96 deletions
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;
-}