summaryrefslogtreecommitdiffstats
path: root/source3/rpc_client/cli_pipe.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2013-07-27 11:30:13 +0200
committerStefan Metzmacher <metze@samba.org>2014-01-07 12:47:06 +0100
commit38d4dba37406515181e4d6f1a1faffc18e652e27 (patch)
treed7644727673b23e6167958e6c32422a2ab3a82d6 /source3/rpc_client/cli_pipe.c
parent11aed7cd3dbd967593b34a206f0802fd0002bf27 (diff)
downloadsamba-38d4dba37406515181e4d6f1a1faffc18e652e27.tar.gz
samba-38d4dba37406515181e4d6f1a1faffc18e652e27.tar.xz
samba-38d4dba37406515181e4d6f1a1faffc18e652e27.zip
s3:rpc_client: make use of the new netlogon_creds_cli_context
This exchanges rpc_pipe_client->dc with rpc_pipe_client->netlogon_creds and lets the secure channel session state be stored in node local database. This is the proper fix for a large number of bugs: https://bugzilla.samba.org/show_bug.cgi?id=6563 https://bugzilla.samba.org/show_bug.cgi?id=7944 https://bugzilla.samba.org/show_bug.cgi?id=7945 https://bugzilla.samba.org/show_bug.cgi?id=7568 https://bugzilla.samba.org/show_bug.cgi?id=8599 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source3/rpc_client/cli_pipe.c')
-rw-r--r--source3/rpc_client/cli_pipe.c139
1 files changed, 34 insertions, 105 deletions
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index b6908be7e28..7f79046fc7c 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -24,6 +24,7 @@
#include "librpc/gen_ndr/ndr_epmapper_c.h"
#include "../librpc/gen_ndr/ndr_dssetup.h"
#include "../libcli/auth/schannel.h"
+#include "../libcli/auth/netlogon_creds_cli.h"
#include "auth_generic.h"
#include "librpc/gen_ndr/ndr_dcerpc.h"
#include "librpc/gen_ndr/ndr_netlogon_c.h"
@@ -3024,34 +3025,39 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
enum dcerpc_transport_t transport,
enum dcerpc_AuthLevel auth_level,
const char *domain,
- struct netlogon_creds_CredentialState **pdc,
+ struct netlogon_creds_cli_context *netlogon_creds,
struct rpc_pipe_client **_rpccli)
{
struct rpc_pipe_client *rpccli;
struct pipe_auth_data *rpcauth;
+ struct netlogon_creds_CredentialState *creds = NULL;
NTSTATUS status;
- NTSTATUS result;
- struct netlogon_creds_CredentialState save_creds;
- struct netr_Authenticator auth;
- struct netr_Authenticator return_auth;
- union netr_Capabilities capabilities;
const char *target_service = table->authservices->names[0];
+ 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, &creds);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("netlogon_creds_cli_get returned %s\n",
+ nt_errstr(status)));
+ TALLOC_FREE(rpccli);
+ return status;
+ }
+
status = rpccli_generic_bind_data(rpccli,
DCERPC_AUTH_TYPE_SCHANNEL,
auth_level,
NULL,
target_service,
domain,
- (*pdc)->computer_name,
+ creds->computer_name,
NULL,
CRED_AUTO_USE_KERBEROS,
- *pdc,
+ creds,
&rpcauth);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
@@ -3060,120 +3066,43 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
return status;
}
- /*
- * The credentials on a new netlogon pipe are the ones we are passed
- * in - copy them over
- *
- * This may get overwritten... in rpc_pipe_bind()...
- */
- rpccli->dc = netlogon_creds_copy(rpccli, *pdc);
- if (rpccli->dc == NULL) {
- TALLOC_FREE(rpccli);
- return NT_STATUS_NO_MEMORY;
- }
-
status = rpc_pipe_bind(rpccli, rpcauth);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
+ rpc_pipe_bind_dbglvl = 1;
+ netlogon_creds_cli_delete(netlogon_creds, &creds);
+ }
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
- "cli_rpc_pipe_bind failed with error %s\n",
- nt_errstr(status) ));
+ DEBUG(rpc_pipe_bind_dbglvl,
+ ("cli_rpc_pipe_open_schannel_with_key: "
+ "rpc_pipe_bind failed with error %s\n",
+ nt_errstr(status)));
TALLOC_FREE(rpccli);
return status;
}
- if (!ndr_syntax_id_equal(&table->syntax_id, &ndr_table_netlogon.syntax_id)) {
- goto done;
- }
-
- save_creds = *rpccli->dc;
- ZERO_STRUCT(return_auth);
- ZERO_STRUCT(capabilities);
+ TALLOC_FREE(creds);
- netlogon_creds_client_authenticator(&save_creds, &auth);
-
- status = dcerpc_netr_LogonGetCapabilities(rpccli->binding_handle,
- talloc_tos(),
- rpccli->srv_name_slash,
- save_creds.computer_name,
- &auth, &return_auth,
- 1, &capabilities,
- &result);
- if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
- if (save_creds.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
- DEBUG(5, ("AES was negotiated and the error was %s - "
- "downgrade detected\n",
- nt_errstr(status)));
- TALLOC_FREE(rpccli);
- return NT_STATUS_INVALID_NETWORK_RESPONSE;
- }
-
- /* This is probably an old Samba Version */
- DEBUG(5, ("We are checking against an NT or old Samba - %s\n",
- nt_errstr(status)));
+ 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, ("dcerpc_netr_LogonGetCapabilities failed with %s\n",
+ DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
nt_errstr(status)));
TALLOC_FREE(rpccli);
return status;
}
- if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
- if (save_creds.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
- /* This means AES isn't supported. */
- DEBUG(5, ("AES was negotiated and the result was %s - "
- "downgrade detected\n",
- nt_errstr(result)));
- TALLOC_FREE(rpccli);
- return NT_STATUS_INVALID_NETWORK_RESPONSE;
- }
-
- /* This is probably an old Windows version */
- DEBUG(5, ("We are checking against an win2k3 or Samba - %s\n",
- nt_errstr(result)));
- goto done;
- }
-
- /*
- * We need to check the credential state here, cause win2k3 and earlier
- * returns NT_STATUS_NOT_IMPLEMENTED
- */
- if (!netlogon_creds_client_check(&save_creds, &return_auth.cred)) {
- /*
- * Server replied with bad credential. Fail.
- */
- DEBUG(0,("cli_rpc_pipe_open_schannel_with_key: server %s "
- "replied with bad credential\n",
- rpccli->desthost));
- TALLOC_FREE(rpccli);
- return NT_STATUS_INVALID_NETWORK_RESPONSE;
- }
- *rpccli->dc = save_creds;
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0, ("dcerpc_netr_LogonGetCapabilities failed with %s\n",
- nt_errstr(result)));
- TALLOC_FREE(rpccli);
- return result;
- }
-
- if (!(save_creds.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
- /* This means AES isn't supported. */
- DEBUG(5, ("AES is not negotiated, but netr_LogonGetCapabilities "
- "was OK - downgrade detected\n"));
- TALLOC_FREE(rpccli);
- return NT_STATUS_INVALID_NETWORK_RESPONSE;
- }
-
- if (save_creds.negotiate_flags != capabilities.server_capabilities) {
- DEBUG(0, ("The client capabilities don't match the server "
- "capabilities: local[0x%08X] remote[0x%08X]\n",
- save_creds.negotiate_flags,
- capabilities.server_capabilities));
+ status = netlogon_creds_cli_context_copy(netlogon_creds,
+ rpccli,
+ &rpccli->netlogon_creds);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("netlogon_creds_cli_context_copy failed with %s\n",
+ nt_errstr(status)));
TALLOC_FREE(rpccli);
- return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ return status;
}
done: