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/>.
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"
29 #include "libsmb/libsmb.h"
30 #include "auth/gensec/gensec.h"
31 #include "../libcli/smb/smbXcli_base.h"
34 #define DBGC_CLASS DBGC_RPC_CLI
37 /****************************************************************************
38 Get a the schannel session key out of an already opened netlogon pipe.
39 ****************************************************************************/
40 static NTSTATUS
get_schannel_session_key_common(struct rpc_pipe_client
*netlogon_pipe
,
41 struct cli_state
*cli
,
45 enum netr_SchannelType sec_chan_type
= 0;
46 unsigned char machine_pwd
[16];
47 const char *machine_account
;
50 /* Get the machine account credentials from secrets.tdb. */
51 if (!get_trust_pw_hash(domain
, machine_pwd
, &machine_account
,
54 DEBUG(0, ("get_schannel_session_key: could not fetch "
55 "trust account password for domain '%s'\n",
57 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
60 status
= rpccli_netlogon_setup_creds(netlogon_pipe
,
61 smbXcli_conn_remote_name(cli
->conn
), /* server name */
63 lp_netbios_name(), /* client name */
64 machine_account
, /* machine account name */
69 if (!NT_STATUS_IS_OK(status
)) {
70 DEBUG(3, ("get_schannel_session_key_common: "
71 "rpccli_netlogon_setup_creds failed with result %s "
72 "to server %s, domain %s, machine account %s.\n",
73 nt_errstr(status
), smbXcli_conn_remote_name(cli
->conn
), domain
,
78 if (((*pneg_flags
) & NETLOGON_NEG_SCHANNEL
) == 0) {
79 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
80 smbXcli_conn_remote_name(cli
->conn
)));
81 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
87 /****************************************************************************
88 Open a named pipe to an SMB server and bind using schannel (bind type 68).
89 Fetch the session key ourselves using a temporary netlogon pipe.
90 ****************************************************************************/
92 NTSTATUS
cli_rpc_pipe_open_schannel(struct cli_state
*cli
,
93 const struct ndr_interface_table
*table
,
94 enum dcerpc_transport_t transport
,
95 enum dcerpc_AuthLevel auth_level
,
97 struct rpc_pipe_client
**presult
)
99 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
|
100 NETLOGON_NEG_SUPPORTS_AES
;
101 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
102 struct rpc_pipe_client
*result
= NULL
;
105 status
= get_schannel_session_key(cli
, domain
, &neg_flags
,
107 if (!NT_STATUS_IS_OK(status
)) {
108 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
109 "key from server %s for domain %s.\n",
110 smbXcli_conn_remote_name(cli
->conn
), domain
));
114 status
= cli_rpc_pipe_open_schannel_with_key(
115 cli
, table
, transport
, domain
,
116 netlogon_pipe
->netlogon_creds
,
119 /* Now we've bound using the session key we can close the netlog pipe. */
120 TALLOC_FREE(netlogon_pipe
);
122 if (NT_STATUS_IS_OK(status
)) {
129 /****************************************************************************
130 Open a netlogon pipe and get the schannel session key.
131 Now exposed to external callers.
132 ****************************************************************************/
135 NTSTATUS
get_schannel_session_key(struct cli_state
*cli
,
138 struct rpc_pipe_client
**presult
)
140 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
143 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_netlogon
,
145 if (!NT_STATUS_IS_OK(status
)) {
149 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
151 if (!NT_STATUS_IS_OK(status
)) {
152 TALLOC_FREE(netlogon_pipe
);
156 *presult
= netlogon_pipe
;