From 202bc164ca11539a62a7e894330265df90319828 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Feb 2006 21:18:23 +0000 Subject: r13641: Finish fix for #3510. Don't use client schannel when told not to, cope with a server that doesn't offer schannel also. Jeremy (This used to be commit 68005f6bdb70883eace0d9067c76c3360a803023) --- source3/rpc_client/cli_pipe.c | 22 ++++++++++-------- source3/utils/net_rpc_join.c | 52 ++++++++++++++++++++++++++++++++----------- 2 files changed, 52 insertions(+), 22 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9cc350bef1..23cc6af114 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2393,13 +2393,14 @@ struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli, /**************************************************************************** Open a netlogon pipe and get the schannel session key. + Now exposed to external callers. ****************************************************************************/ -static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, +struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, const char *domain, + uint32 *pneg_flags, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; uint32 sec_chan_type = 0; unsigned char machine_pwd[16]; @@ -2438,7 +2439,7 @@ static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, machine_account, /* machine account name */ machine_pwd, sec_chan_type, - &neg_flags); + pneg_flags); if (!NT_STATUS_IS_OK(*perr)) { DEBUG(3,("get_schannel_session_key: rpccli_netlogon_setup_creds " @@ -2448,7 +2449,7 @@ static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, return NULL; } - if ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0) { + if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) { DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n", cli->desthost)); cli_rpc_pipe_close(netlogon_pipe); @@ -2520,9 +2521,9 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ const char *domain, const char *username, const char *password, + uint32 *pneg_flags, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; uint32 sec_chan_type = 0; unsigned char machine_pwd[16]; @@ -2564,7 +2565,7 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ machine_account, /* machine account name */ machine_pwd, sec_chan_type, - &neg_flags); + pneg_flags); if (!NT_STATUS_IS_OK(*perr)) { DEBUG(3,("get_schannel_session_key_auth_ntlmssp: rpccli_netlogon_setup_creds " @@ -2574,7 +2575,7 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ return NULL; } - if ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0) { + if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) { DEBUG(3, ("get_schannel_session_key_auth_ntlmssp: Server %s did not offer schannel\n", cli->desthost)); cli_rpc_pipe_close(netlogon_pipe); @@ -2599,10 +2600,12 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state const char *password, NTSTATUS *perr) { + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; - netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username, password, perr); + netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username, + password, &neg_flags, perr); if (!netlogon_pipe) { DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session " "key from server %s for domain %s.\n", @@ -2631,10 +2634,11 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, const char *domain, NTSTATUS *perr) { + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; - netlogon_pipe = get_schannel_session_key(cli, domain, perr); + netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr); if (!netlogon_pipe) { DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session " "key from server %s for domain %s.\n", diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index 29a27d8f64..1f68da0d75 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -43,31 +43,57 @@ **/ static int net_rpc_join_ok(const char *domain) { + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_hnd = NULL; - int retval = 1; - NTSTATUS ret; + struct rpc_pipe_client *netlogon_pipe = NULL; + NTSTATUS ntret = NT_STATUS_UNSUCCESSFUL; /* Connect to remote machine */ if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) { - return 1; + return -1; } - pipe_hnd = cli_rpc_pipe_open_schannel(cli, PI_NETLOGON, - PIPE_AUTH_LEVEL_PRIVACY, - domain, &ret); + /* Setup the creds as though we're going to do schannel... */ + netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, &ntret); + + /* We return NT_STATUS_INVALID_NETWORK_RESPONSE if the server is refusing + to negotiate schannel, but the creds were set up ok. That'll have to do. */ + + if (!netlogon_pipe) { + if (NT_STATUS_EQUAL(ntret, NT_STATUS_INVALID_NETWORK_RESPONSE)) { + cli_shutdown(cli); + return 0; + } else { + DEBUG(0,("net_rpc_join_ok: failed to get schannel session " + "key from server %s for domain %s. Error was %s\n", + cli->desthost, domain, nt_errstr(ntret) )); + cli_shutdown(cli); + return -1; + } + } - if (!pipe_hnd) { - DEBUG(0,("Error connecting to NETLOGON pipe. Error was %s\n", nt_errstr(ret) )); - goto done; + /* Only do the rest of the schannel test if the client is allowed to do this. */ + if (!lp_client_schannel()) { + cli_shutdown(cli); + /* We're good... */ + return 0; } - retval = 0; /* Success! */ - -done: + pipe_hnd = cli_rpc_pipe_open_schannel_with_key(cli, PI_NETLOGON, + PIPE_AUTH_LEVEL_PRIVACY, + domain, netlogon_pipe->dc, &ntret); + + if (!pipe_hnd) { + DEBUG(0,("net_rpc_join_ok: failed to open schannel session " + "on netlogon pipe to server %s for domain %s. Error was %s\n", + cli->desthost, domain, nt_errstr(ntret) )); + cli_shutdown(cli); + return -1; + } cli_shutdown(cli); - return retval; + return 0; } /** -- cgit