s3: separate out cli schannel functions that depend on cli_netlogon.
authorGünther Deschner <gd@samba.org>
Mon, 16 Aug 2010 22:46:25 +0000 (00:46 +0200)
committerGünther Deschner <gd@samba.org>
Wed, 25 Aug 2010 22:16:57 +0000 (00:16 +0200)
Guenther

source3/Makefile.in
source3/rpc_client/cli_pipe.c
source3/rpc_client/cli_pipe_schannel.c [new file with mode: 0644]
source3/wscript_build

index 82f0541bfcf73a9313f587755d4880a73a7df245..eabf35105f090c0b9782c9f57dddec9130aef624 100644 (file)
@@ -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@
index d57bc0af60cc101d6a166faddda9e3c43cc3d9ac..16bd649b464f208c0dea0c1cf8adfe752f408014 100644 (file)
 #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"
@@ -2922,87 +2920,6 @@ NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
        return status;
 }
 
-/****************************************************************************
-  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)
@@ -3065,123 +2982,6 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
        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 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
diff --git a/source3/rpc_client/cli_pipe_schannel.c b/source3/rpc_client/cli_pipe_schannel.c
new file mode 100644 (file)
index 0000000..7bc8d80
--- /dev/null
@@ -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;
+}
index 0c7f5aa86b07f16f66f4d140cc1f9bab677767ac..ed47f3642e2f3bc03e1a0543511f07001a7fa864 100644 (file)
@@ -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}'''