r13641: Finish fix for #3510. Don't use client schannel when told
authorJeremy Allison <jra@samba.org>
Wed, 22 Feb 2006 21:18:23 +0000 (21:18 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:10:20 +0000 (11:10 -0500)
not to, cope with a server that doesn't offer schannel also.
Jeremy

source/rpc_client/cli_pipe.c
source/utils/net_rpc_join.c

index 9cc350bef1b2bdd992ce042dd97b7fc8b5927cdf..23cc6af114b98f7fdeccf47f174f7587179ae3af 100644 (file)
@@ -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",
index 29a27d8f647699fafdcaae985b81cf30b29ae339..1f68da0d754c9ac85d972014acebc26016a5fdfe 100644 (file)
  **/
 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;
 }
 
 /**