From fb42b02c9f75804bc471c1f88fbda28865d9f01e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Dec 2014 09:19:49 +0000 Subject: [PATCH] s3:rpc_client: add cli_rpc_pipe_open_schannel_with_creds() helper function This will simplify the callers and add potential support for SEC_CHAN_DNS_DOMAIN as cli_credentials_get_realm() will return the correct value compared to cli_credentials_get_domain(). Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett --- source3/rpc_client/cli_pipe.c | 86 +++++++++++++++++++++++++++++++++++ source3/rpc_client/cli_pipe.h | 7 +++ 2 files changed, 93 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index fcb8b61751c..db283060148 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3210,6 +3210,92 @@ done: return NT_STATUS_OK; } +NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli, + const struct ndr_interface_table *table, + enum dcerpc_transport_t transport, + struct cli_credentials *cli_creds, + struct netlogon_creds_cli_context *netlogon_creds, + struct rpc_pipe_client **_rpccli) +{ + struct rpc_pipe_client *rpccli; + struct pipe_auth_data *rpcauth; + const char *target_service = table->authservices->names[0]; + struct netlogon_creds_CredentialState *ncreds = NULL; + enum dcerpc_AuthLevel auth_level; + NTSTATUS status; + int rpc_pipe_bind_dbglvl = 0; + + status = cli_rpc_pipe_open(cli, transport, table, &rpccli); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = netlogon_creds_cli_lock(netlogon_creds, rpccli, &ncreds); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("netlogon_creds_cli_get returned %s\n", + nt_errstr(status))); + TALLOC_FREE(rpccli); + return status; + } + + auth_level = netlogon_creds_cli_auth_level(netlogon_creds); + + cli_credentials_set_netlogon_creds(cli_creds, ncreds); + + status = rpccli_generic_bind_data_from_creds(rpccli, + DCERPC_AUTH_TYPE_SCHANNEL, + auth_level, + rpccli->desthost, + target_service, + cli_creds, + &rpcauth); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n", + nt_errstr(status))); + TALLOC_FREE(rpccli); + return status; + } + + status = rpc_pipe_bind(rpccli, rpcauth); + cli_credentials_set_netlogon_creds(cli_creds, NULL); + if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) { + rpc_pipe_bind_dbglvl = 1; + netlogon_creds_cli_delete(netlogon_creds, &ncreds); + } + if (!NT_STATUS_IS_OK(status)) { + DEBUG(rpc_pipe_bind_dbglvl, + ("%s: rpc_pipe_bind failed with error %s\n", + __func__, nt_errstr(status))); + TALLOC_FREE(rpccli); + return status; + } + + TALLOC_FREE(ncreds); + + if (!ndr_syntax_id_equal(&table->syntax_id, &ndr_table_netlogon.syntax_id)) { + goto done; + } + + status = netlogon_creds_cli_check(netlogon_creds, + rpccli->binding_handle); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("netlogon_creds_cli_check failed with %s\n", + nt_errstr(status))); + TALLOC_FREE(rpccli); + return status; + } + + +done: + DEBUG(10,("%s: opened pipe %s to machine %s " + "for domain %s and bound using schannel.\n", + __func__, table->name, + rpccli->desthost, cli_credentials_get_domain(cli_creds))); + + *_rpccli = rpccli; + return NT_STATUS_OK; +} + NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, DATA_BLOB *session_key) diff --git a/source3/rpc_client/cli_pipe.h b/source3/rpc_client/cli_pipe.h index 0c1e6921380..16946c5e206 100644 --- a/source3/rpc_client/cli_pipe.h +++ b/source3/rpc_client/cli_pipe.h @@ -106,6 +106,13 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli, struct netlogon_creds_cli_context *netlogon_creds, struct rpc_pipe_client **presult); +NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli, + const struct ndr_interface_table *table, + enum dcerpc_transport_t transport, + struct cli_credentials *cli_creds, + struct netlogon_creds_cli_context *netlogon_creds, + struct rpc_pipe_client **_rpccli); + NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli, struct messaging_context *msg_ctx, const struct ndr_interface_table *table, -- 2.34.1