Coverage Report

Created: 2025-07-23 07:04

/src/samba/source3/rpc_server/rpc_ncacn_np.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *  Unix SMB/CIFS implementation.
3
 *  RPC Pipe client / server routines
4
 *  Copyright (C) Andrew Tridgell              1992-1998,
5
 *  Largely re-written : 2005
6
 *  Copyright (C) Jeremy Allison    1998 - 2005
7
 *  Copyright (C) Simo Sorce      2010
8
 *  Copyright (C) Andrew Bartlett   2011
9
 *
10
 *  This program is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 3 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  This program is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
#include "includes.h"
25
#include "rpc_client/cli_pipe.h"
26
#include "rpc_dce.h"
27
#include "../libcli/named_pipe_auth/npa_tstream.h"
28
#include "rpc_server/rpc_ncacn_np.h"
29
#include "librpc/gen_ndr/netlogon.h"
30
#include "librpc/gen_ndr/auth.h"
31
#include "../auth/auth_sam_reply.h"
32
#include "../auth/auth_util.h"
33
#include "auth.h"
34
#include "rpc_server/rpc_pipes.h"
35
#include "../lib/tsocket/tsocket.h"
36
#include "../lib/util/tevent_ntstatus.h"
37
#include "rpc_server/rpc_config.h"
38
#include "librpc/ndr/ndr_table.h"
39
#include "rpc_server/rpc_server.h"
40
#include "librpc/rpc/dcerpc_util.h"
41
42
#undef DBGC_CLASS
43
0
#define DBGC_CLASS DBGC_RPC_SRV
44
45
struct np_proxy_state {
46
  uint16_t file_type;
47
  uint16_t device_state;
48
  uint64_t allocation_size;
49
  struct tstream_context *npipe;
50
  struct tevent_queue *read_queue;
51
  struct tevent_queue *write_queue;
52
};
53
54
struct npa_state *npa_state_init(TALLOC_CTX *mem_ctx)
55
0
{
56
0
  struct npa_state *npa;
57
58
0
  npa = talloc_zero(mem_ctx, struct npa_state);
59
0
  if (npa == NULL) {
60
0
    return NULL;
61
0
  }
62
63
0
  npa->read_queue = tevent_queue_create(npa, "npa_cli_read");
64
0
  if (npa->read_queue == NULL) {
65
0
    DEBUG(0, ("tevent_queue_create failed\n"));
66
0
    goto fail;
67
0
  }
68
69
0
  npa->write_queue = tevent_queue_create(npa, "npa_cli_write");
70
0
  if (npa->write_queue == NULL) {
71
0
    DEBUG(0, ("tevent_queue_create failed\n"));
72
0
    goto fail;
73
0
  }
74
75
0
  return npa;
76
0
fail:
77
0
  talloc_free(npa);
78
0
  return NULL;
79
0
}
80
81
/**
82
 * @brief Create a new DCERPC Binding Handle which uses a local dispatch function.
83
 *
84
 * @param[in]  mem_ctx  The memory context to use.
85
 *
86
 * @param[in]  ndr_table Normally the ndr_table_<name>.
87
 *
88
 * @param[in]  remote_address The info about the connected client.
89
 *
90
 * @param[in]  serversupplied_info The server supplied authentication function.
91
 *
92
 * @param[in]  msg_ctx   The messaging context that can be used by the server
93
 *
94
 * @param[out] binding_handle  A pointer to store the connected
95
 *                             dcerpc_binding_handle
96
 *
97
 * @return              NT_STATUS_OK on success, a corresponding NT status if an
98
 *                      error occurred.
99
 *
100
 * @code
101
 *   struct dcerpc_binding_handle *winreg_binding;
102
 *   NTSTATUS status;
103
 *
104
 *   status = rpcint_binding_handle(tmp_ctx,
105
 *                                  &ndr_table_winreg,
106
 *                                  p->remote_address,
107
 *                                  p->session_info,
108
 *                                  p->msg_ctx
109
 *                                  &winreg_binding);
110
 * @endcode
111
 */
