summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in14
-rw-r--r--source3/rpc_client/cli_pipe.c200
-rw-r--r--source3/rpc_client/cli_pipe_schannel.c228
-rw-r--r--source3/wscript_build3
4 files changed, 241 insertions, 204 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 82f0541bfc..eabf35105f 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -717,7 +717,8 @@ RPC_SERVER_OBJ = @RPC_STATIC@ $(RPC_PIPE_OBJ) $(NPA_TSTREAM_OBJ) \
$(LIBCLI_WINREG_OBJ) \
$(LIBCLI_SRVSVC_OBJ) \
$(LIBCLI_LSA_OBJ) \
- $(LIBCLI_SAMR_OBJ)
+ $(LIBCLI_SAMR_OBJ) \
+ $(RPC_CLIENT_SCHANNEL_OBJ)
RPC_CLIENT_OBJ = rpc_client/cli_pipe.o \
librpc/rpc/dcerpc_gssapi.o \
@@ -726,6 +727,8 @@ RPC_CLIENT_OBJ = rpc_client/cli_pipe.o \
rpc_client/rpc_transport_np.o \
rpc_client/rpc_transport_sock.o
+RPC_CLIENT_SCHANNEL_OBJ = rpc_client/cli_pipe_schannel.o
+
LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
PRIVILEGES_BASIC_OBJ = lib/privileges_basic.o
@@ -1017,7 +1020,8 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
$(LIBCLI_WKSSVC_OBJ) \
$(LIBCLI_SRVSVC_OBJ) \
$(LIBCLI_LSA_OBJ) \
- $(LIBCLI_SAMR_OBJ)
+ $(LIBCLI_SAMR_OBJ) \
+ $(RPC_CLIENT_SCHANNEL_OBJ)
PAM_WINBIND_OBJ = ../nsswitch/pam_winbind.o $(WBCOMMON_OBJ) \
$(LIBREPLACE_OBJ) @BUILD_INIPARSER@
@@ -1129,7 +1133,8 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_help.o \
$(LIBCLI_WKSSVC_OBJ) \
$(LIBCLI_SRVSVC_OBJ) \
$(LIBCLI_LSA_OBJ) \
- $(LIBCLI_SAMR_OBJ)
+ $(LIBCLI_SAMR_OBJ) \
+ $(RPC_CLIENT_SCHANNEL_OBJ)
# these are not processed by make proto
NET_OBJ2 = utils/net_registry_util.o utils/net_help_common.o
@@ -2298,7 +2303,8 @@ LIBNETAPI_OBJ = $(LIBNETAPI_OBJ0) $(LIBNET_OBJ) \
$(LIBCLI_WKSSVC_OBJ) \
$(LIBCLI_SRVSVC_OBJ) \
$(LIBCLI_LSA_OBJ) \
- $(LIBCLI_SAMR_OBJ)
+ $(LIBCLI_SAMR_OBJ) \
+ $(RPC_CLIENT_SCHANNEL_OBJ)
LIBNETAPI_SHARED_TARGET=@LIBNETAPI_SHARED_TARGET@
LIBNETAPI_SOVER=@LIBNETAPI_SOVER@
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index d57bc0af60..16bd649b46 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -22,13 +22,11 @@
#include "librpc/gen_ndr/cli_epmapper.h"
#include "../librpc/gen_ndr/ndr_schannel.h"
#include "../librpc/gen_ndr/ndr_dssetup.h"
-#include "../librpc/gen_ndr/ndr_netlogon.h"
#include "../libcli/auth/schannel.h"
#include "../libcli/auth/spnego.h"
#include "smb_krb5.h"
#include "../libcli/auth/ntlmssp.h"
#include "ntlmssp_wrap.h"
-#include "rpc_client/cli_netlogon.h"
#include "librpc/gen_ndr/ndr_dcerpc.h"
#include "librpc/rpc/dcerpc.h"
#include "librpc/rpc/dcerpc_gssapi.h"
@@ -2923,87 +2921,6 @@ NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
}
/****************************************************************************
- Get a the schannel session key out of an already opened netlogon pipe.
- ****************************************************************************/
-static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
- struct cli_state *cli,
- const char *domain,
- uint32 *pneg_flags)
-{
- enum netr_SchannelType sec_chan_type = 0;
- unsigned char machine_pwd[16];
- const char *machine_account;
- NTSTATUS status;
-
- /* Get the machine account credentials from secrets.tdb. */
- if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
- &sec_chan_type))
- {
- DEBUG(0, ("get_schannel_session_key: could not fetch "
- "trust account password for domain '%s'\n",
- domain));
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
-
- status = rpccli_netlogon_setup_creds(netlogon_pipe,
- cli->desthost, /* server name */
- domain, /* domain */
- global_myname(), /* client name */
- machine_account, /* machine account name */
- machine_pwd,
- sec_chan_type,
- pneg_flags);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("get_schannel_session_key_common: "
- "rpccli_netlogon_setup_creds failed with result %s "
- "to server %s, domain %s, machine account %s.\n",
- nt_errstr(status), cli->desthost, domain,
- machine_account ));
- return status;
- }
-
- if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
- DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
- cli->desthost));
- return NT_STATUS_INVALID_NETWORK_RESPONSE;
- }
-
- return NT_STATUS_OK;;
-}
-
-/****************************************************************************
- Open a netlogon pipe and get the schannel session key.
- Now exposed to external callers.
- ****************************************************************************/
-
-
-NTSTATUS get_schannel_session_key(struct cli_state *cli,
- const char *domain,
- uint32 *pneg_flags,
- struct rpc_pipe_client **presult)
-{
- struct rpc_pipe_client *netlogon_pipe = NULL;
- NTSTATUS status;
-
- status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
- &netlogon_pipe);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
- pneg_flags);
- if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(netlogon_pipe);
- return status;
- }
-
- *presult = netlogon_pipe;
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
External interface.
Open a named pipe to an SMB server and bind using schannel (bind type 68)
using session_key. sign and seal.
@@ -3066,123 +2983,6 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
}
/****************************************************************************
- Open a named pipe to an SMB server and bind using schannel (bind type 68).
- Fetch the session key ourselves using a temporary netlogon pipe. This
- version uses an ntlmssp auth bound netlogon pipe to get the key.
- ****************************************************************************/
-
-static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
- const char *domain,
- const char *username,
- const char *password,
- uint32 *pneg_flags,
- struct rpc_pipe_client **presult)
-{
- struct rpc_pipe_client *netlogon_pipe = NULL;
- NTSTATUS status;
-
- status = cli_rpc_pipe_open_spnego_ntlmssp(
- cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
- DCERPC_AUTH_LEVEL_PRIVACY,
- domain, username, password, &netlogon_pipe);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
- pneg_flags);
- if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(netlogon_pipe);
- return status;
- }
-
- *presult = netlogon_pipe;
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Open a named pipe to an SMB server and bind using schannel (bind type 68).
- Fetch the session key ourselves using a temporary netlogon pipe. This version
- uses an ntlmssp bind to get the session key.
- ****************************************************************************/
-
-NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
- const struct ndr_syntax_id *interface,
- enum dcerpc_transport_t transport,
- enum dcerpc_AuthLevel auth_level,
- const char *domain,
- const char *username,
- const char *password,
- struct rpc_pipe_client **presult)
-{
- uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
- struct rpc_pipe_client *netlogon_pipe = NULL;
- struct rpc_pipe_client *result = NULL;
- NTSTATUS status;
-
- status = get_schannel_session_key_auth_ntlmssp(
- cli, domain, username, password, &neg_flags, &netlogon_pipe);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
- "key from server %s for domain %s.\n",
- cli->desthost, domain ));
- return status;
- }
-
- status = cli_rpc_pipe_open_schannel_with_key(
- cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
- &result);
-
- /* Now we've bound using the session key we can close the netlog pipe. */
- TALLOC_FREE(netlogon_pipe);
-
- if (NT_STATUS_IS_OK(status)) {
- *presult = result;
- }
- return status;
-}
-
-/****************************************************************************
- Open a named pipe to an SMB server and bind using schannel (bind type 68).
- Fetch the session key ourselves using a temporary netlogon pipe.
- ****************************************************************************/
-
-NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
- const struct ndr_syntax_id *interface,
- enum dcerpc_transport_t transport,
- enum dcerpc_AuthLevel auth_level,
- const char *domain,
- struct rpc_pipe_client **presult)
-{
- uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
- struct rpc_pipe_client *netlogon_pipe = NULL;
- struct rpc_pipe_client *result = NULL;
- NTSTATUS status;
-
- status = get_schannel_session_key(cli, domain, &neg_flags,
- &netlogon_pipe);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
- "key from server %s for domain %s.\n",
- cli->desthost, domain ));
- return status;
- }
-
- status = cli_rpc_pipe_open_schannel_with_key(
- cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
- &result);
-
- /* Now we've bound using the session key we can close the netlog pipe. */
- TALLOC_FREE(netlogon_pipe);
-
- if (NT_STATUS_IS_OK(status)) {
- *presult = result;
- }
-
- return status;
-}
-
-/****************************************************************************
Open a named pipe to an SMB server and bind using krb5 (bind type 16).
The idea is this can be called with service_princ, username and password all
NULL so long as the caller has a TGT.
diff --git a/source3/rpc_client/cli_pipe_schannel.c b/source3/rpc_client/cli_pipe_schannel.c
new file mode 100644
index 0000000000..7bc8d80ec9
--- /dev/null
+++ b/source3/rpc_client/cli_pipe_schannel.c
@@ -0,0 +1,228 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Largely rewritten by Jeremy Allison 2005.
+ *
+ * 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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "../librpc/gen_ndr/ndr_schannel.h"
+#include "../librpc/gen_ndr/ndr_netlogon.h"
+#include "../libcli/auth/schannel.h"
+#include "rpc_client/cli_netlogon.h"
+#include "librpc/gen_ndr/ndr_dcerpc.h"
+#include "librpc/rpc/dcerpc.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_CLI
+
+
+/****************************************************************************
+ Get a the schannel session key out of an already opened netlogon pipe.
+ ****************************************************************************/
+static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
+ struct cli_state *cli,
+ const char *domain,
+ uint32 *pneg_flags)
+{
+ enum netr_SchannelType sec_chan_type = 0;
+ unsigned char machine_pwd[16];
+ const char *machine_account;
+ NTSTATUS status;
+
+ /* Get the machine account credentials from secrets.tdb. */
+ if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
+ &sec_chan_type))
+ {
+ DEBUG(0, ("get_schannel_session_key: could not fetch "
+ "trust account password for domain '%s'\n",
+ domain));
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+
+ status = rpccli_netlogon_setup_creds(netlogon_pipe,
+ cli->desthost, /* server name */
+ domain, /* domain */
+ global_myname(), /* client name */
+ machine_account, /* machine account name */
+ machine_pwd,
+ sec_chan_type,
+ pneg_flags);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("get_schannel_session_key_common: "
+ "rpccli_netlogon_setup_creds failed with result %s "
+ "to server %s, domain %s, machine account %s.\n",
+ nt_errstr(status), cli->desthost, domain,
+ machine_account ));
+ return status;
+ }
+
+ if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
+ DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
+ cli->desthost));
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ return NT_STATUS_OK;;
+}
+
+/****************************************************************************
+ Open a named pipe to an SMB server and bind using schannel (bind type 68).
+ Fetch the session key ourselves using a temporary netlogon pipe. This
+ version uses an ntlmssp auth bound netlogon pipe to get the key.
+ ****************************************************************************/
+
+static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
+ const char *domain,
+ const char *username,
+ const char *password,
+ uint32 *pneg_flags,
+ struct rpc_pipe_client **presult)
+{
+ struct rpc_pipe_client *netlogon_pipe = NULL;
+ NTSTATUS status;
+
+ status = cli_rpc_pipe_open_spnego_ntlmssp(
+ cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
+ DCERPC_AUTH_LEVEL_PRIVACY,
+ domain, username, password, &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
+ pneg_flags);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(netlogon_pipe);
+ return status;
+ }
+
+ *presult = netlogon_pipe;
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Open a named pipe to an SMB server and bind using schannel (bind type 68).
+ Fetch the session key ourselves using a temporary netlogon pipe. This version
+ uses an ntlmssp bind to get the session key.
+ ****************************************************************************/
+
+NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
+ const struct ndr_syntax_id *interface,
+ enum dcerpc_transport_t transport,
+ enum dcerpc_AuthLevel auth_level,
+ const char *domain,
+ const char *username,
+ const char *password,
+ struct rpc_pipe_client **presult)
+{
+ uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+ struct rpc_pipe_client *netlogon_pipe = NULL;
+ struct rpc_pipe_client *result = NULL;
+ NTSTATUS status;
+
+ status = get_schannel_session_key_auth_ntlmssp(
+ cli, domain, username, password, &neg_flags, &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
+ "key from server %s for domain %s.\n",
+ cli->desthost, domain ));
+ return status;
+ }
+
+ status = cli_rpc_pipe_open_schannel_with_key(
+ cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
+ &result);
+
+ /* Now we've bound using the session key we can close the netlog pipe. */
+ TALLOC_FREE(netlogon_pipe);
+
+ if (NT_STATUS_IS_OK(status)) {
+ *presult = result;
+ }
+ return status;
+}
+
+/****************************************************************************
+ Open a named pipe to an SMB server and bind using schannel (bind type 68).
+ Fetch the session key ourselves using a temporary netlogon pipe.
+ ****************************************************************************/
+
+NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
+ const struct ndr_syntax_id *interface,
+ enum dcerpc_transport_t transport,
+ enum dcerpc_AuthLevel auth_level,
+ const char *domain,
+ struct rpc_pipe_client **presult)
+{
+ uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+ struct rpc_pipe_client *netlogon_pipe = NULL;
+ struct rpc_pipe_client *result = NULL;
+ NTSTATUS status;
+
+ status = get_schannel_session_key(cli, domain, &neg_flags,
+ &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
+ "key from server %s for domain %s.\n",
+ cli->desthost, domain ));
+ return status;
+ }
+
+ status = cli_rpc_pipe_open_schannel_with_key(
+ cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
+ &result);
+
+ /* Now we've bound using the session key we can close the netlog pipe. */
+ TALLOC_FREE(netlogon_pipe);
+
+ if (NT_STATUS_IS_OK(status)) {
+ *presult = result;
+ }
+
+ return status;
+}
+
+/****************************************************************************
+ Open a netlogon pipe and get the schannel session key.
+ Now exposed to external callers.
+ ****************************************************************************/
+
+
+NTSTATUS get_schannel_session_key(struct cli_state *cli,
+ const char *domain,
+ uint32 *pneg_flags,
+ struct rpc_pipe_client **presult)
+{
+ struct rpc_pipe_client *netlogon_pipe = NULL;
+ NTSTATUS status;
+
+ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
+ &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
+ pneg_flags);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(netlogon_pipe);
+ return status;
+ }
+
+ *presult = netlogon_pipe;
+ return NT_STATUS_OK;
+}
diff --git a/source3/wscript_build b/source3/wscript_build
index 0c7f5aa86b..ed47f3642e 100644
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -477,6 +477,8 @@ RPC_CLIENT_SRC = '''rpc_client/cli_pipe.c
rpc_client/rpc_transport_np.c
rpc_client/rpc_transport_sock.c'''
+RPC_CLIENT_SCHANNEL_SRC = '''rpc_client/cli_pipe_schannel.c'''
+
LOCKING_SRC = '''locking/locking.c locking/brlock.c locking/posix.c'''
PRIVILEGES_BASIC_SRC = '''lib/privileges_basic.c'''
@@ -805,6 +807,7 @@ SMBD_SRC_BASE = '''${SMBD_SRC_SRV}
${LIBCLI_SRVSVC_SRC}
${LIBCLI_LSA_SRC}
${LIBCLI_SAMR_SRC}
+ ${RPC_CLIENT_SCHANNEL_SRC}
${AUTH_SRC}
${PRIVILEGES_BASIC_SRC}'''