Schannel, once setup, may be used on *ANY* TCP/IP connection until the
authorAndrew Bartlett <abartlet@samba.org>
Fri, 25 Jul 2003 01:26:19 +0000 (01:26 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 25 Jul 2003 01:26:19 +0000 (01:26 +0000)
connection that set it up has been shut down.

(Also, pipes still connected, and reconnections to the same pipe (eg SAMR)
may continue to use that session key until their TCP/IP connection is shut
down)

Allow further testing by printing out the session key, and allowing it's input
into rpcclient.

Next step is automatic storage in a TDB.

Andrew Bartlett

source/rpc_client/cli_pipe.c
source/rpcclient/rpcclient.c

index 01b4c83235f543c45bf392fba9f7e0e3e599a894..53ff58b966187c74f02f8bb0306c40a2fa166dc3 100644 (file)
@@ -5,6 +5,7 @@
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
  *  Copyright (C) Paul Ashton                       1998.
  *  Copyright (C) Jeremy Allison                    1999.
+ *  Copyright (C) Andrew Bartlett                   2003.
  *  
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -1568,9 +1569,6 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
                }
        }
        
-       /* doing schannel, not per-user auth */
-       cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL;
-       
        if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname())) {
                DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON));
                cli_close(cli, cli->nt_pipe_fnum);
@@ -1581,6 +1579,57 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
 }
 
 
+NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan,
+                            const uchar trust_password[16])
+{
+       NTSTATUS result;        
+       uint32 neg_flags = 0x000001ff;
+       cli->pipe_auth_flags = 0;
+
+       if (lp_client_schannel() == False) {
+               return NT_STATUS_OK;
+       }
+
+       if (!cli_nt_session_open(cli, PI_NETLOGON)) {
+               DEBUG(0, ("Could not initialise %s\n",
+                         get_pipe_name_from_index(PI_NETLOGON)));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (lp_client_schannel() != False)
+               neg_flags |= NETLOGON_NEG_SCHANNEL;
+
+       neg_flags |= NETLOGON_NEG_SCHANNEL;
+
+       result = cli_nt_setup_creds(cli, sec_chan, trust_password,
+                                   &neg_flags, 2);
+
+       if (!(neg_flags & NETLOGON_NEG_SCHANNEL) 
+           && lp_client_schannel() == True) {
+               DEBUG(1, ("Could not negotiate SCHANNEL with the DC!\n"));
+               result = NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (!NT_STATUS_IS_OK(result)) {
+               ZERO_STRUCT(cli->auth_info.sess_key);
+               ZERO_STRUCT(cli->sess_key);
+               cli->pipe_auth_flags = 0;
+               cli_nt_session_close(cli);
+               return result;
+       }
+
+       memcpy(cli->auth_info.sess_key, cli->sess_key,
+              sizeof(cli->auth_info.sess_key));
+
+       cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum;
+       cli->nt_pipe_fnum = 0;
+
+       /* doing schannel, not per-user auth */
+       cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL;
+
+       return NT_STATUS_OK;
+}
+
 const char *cli_pipe_get_name(struct cli_state *cli)
 {
        return cli->pipe_name;
index 614a3bc36ba8dac8a037da1fdf6ab599684efb92..e684f05ecb23db3d17bcc2a2c24db8be836040b9 100644 (file)
@@ -355,66 +355,64 @@ static NTSTATUS cmd_none(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 static NTSTATUS cmd_schannel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                             int argc, const char **argv)
 {
+       NTSTATUS ret;
        uchar trust_password[16];
        uint32 sec_channel_type;
-       uint32 neg_flags = 0x000001ff;
-       NTSTATUS result;
        static uchar zeros[16];
 
+       if (argc == 2) {
+               strhex_to_str(cli->auth_info.sess_key,
+                             strlen(argv[1]), 
+                             argv[1]);
+               memcpy(cli->sess_key, cli->auth_info.sess_key, sizeof(cli->sess_key));
+
+               cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
+               cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
+               cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
+
+               return NT_STATUS_OK;
+       }
+
        /* Cleanup */
 
-       if ((memcmp(cli->auth_info.sess_key, zeros, sizeof(cli->auth_info.sess_key)) != 0) 
-           && (cli->saved_netlogon_pipe_fnum != 0)) {
+       if ((memcmp(cli->auth_info.sess_key, zeros, sizeof(cli->auth_info.sess_key)) != 0)) {
                if (cli->pipe_auth_flags == (AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL)) {
+                       /* already in this mode nothing to do */
                        return NT_STATUS_OK;
                } else {
-                       /* still have session, just need to use it again */
+                       /* schannel is setup, just need to use it again */
                        cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
                        cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
                        cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
                        if (cli->nt_pipe_fnum != 0)
                                cli_nt_session_close(cli);
+                       return NT_STATUS_OK;
                }
        }
        
        if (cli->nt_pipe_fnum != 0)
                cli_nt_session_close(cli);
 
-       cli->pipe_auth_flags = 0;
-       
+       cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
+       cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
+       cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
+
        if (!secrets_fetch_trust_account_password(lp_workgroup(),
                                                  trust_password,
                                                  NULL, &sec_channel_type)) {
                return NT_STATUS_UNSUCCESSFUL;
        }
-       
-       if (!cli_nt_session_open(cli, PI_NETLOGON)) {
-               DEBUG(0, ("Could not initialise %s\n",
-                         get_pipe_name_from_index(PI_NETLOGON)));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       neg_flags |= NETLOGON_NEG_SCHANNEL;
 
-       result = cli_nt_setup_creds(cli, sec_channel_type, trust_password,
-                                   &neg_flags, 2);
-
-       if (!NT_STATUS_IS_OK(result)) {
-               ZERO_STRUCT(cli->auth_info.sess_key);
-               cli->pipe_auth_flags = 0;
-               return result;
+       ret = cli_nt_setup_netsec(cli, sec_channel_type, trust_password);
+       if (NT_STATUS_IS_OK(ret)) {
+               char *hex_session_key;
+               hex_encode(cli->auth_info.sess_key,
+                          sizeof(cli->auth_info.sess_key),
+                          &hex_session_key);
+               printf("Got Session key: %s\n", hex_session_key);
+               SAFE_FREE(hex_session_key);
        }
-
-       memcpy(cli->auth_info.sess_key, cli->sess_key,
-              sizeof(cli->auth_info.sess_key));
-
-       cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum;
-
-       cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
-       cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
-       cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
-
-       return NT_STATUS_OK; 
+       return ret;
 }
 
 /* Built in rpcclient commands */