s3:cli_pipe_schannel: make use of cli_state_remote_name()
[Samba/gebeck_regimport.git] / source3 / rpc_client / cli_pipe_schannel.c
blob2c937df0f0985fd382c2c8098dadf21df58cadae
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "../librpc/gen_ndr/ndr_schannel.h"
22 #include "../librpc/gen_ndr/ndr_netlogon.h"
23 #include "../libcli/auth/schannel.h"
24 #include "rpc_client/cli_netlogon.h"
25 #include "rpc_client/cli_pipe.h"
26 #include "librpc/gen_ndr/ndr_dcerpc.h"
27 #include "librpc/rpc/dcerpc.h"
28 #include "passdb.h"
29 #include "libsmb/libsmb.h"
31 #undef DBGC_CLASS
32 #define DBGC_CLASS DBGC_RPC_CLI
35 /****************************************************************************
36 Get a the schannel session key out of an already opened netlogon pipe.
37 ****************************************************************************/
38 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
39 struct cli_state *cli,
40 const char *domain,
41 uint32 *pneg_flags)
43 enum netr_SchannelType sec_chan_type = 0;
44 unsigned char machine_pwd[16];
45 const char *machine_account;
46 NTSTATUS status;
48 /* Get the machine account credentials from secrets.tdb. */
49 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
50 &sec_chan_type))
52 DEBUG(0, ("get_schannel_session_key: could not fetch "
53 "trust account password for domain '%s'\n",
54 domain));
55 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
58 status = rpccli_netlogon_setup_creds(netlogon_pipe,
59 cli_state_remote_name(cli), /* server name */
60 domain, /* domain */
61 lp_netbios_name(), /* client name */
62 machine_account, /* machine account name */
63 machine_pwd,
64 sec_chan_type,
65 pneg_flags);
67 if (!NT_STATUS_IS_OK(status)) {
68 DEBUG(3, ("get_schannel_session_key_common: "
69 "rpccli_netlogon_setup_creds failed with result %s "
70 "to server %s, domain %s, machine account %s.\n",
71 nt_errstr(status), cli_state_remote_name(cli), domain,
72 machine_account ));
73 return status;
76 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
77 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
78 cli_state_remote_name(cli)));
79 return NT_STATUS_INVALID_NETWORK_RESPONSE;
82 return NT_STATUS_OK;
85 /****************************************************************************
86 Open a named pipe to an SMB server and bind using schannel (bind type 68).
87 Fetch the session key ourselves using a temporary netlogon pipe. This
88 version uses an ntlmssp auth bound netlogon pipe to get the key.
89 ****************************************************************************/
91 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
92 const char *domain,
93 const char *username,
94 const char *password,
95 uint32 *pneg_flags,
96 struct rpc_pipe_client **presult)
98 struct rpc_pipe_client *netlogon_pipe = NULL;
99 NTSTATUS status;
101 status = cli_rpc_pipe_open_spnego_ntlmssp(
102 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
103 DCERPC_AUTH_LEVEL_PRIVACY,
104 domain, username, password, &netlogon_pipe);
105 if (!NT_STATUS_IS_OK(status)) {
106 return status;
109 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
110 pneg_flags);
111 if (!NT_STATUS_IS_OK(status)) {
112 TALLOC_FREE(netlogon_pipe);
113 return status;
116 *presult = netlogon_pipe;
117 return NT_STATUS_OK;
120 /****************************************************************************
121 Open a named pipe to an SMB server and bind using schannel (bind type 68).
122 Fetch the session key ourselves using a temporary netlogon pipe. This version
123 uses an ntlmssp bind to get the session key.
124 ****************************************************************************/
126 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
127 const struct ndr_syntax_id *interface,
128 enum dcerpc_transport_t transport,
129 enum dcerpc_AuthLevel auth_level,
130 const char *domain,
131 const char *username,
132 const char *password,
133 struct rpc_pipe_client **presult)
135 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
136 struct rpc_pipe_client *netlogon_pipe = NULL;
137 struct rpc_pipe_client *result = NULL;
138 NTSTATUS status;
140 status = get_schannel_session_key_auth_ntlmssp(
141 cli, domain, username, password, &neg_flags, &netlogon_pipe);
142 if (!NT_STATUS_IS_OK(status)) {
143 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
144 "key from server %s for domain %s.\n",
145 cli_state_remote_name(cli), domain ));
146 return status;
149 status = cli_rpc_pipe_open_schannel_with_key(
150 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
151 &result);
153 /* Now we've bound using the session key we can close the netlog pipe. */
154 TALLOC_FREE(netlogon_pipe);
156 if (NT_STATUS_IS_OK(status)) {
157 *presult = result;
159 return status;
162 /****************************************************************************
163 Open a named pipe to an SMB server and bind using schannel (bind type 68).
164 Fetch the session key ourselves using a temporary netlogon pipe.
165 ****************************************************************************/
167 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
168 const struct ndr_syntax_id *interface,
169 enum dcerpc_transport_t transport,
170 enum dcerpc_AuthLevel auth_level,
171 const char *domain,
172 struct rpc_pipe_client **presult)
174 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
175 struct rpc_pipe_client *netlogon_pipe = NULL;
176 struct rpc_pipe_client *result = NULL;
177 NTSTATUS status;
179 status = get_schannel_session_key(cli, domain, &neg_flags,
180 &netlogon_pipe);
181 if (!NT_STATUS_IS_OK(status)) {
182 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
183 "key from server %s for domain %s.\n",
184 cli_state_remote_name(cli), domain ));
185 return status;
188 status = cli_rpc_pipe_open_schannel_with_key(
189 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
190 &result);
192 /* Now we've bound using the session key we can close the netlog pipe. */
193 TALLOC_FREE(netlogon_pipe);
195 if (NT_STATUS_IS_OK(status)) {
196 *presult = result;
199 return status;
202 /****************************************************************************
203 Open a netlogon pipe and get the schannel session key.
204 Now exposed to external callers.
205 ****************************************************************************/
208 NTSTATUS get_schannel_session_key(struct cli_state *cli,
209 const char *domain,
210 uint32 *pneg_flags,
211 struct rpc_pipe_client **presult)
213 struct rpc_pipe_client *netlogon_pipe = NULL;
214 NTSTATUS status;
216 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
217 &netlogon_pipe);
218 if (!NT_STATUS_IS_OK(status)) {
219 return status;
222 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
223 pneg_flags);
224 if (!NT_STATUS_IS_OK(status)) {
225 TALLOC_FREE(netlogon_pipe);
226 return status;
229 *presult = netlogon_pipe;
230 return NT_STATUS_OK;