112
NTSTATUS rpcint_binding_handle(TALLOC_CTX *mem_ctx,
113
             const struct ndr_interface_table *ndr_table,
114
             const struct tsocket_address *remote_address,
115
             const struct tsocket_address *local_address,
116
             const struct auth_session_info *session_info,
117
             struct messaging_context *msg_ctx,
118
             struct dcerpc_binding_handle **binding_handle)
119
0
{
120
0
  struct rpc_pipe_client *rpccli = NULL;
121
0
  NTSTATUS status;
122
123
0
  status = rpc_pipe_open_local_np(
124
0
    mem_ctx,
125
0
    ndr_table,
126
0
    NULL,
127
0
    remote_address,
128
0
    NULL,
129
0
    local_address,
130
0
    session_info,
131
0
    &rpccli);
132
0
  if (!NT_STATUS_IS_OK(status)) {
133
0
    DBG_DEBUG("rpc_pipe_open_local_np failed: %s\n",
134
0
        nt_errstr(status));
135
0
    goto fail;
136
0
  }
137
138
0
  *binding_handle = rpccli->binding_handle;
139
0
  return NT_STATUS_OK;
140
0
fail:
141
0
  TALLOC_FREE(rpccli);
142
0
  return status;
143
0
}
144
145
/**
146
 * @brief Create a new RPC client context which uses a local dispatch function
147
 *    or a remote transport, depending on rpc_server configuration for the
148
 *    specific service.
149
 *
150
 * @param[in]  mem_ctx  The memory context to use.
151
 *
152
 * @param[in]  abstract_syntax Normally the syntax_id of the autogenerated
153
 *                             ndr_table_<name>.
154
 *
155
 * @param[in]  serversupplied_info The server supplied authentication function.
156
 *
157
 * @param[in]  remote_address The client address information.
158
 *
159
 * @param[in]  msg_ctx  The messaging context to use.
160
 *
161
 * @param[out] presult  A pointer to store the connected rpc client pipe.
162
 *
163
 * @return              NT_STATUS_OK on success, a corresponding NT status if an
164
 *                      error occurred.
165
 *
166
 * @code
167
 *   struct rpc_pipe_client *winreg_pipe;
168
 *   NTSTATUS status;
169
 *
170
 *   status = rpc_pipe_open_interface(tmp_ctx,
171
 *                                    &ndr_table_winreg.syntax_id,
172
 *                                    p->session_info,
173
 *                                    remote_address,
174
 *                                    &winreg_pipe);
175
 * @endcode
176
 */
177
178
NTSTATUS rpc_pipe_open_interface(TALLOC_CTX *mem_ctx,
179
         const struct ndr_interface_table *table,
180
         const struct auth_session_info *session_info,
181
         const struct tsocket_address *remote_address,
182
         const struct tsocket_address *local_address,
183
         struct messaging_context *msg_ctx,
184
         struct rpc_pipe_client **cli_pipe)
185
0
{
186
0
  struct rpc_pipe_client *cli = NULL;
187
0
  NTSTATUS status;
188
189
0
  if (cli_pipe != NULL) {
190
0
    if (rpccli_is_connected(*cli_pipe)) {
191
0
      return NT_STATUS_OK;
192
0
    } else {
193
0
      TALLOC_FREE(*cli_pipe);
194
0
    }
195
0
  }
196
197
0
  status = rpc_pipe_open_local_np(
198
0
    mem_ctx,
199
0
    table,
200
0
    NULL,
201
0
    remote_address,
202
0
    NULL,
203
0
    local_address,
204
0
    session_info,
205
0
    &cli);
206
0
  if (!NT_STATUS_IS_OK(status)) {
207
0
    DBG_ERR("Could not connect to %s pipe: %s\n",
208
0
      table->name,
209
0
      nt_errstr(status));
210
0
    return status;
211
0
  }
212
213
0
  if (NT_STATUS_IS_OK(status) && cli_pipe != NULL) {
214
0
    *cli_pipe = cli;
215
0
  }
216
0
  return status;
217
0
}