Coverage Report

Created: 2026-06-07 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/rpc_client/cli_pipe_schannel.c
Line
Count
Source
1
/*
2
 *  Unix SMB/CIFS implementation.
3
 *  RPC Pipe client / server routines
4
 *  Largely rewritten by Jeremy Allison       2005.
5
 *
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.
10
 *
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.
15
 *
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/>.
18
 */
19
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/rpc/dcerpc.h"
27
#include "passdb.h"
28
#include "../libcli/smb/smbXcli_base.h"
29
#include "libcli/auth/netlogon_creds_cli.h"
30
#include "auth/gensec/gensec.h"
31
32
#undef DBGC_CLASS
33
#define DBGC_CLASS DBGC_RPC_CLI
34
35
/****************************************************************************
36
 Open a named pipe to an SMB server and bind using schannel (bind type 68).
37
 Fetch the session key ourselves using a temporary netlogon pipe.
38
 ****************************************************************************/
39
40
NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
41
            struct messaging_context *msg_ctx,
42
            const struct ndr_interface_table *table,
43
            enum dcerpc_transport_t transport,
44
            const char *domain,
45
            const char *remote_name,
46
            const struct sockaddr_storage *remote_sockaddr,
47
            struct rpc_pipe_client **presult,
48
            TALLOC_CTX *mem_ctx,
49
            struct netlogon_creds_cli_context **pcreds)
50
0
{
51
0
  TALLOC_CTX *frame = talloc_stackframe();
52
0
  struct rpc_pipe_client *result = NULL;
53
0
  NTSTATUS status;
54
0
  struct cli_credentials *cli_creds = NULL;
55
0
  struct netlogon_creds_cli_context *netlogon_creds = NULL;
56
0
  struct netlogon_creds_CredentialState *creds = NULL;
57
0
  uint32_t netlogon_flags;
58
0
  bool authenticate_kerberos;
59
60
0
  status = pdb_get_trust_credentials(domain, NULL,
61
0
             frame, &cli_creds);
62
0
  if (!NT_STATUS_IS_OK(status)) {
63
0
    TALLOC_FREE(frame);
64
0
    return status;
65
0
  }
66
67
0
  cli_credentials_add_gensec_features(cli_creds,
68
0
              GENSEC_FEATURE_NO_DELEGATION,
69
0
              CRED_SPECIFIED);
70
71
0
  status = rpccli_create_netlogon_creds_ctx(cli_creds,
72
0
              remote_name,
73
0
              msg_ctx,
74
0
              frame,
75
0
              &netlogon_creds);
76
0
  if (!NT_STATUS_IS_OK(status)) {
77
0
    TALLOC_FREE(frame);
78
0
    return status;
79
0
  }
80
81
0
  if (table == &ndr_table_netlogon) {
82
0
    status = rpccli_connect_netlogon(cli,
83
0
             transport,
84
0
             remote_name,
85
0
             remote_sockaddr,
86
0
             netlogon_creds,
87
0
             false, /* force_reauth */
88
0
             cli_creds,
89
0
             &result);
90
0
    if (!NT_STATUS_IS_OK(status)) {
91
0
      TALLOC_FREE(frame);
92
0
      return status;
93
0
    }
94
0
    goto done;
95
0
  }
96
97
0
  status = rpccli_setup_netlogon_creds(cli,
98
0
               transport,
99
0
               remote_name,
100
0
               remote_sockaddr,
101
0
               netlogon_creds,
102
0
               false, /* force_reauth */
103
0
               cli_creds);
104
0
  if (!NT_STATUS_IS_OK(status)) {
105
0
    TALLOC_FREE(frame);
106
0
    return status;
107
0
  }
108
109
0
  status = netlogon_creds_cli_get(netlogon_creds, frame, &creds);
110
0
  if (!NT_STATUS_IS_OK(status)) {
111
0
    TALLOC_FREE(frame);
112
0
    return status;
113
0
  }
114
115
0
  netlogon_flags = creds->negotiate_flags;
116
0
  authenticate_kerberos = creds->authenticate_kerberos;
117
0
  TALLOC_FREE(creds);
118
119
0
  if (authenticate_kerberos) {
120
0
    status = cli_rpc_pipe_open_with_creds(cli,
121
0
                  table,
122
0
                  transport,
123
0
                  DCERPC_AUTH_TYPE_KRB5,
124
0
                  DCERPC_AUTH_LEVEL_PRIVACY,
125
0
                  "netlogon",
126
0
                  remote_name,
127
0
                  remote_sockaddr,
128
0
                  cli_creds,
129
0
                  &result);
130
0
    if (!NT_STATUS_IS_OK(status)) {
131
0
      TALLOC_FREE(frame);
132
0
      return status;
133
0
    }
134
0
  } else if (netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC) {
135
0
    status = cli_rpc_pipe_open_schannel_with_creds(cli, table,
136
0
                     transport,
137
0
                     netlogon_creds,
138
0
                     remote_name,
139
0
                     remote_sockaddr,
140
0
                     &result);
141
0
    if (!NT_STATUS_IS_OK(status)) {
142
0
      TALLOC_FREE(frame);
143
0
      return status;
144
0
    }
145
0
  } else {
146
0
    status = cli_rpc_pipe_open_noauth(cli, table, &result);
147
0
    if (!NT_STATUS_IS_OK(status)) {
148
0
      TALLOC_FREE(frame);
149
0
      return status;
150
0
    }
151
0
  }
152
153
0
done:
154
0
  *presult = result;
155
0
  if (pcreds != NULL) {
156
0
    *pcreds = talloc_move(mem_ctx, &netlogon_creds);
157
0
  }
158
159
0
  TALLOC_FREE(frame);
160
0
  return NT_STATUS_OK;
161
0
}