s3:rpc_client: pass object and table to rpccli_bh_create()
[mat/samba.git] / source3 / rpc_client / cli_pipe.c
index ca0473ce47977168b757894323ac45a069c24709..48ed92ce50a1faf1b7ff82cc564303e1ba1e8f16 100644 (file)
 #include "includes.h"
 #include "../lib/util/tevent_ntstatus.h"
 #include "librpc/gen_ndr/ndr_epmapper_c.h"
-#include "../librpc/gen_ndr/ndr_schannel.h"
 #include "../librpc/gen_ndr/ndr_dssetup.h"
 #include "../libcli/auth/schannel.h"
-#include "../libcli/auth/spnego.h"
-#include "../auth/ntlmssp/ntlmssp.h"
 #include "auth_generic.h"
 #include "librpc/gen_ndr/ndr_dcerpc.h"
 #include "librpc/gen_ndr/ndr_netlogon_c.h"
@@ -993,42 +990,6 @@ static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
        return gensec_update(gensec_security, mem_ctx, NULL, null_blob, auth_token);
 }
 
-/*******************************************************************
- Creates schannel auth bind.
- ********************************************************************/
-
-static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
-                                                 DATA_BLOB *auth_token)
-{
-       NTSTATUS status;
-       struct NL_AUTH_MESSAGE r;
-
-       if (!cli->auth->user_name || !cli->auth->user_name[0]) {
-               return NT_STATUS_INVALID_PARAMETER_MIX;
-       }
-
-       if (!cli->auth->domain || !cli->auth->domain[0]) {
-               return NT_STATUS_INVALID_PARAMETER_MIX;
-       }
-
-       /*
-        * Now marshall the data into the auth parse_struct.
-        */
-
-       r.MessageType                   = NL_NEGOTIATE_REQUEST;
-       r.Flags                         = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
-                                         NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
-       r.oem_netbios_domain.a          = cli->auth->domain;
-       r.oem_netbios_computer.a        = cli->auth->user_name;
-
-       status = dcerpc_push_schannel_bind(cli, &r, auth_token);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       return NT_STATUS_OK;
-}
-
 /*******************************************************************
  Creates the internals of a DCE/RPC bind request or alter context PDU.
  ********************************************************************/
@@ -1096,12 +1057,6 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
 
        switch (auth->auth_type) {
        case DCERPC_AUTH_TYPE_SCHANNEL:
-               ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
-               if (!NT_STATUS_IS_OK(ret)) {
-                       return ret;
-               }
-               break;
-
        case DCERPC_AUTH_TYPE_NTLMSSP:
        case DCERPC_AUTH_TYPE_KRB5:
        case DCERPC_AUTH_TYPE_SPNEGO:
@@ -1884,6 +1839,25 @@ static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
        return rpccli_set_timeout(hs->rpc_cli, timeout);
 }
 
+static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h,
+                               enum dcerpc_AuthType *auth_type,
+                               enum dcerpc_AuthLevel *auth_level)
+{
+       struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
+                                    struct rpccli_bh_state);
+
+       if (hs->rpc_cli == NULL) {
+               return;
+       }
+
+       if (hs->rpc_cli->auth == NULL) {
+               return;
+       }
+
+       *auth_type = hs->rpc_cli->auth->auth_type;
+       *auth_level = hs->rpc_cli->auth->auth_level;
+}
+
 struct rpccli_bh_raw_call_state {
        DATA_BLOB in_data;
        DATA_BLOB out_data;
@@ -2063,6 +2037,7 @@ static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
        .name                   = "rpccli",
        .is_connected           = rpccli_bh_is_connected,
        .set_timeout            = rpccli_bh_set_timeout,
+       .auth_info              = rpccli_bh_auth_info,
        .raw_call_send          = rpccli_bh_raw_call_send,
        .raw_call_recv          = rpccli_bh_raw_call_recv,
        .disconnect_send        = rpccli_bh_disconnect_send,
@@ -2073,15 +2048,17 @@ static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
 };
 
 /* initialise a rpc_pipe_client binding handle */
-struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
+struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c,
+                                       const struct GUID *object,
+                                       const struct ndr_interface_table *table)
 {
        struct dcerpc_binding_handle *h;
        struct rpccli_bh_state *hs;
 
        h = dcerpc_binding_handle_create(c,
                                         &rpccli_bh_ops,
-                                        NULL,
-                                        NULL, /* TODO */
+                                        object,
+                                        table,
                                         &hs,
                                         struct rpccli_bh_state,
                                         __location__);
@@ -2150,6 +2127,7 @@ static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
                                         const char *username,
                                         const char *password,
                                         enum credentials_use_kerberos use_kerberos,
+                                        struct netlogon_creds_CredentialState *creds,
                                         struct pipe_auth_data **presult)
 {
        struct auth_generic_state *auth_generic_ctx;
@@ -2203,6 +2181,7 @@ static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
        }
 
        cli_credentials_set_kerberos_state(auth_generic_ctx->credentials, use_kerberos);
