s3: Fix Coverity ID 242726 Uninitialized scalar variable
[Samba/gebeck_regimport.git] / source3 / rpc_client / cli_pipe_schannel.c
blob0ee2a8551ff8f736f8e9abbac46b220342f78f88
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"
30 #include "auth/gensec/gensec.h"
32 #undef DBGC_CLASS
33 #define DBGC_CLASS DBGC_RPC_CLI
36 /****************************************************************************
37 Get a the schannel session key out of an already opened netlogon pipe.
38 ****************************************************************************/
39 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
40 struct cli_state *cli,
41 const char *domain,
42 uint32 *pneg_flags)
44 enum netr_SchannelType sec_chan_type = 0;
45 unsigned char machine_pwd[16];
46 const char *machine_account;
47 NTSTATUS status;
49 /* Get the machine account credentials from secrets.tdb. */
50 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
51 &sec_chan_type))
53 DEBUG(0, ("get_schannel_session_key: could not fetch "
54 "trust account password for domain '%s'\n",
55 domain));
56 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
59 status = rpccli_netlogon_setup_creds(netlogon_pipe,
60 cli_state_remote_name(cli), /* server name */
61 domain, /* domain */
62 lp_netbios_name(), /* client name */
63 machine_account, /* machine account name */
64 machine_pwd,
65 sec_chan_type,
66 pneg_flags);
68 if (!NT_STATUS_IS_OK(status)) {
69 DEBUG(3, ("get_schannel_session_key_common: "
70 "rpccli_netlogon_setup_creds failed with result %s "
71 "to server %s, domain %s, machine account %s.\n",
72 nt_errstr(status), cli_state_remote_name(cli), domain,
73 machine_account ));
74 return status;
77 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
78 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
79 cli_state_remote_name(cli)));
80 return NT_STATUS_INVALID_NETWORK_RESPONSE;
83 return NT_STATUS_OK;
86 /****************************************************************************
87 Open a named pipe to an SMB server and bind using schannel (bind type 68).
88 Fetch the session key ourselves using a temporary netlogon pipe. This
89 version uses an ntlmssp auth bound netlogon pipe to get the key.
90 ****************************************************************************/
92 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
93 const char *domain,
94 const char *username,
95 const char *password,
96 uint32 *pneg_flags,
97 struct rpc_pipe_client **presult)
99 struct rpc_pipe_client *netlogon_pipe = NULL;
100 NTSTATUS status;
102 status = cli_rpc_pipe_open_spnego(
103 cli, &ndr_table_netlogon, NCACN_NP,
104 GENSEC_OID_NTLMSSP,
105 DCERPC_AUTH_LEVEL_PRIVACY,
106 cli_state_remote_name(cli),
107 domain, username, password, &netlogon_pipe);
108 if (!NT_STATUS_IS_OK(status)) {
109 return status;
112 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
113 pneg_flags);
114 if (!NT_STATUS_IS_OK(status)) {
115 TALLOC_FREE(netlogon_pipe);
116 return status;
119 *presult = netlogon_pipe;
120 return NT_STATUS_OK;
123 /****************************************************************************
124 Open a named pipe to an SMB server and bind using schannel (bind type 68).
125 Fetch the session key ourselves using a temporary netlogon pipe. This version
126 uses an ntlmssp bind to get the session key.
127 ****************************************************************************/
129 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
130 const struct ndr_syntax_id *interface,
131 enum dcerpc_transport_t transport,
132 enum dcerpc_AuthLevel auth_level,
133 const char *domain,
134 const char *username,
135 const char *password,
136 struct rpc_pipe_client **presult)
138 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
139 struct rpc_pipe_client *netlogon_pipe = NULL;
140 struct rpc_pipe_client *result = NULL;
141 NTSTATUS status;
143 status = get_schannel_session_key_auth_ntlmssp(
144 cli, domain, username, password, &neg_flags, &netlogon_pipe);
145 if (!NT_STATUS_IS_OK(status)) {
146 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
147 "key from server %s for domain %s.\n",
148 cli_state_remote_name(cli), domain ));
149 return status;
152 status = cli_rpc_pipe_open_schannel_with_key(
153 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
154 &result);
156 /* Now we've bound using the session key we can close the netlog pipe. */
157 TALLOC_FREE(netlogon_pipe);
159 if (NT_STATUS_IS_OK(status)) {
160 *presult = result;
162 return status;
165 /****************************************************************************
166 Open a named pipe to an SMB server and bind using schannel (bind type 68).
167 Fetch the session key ourselves using a temporary netlogon pipe.
168 ****************************************************************************/
170 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
171 const struct ndr_syntax_id *interface,
172 enum dcerpc_transport_t transport,
173 enum dcerpc_AuthLevel auth_level,
174 const char *domain,
175 struct rpc_pipe_client **presult)
177 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
178 struct rpc_pipe_client *netlogon_pipe = NULL;
179 struct rpc_pipe_client *result = NULL;
180 NTSTATUS status;
182 status = get_schannel_session_key(cli, domain, &neg_flags,
183 &netlogon_pipe);
184 if (!NT_STATUS_IS_OK(status)) {
185 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
186 "key from server %s for domain %s.\n",
187 cli_state_remote_name(cli), domain ));
188 return status;
191 status = cli_rpc_pipe_open_schannel_with_key(
192 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
193 &result);
195 /* Now we've bound using the session key we can close the netlog pipe. */
196 TALLOC_FREE(netlogon_pipe);
198 if (NT_STATUS_IS_OK(status)) {
199 *presult = result;
202 return status;
205 /****************************************************************************
206 Open a netlogon pipe and get the schannel session key.
207 Now exposed to external callers.
208 ****************************************************************************/
211 NTSTATUS get_schannel_session_key(struct cli_state *cli,
212 const char *domain,
213 uint32 *pneg_flags,
214 struct rpc_pipe_client **presult)
216 struct rpc_pipe_client *netlogon_pipe = NULL;
217 NTSTATUS status;
219 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
220 &netlogon_pipe);
221 if (!NT_STATUS_IS_OK(status)) {
222 return status;
225 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
226 pneg_flags);
227 if (!NT_STATUS_IS_OK(status)) {
228 TALLOC_FREE(netlogon_pipe);
229 return status;
232 *presult = netlogon_pipe;
233 return NT_STATUS_OK;