+       cli_credentials_set_netlogon_creds(auth_generic_ctx->credentials, creds);
 
        status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
        if (!NT_STATUS_IS_OK(status)) {
@@ -2219,43 +2198,6 @@ static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
        return status;
 }
 
-static NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx,
-                               const char *domain,
-                               enum dcerpc_AuthLevel auth_level,
-                               struct netlogon_creds_CredentialState *creds,
-                               struct pipe_auth_data **presult)
-{
-       struct schannel_state *schannel_auth;
-       struct pipe_auth_data *result;
-
-       result = talloc(mem_ctx, struct pipe_auth_data);
-       if (result == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
-       result->auth_level = auth_level;
-
-       result->user_name = talloc_strdup(result, creds->computer_name);
-       result->domain = talloc_strdup(result, domain);
-       if ((result->user_name == NULL) || (result->domain == NULL)) {
-               goto fail;
-       }
-
-       schannel_auth = netsec_create_state(result, creds, true /* initiator */);
-       if (schannel_auth == NULL) {
-               goto fail;
-       }
-
-       result->auth_ctx = schannel_auth;
-       *presult = result;
-       return NT_STATUS_OK;
-
- fail:
-       TALLOC_FREE(result);
-       return NT_STATUS_NO_MEMORY;
-}
-
 /**
  * Create an rpc pipe client struct, connecting to a tcp port.
  */
@@ -2312,7 +2254,7 @@ static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
 
        result->transport->transport = NCACN_IP_TCP;
 
-       result->binding_handle = rpccli_bh_create(result);
+       result->binding_handle = rpccli_bh_create(result, NULL, table);
        if (result->binding_handle == NULL) {
                TALLOC_FREE(result);
                return NT_STATUS_NO_MEMORY;
@@ -2551,7 +2493,7 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
 
        result->transport->transport = NCALRPC;
 
-       result->binding_handle = rpccli_bh_create(result);
+       result->binding_handle = rpccli_bh_create(result, NULL, table);
        if (result->binding_handle == NULL) {
                TALLOC_FREE(result);
                return NT_STATUS_NO_MEMORY;
@@ -2642,7 +2584,7 @@ static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
        DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
        talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
 
-       result->binding_handle = rpccli_bh_create(result);
+       result->binding_handle = rpccli_bh_create(result, NULL, table);
        if (result->binding_handle == NULL) {
                TALLOC_FREE(result);
                return NT_STATUS_NO_MEMORY;
@@ -2744,8 +2686,7 @@ NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
                }
                DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
                            "%s failed with error %s\n",
-                           get_pipe_name_from_syntax(talloc_tos(),
-                                                     &table->syntax_id),
+                           table->name,
                            nt_errstr(status) ));
                TALLOC_FREE(result);
                return status;
@@ -2753,7 +2694,7 @@ NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
 
        DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
                  "%s and bound anonymously.\n",
-                 get_pipe_name_from_syntax(talloc_tos(), &table->syntax_id),
+                 table->name,
                  result->desthost));
 
        *presult = result;
@@ -2802,6 +2743,7 @@ NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
                                          server, target_service,
                                          domain, username, password, 
                                          CRED_AUTO_USE_KERBEROS,
+                                         NULL,
                                          &auth);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
@@ -2853,16 +2795,26 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
        struct netr_Authenticator auth;
        struct netr_Authenticator return_auth;
        union netr_Capabilities capabilities;
+       const char *target_service = table->authservices->names[0];
 
        status = cli_rpc_pipe_open(cli, transport, table, &rpccli);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       status = rpccli_schannel_bind_data(rpccli, domain, auth_level,
-                                          *pdc, &rpcauth);
+       status = rpccli_generic_bind_data(rpccli,
+                                         DCERPC_AUTH_TYPE_SCHANNEL,
+                                         auth_level,
+                                         NULL,
+                                         target_service,
+                                         domain,
+                                         (*pdc)->computer_name,
+                                         NULL,
+                                         CRED_AUTO_USE_KERBEROS,
+                                         *pdc,
+                                         &rpcauth);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
+               DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
                          nt_errstr(status)));
                TALLOC_FREE(rpccli);
                return status;
@@ -2987,7 +2939,7 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
 done:
        DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
                  "for domain %s and bound using schannel.\n",
-                 get_pipe_name_from_syntax(talloc_tos(), &table->syntax_id),
+                 table->name,
                  rpccli->desthost, domain));
 
        *_rpccli = rpccli;
@@ -3029,7 +2981,7 @@ NTSTATUS cli_rpc_pipe_open_spnego(struct cli_state *cli,
                                          DCERPC_AUTH_TYPE_SPNEGO, auth_level,
                                          server, target_service,
                                          domain, username, password, 
-                                         use_kerberos,
+                                         use_kerberos, NULL,
                                          &auth);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("rpccli_generic_bind_data returned %s\n",