Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : server side dcerpc core code
5 :
6 : Copyright (C) Andrew Tridgell 2003-2005
7 : Copyright (C) Stefan (metze) Metzmacher 2004-2005
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "auth/auth.h"
25 : #include "auth/gensec/gensec.h"
26 : #include "auth/credentials/credentials.h"
27 : #include "rpc_server/dcerpc_server.h"
28 : #include "rpc_server/dcerpc_server_proto.h"
29 : #include "param/param.h"
30 : #include "samba/service_stream.h"
31 : #include "lib/tsocket/tsocket.h"
32 : #include "lib/socket/socket.h"
33 : #include "samba/process_model.h"
34 : #include "lib/util/samba_modules.h"
35 : #include "lib/util/tevent_ntstatus.h"
36 : #include "lib/util/idtree_random.h"
37 :
38 : /*
39 : take a reference to an existing association group
40 : */
41 404 : static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(struct dcesrv_connection *conn,
42 : uint32_t id)
43 : {
44 404 : const struct dcesrv_endpoint *endpoint = conn->endpoint;
45 : enum dcerpc_transport_t transport =
46 404 : dcerpc_binding_get_transport(endpoint->ep_description);
47 : struct dcesrv_assoc_group *assoc_group;
48 404 : void *id_ptr = NULL;
49 :
50 : /* find an association group given a assoc_group_id */
51 404 : id_ptr = idr_find(conn->dce_ctx->assoc_groups_idr, id);
52 404 : if (id_ptr == NULL) {
53 144 : DBG_NOTICE("Failed to find assoc_group 0x%08x\n", id);
54 144 : return NULL;
55 : }
56 260 : assoc_group = talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
57 :
58 260 : if (assoc_group->transport != transport) {
59 : const char *at =
60 1 : derpc_transport_string_by_transport(
61 : assoc_group->transport);
62 : const char *ct =
63 1 : derpc_transport_string_by_transport(
64 : transport);
65 :
66 1 : DBG_NOTICE("assoc_group 0x%08x (transport %s) "
67 : "is not available on transport %s",
68 : id, at, ct);
69 1 : return NULL;
70 : }
71 :
72 259 : return talloc_reference(conn, assoc_group);
73 : }
74 :
75 17238 : static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
76 : {
77 : int ret;
78 17238 : ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
79 17238 : if (ret != 0) {
80 0 : DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
81 : assoc_group->id));
82 : }
83 17238 : return 0;
84 : }
85 :
86 : /*
87 : allocate a new association group
88 : */
89 16071 : static struct dcesrv_assoc_group *dcesrv_assoc_group_new(struct dcesrv_connection *conn)
90 : {
91 16071 : struct dcesrv_context *dce_ctx = conn->dce_ctx;
92 16071 : const struct dcesrv_endpoint *endpoint = conn->endpoint;
93 : enum dcerpc_transport_t transport =
94 16071 : dcerpc_binding_get_transport(endpoint->ep_description);
95 : struct dcesrv_assoc_group *assoc_group;
96 : int id;
97 :
98 16071 : assoc_group = talloc_zero(conn, struct dcesrv_assoc_group);
99 16071 : if (assoc_group == NULL) {
100 0 : return NULL;
101 : }
102 :
103 16071 : id = idr_get_new_random(
104 : dce_ctx->assoc_groups_idr, assoc_group, 1, UINT16_MAX);
105 16071 : if (id == -1) {
106 0 : talloc_free(assoc_group);
107 0 : DEBUG(0,(__location__ ": Out of association groups!\n"));
108 0 : return NULL;
109 : }
110 :
111 16071 : assoc_group->transport = transport;
112 16071 : assoc_group->id = id;
113 16071 : assoc_group->dce_ctx = dce_ctx;
114 :
115 16071 : talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
116 :
117 16071 : return assoc_group;
118 : }
119 :
120 16351 : NTSTATUS dcesrv_assoc_group_find_s4(
121 : struct dcesrv_call_state *call,
122 : void *private_data)
123 : {
124 : /*
125 : if provided, check the assoc_group is valid
126 : */
127 16351 : if (call->pkt.u.bind.assoc_group_id != 0) {
128 404 : call->conn->assoc_group =
129 404 : dcesrv_assoc_group_reference(call->conn,
130 : call->pkt.u.bind.assoc_group_id);
131 : } else {
132 15947 : call->conn->assoc_group = dcesrv_assoc_group_new(call->conn);
133 : }
134 :
135 : /*
136 : * The NETLOGON server does not use handles and so
137 : * there is no need to support association groups, but
138 : * we need to give back a number regardless.
139 : *
140 : * We have to do this when it is not run as a single process,
141 : * because then it can't see the other valid association
142 : * groups. We handle this genericly for all endpoints not
143 : * running in single process mode.
144 : *
145 : * We know which endpoint we are on even before checking the
146 : * iface UUID, so for simplicity we enforce the same policy
147 : * for all interfaces on the endpoint.
148 : *
149 : * This means that where NETLOGON
150 : * shares an endpoint (such as ncalrpc or if 'lsa over
151 : * netlogon' is set) we will still check association groups.
152 : *
153 : */
154 :
155 16351 : if (call->conn->assoc_group == NULL &&
156 145 : !call->conn->endpoint->use_single_process) {
157 124 : call->conn->assoc_group
158 124 : = dcesrv_assoc_group_new(call->conn);
159 : }
160 :
161 16351 : if (call->conn->assoc_group == NULL) {
162 : /* TODO Return correct status */
163 21 : return NT_STATUS_UNSUCCESSFUL;
164 : }
165 :
166 16330 : return NT_STATUS_OK;
167 : }
168 :
169 56 : void dcerpc_server_init(struct loadparm_context *lp_ctx)
170 : {
171 : static bool initialized;
172 : #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
173 : STATIC_dcerpc_server_MODULES_PROTO;
174 56 : init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
175 : init_module_fn *shared_init;
176 :
177 56 : if (initialized) {
178 0 : return;
179 : }
180 56 : initialized = true;
181 :
182 56 : shared_init = load_samba_modules(NULL, "dcerpc_server");
183 :
184 56 : run_init_functions(NULL, static_init);
185 56 : run_init_functions(NULL, shared_init);
186 :
187 56 : talloc_free(shared_init);
188 : }
189 :
190 : struct dcesrv_socket_context {
191 : const struct dcesrv_endpoint *endpoint;
192 : struct dcesrv_context *dcesrv_ctx;
193 : };
194 :
195 16375 : static void dcesrv_sock_accept(struct stream_connection *srv_conn)
196 : {
197 : NTSTATUS status;
198 : struct dcesrv_socket_context *dcesrv_sock =
199 16375 : talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
200 : enum dcerpc_transport_t transport =
201 16375 : dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
202 16375 : struct dcesrv_connection *dcesrv_conn = NULL;
203 : int ret;
204 16375 : struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
205 :
206 16375 : dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
207 :
208 16375 : if (!srv_conn->session_info) {
209 11462 : status = auth_anonymous_session_info(srv_conn,
210 : lp_ctx,
211 : &srv_conn->session_info);
212 11462 : if (!NT_STATUS_IS_OK(status)) {
213 0 : DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
214 : nt_errstr(status)));
215 0 : stream_terminate_connection(srv_conn, nt_errstr(status));
216 0 : return;
217 : }
218 : }
219 :
220 : /*
221 : * This fills in dcesrv_conn->endpoint with the endpoint
222 : * associated with the socket. From this point on we know
223 : * which (group of) services we are handling, but not the
224 : * specific interface.
225 : */
226 :
227 16375 : status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
228 : srv_conn,
229 : dcesrv_sock->endpoint,
230 : srv_conn->session_info,
231 : srv_conn->event.ctx,
232 : DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
233 : &dcesrv_conn);
234 16375 : if (!NT_STATUS_IS_OK(status)) {
235 0 : DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
236 : nt_errstr(status)));
237 0 : stream_terminate_connection(srv_conn, nt_errstr(status));
238 0 : return;
239 : }
240 :
241 16375 : dcesrv_conn->transport.private_data = srv_conn;
242 16375 : dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
243 16375 : dcesrv_conn->transport.terminate_connection = dcesrv_transport_terminate_connection_s4;
244 :
245 16375 : TALLOC_FREE(srv_conn->event.fde);
246 :
247 16375 : dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
248 16375 : if (!dcesrv_conn->send_queue) {
249 0 : status = NT_STATUS_NO_MEMORY;
250 0 : DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
251 : nt_errstr(status)));
252 0 : stream_terminate_connection(srv_conn, nt_errstr(status));
253 0 : return;
254 : }
255 :
256 16375 : if (transport == NCACN_NP) {
257 4913 : dcesrv_conn->stream = talloc_move(dcesrv_conn,
258 : &srv_conn->tstream);
259 : } else {
260 11462 : ret = tstream_bsd_existing_socket(dcesrv_conn,
261 : socket_get_fd(srv_conn->socket),
262 : &dcesrv_conn->stream);
263 11462 : if (ret == -1) {
264 0 : status = map_nt_error_from_unix_common(errno);
265 0 : DEBUG(0, ("dcesrv_sock_accept: "
266 : "failed to setup tstream: %s\n",
267 : nt_errstr(status)));
268 0 : stream_terminate_connection(srv_conn, nt_errstr(status));
269 0 : return;
270 : }
271 11462 : socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
272 : }
273 :
274 16375 : dcesrv_conn->local_address = srv_conn->local_address;
275 16375 : dcesrv_conn->remote_address = srv_conn->remote_address;
276 :
277 16375 : if (transport == NCALRPC) {
278 : uid_t uid;
279 : gid_t gid;
280 : int sock_fd;
281 :
282 1458 : sock_fd = socket_get_fd(srv_conn->socket);
283 1458 : if (sock_fd == -1) {
284 0 : stream_terminate_connection(
285 : srv_conn, "socket_get_fd failed\n");
286 0 : return;
287 : }
288 :
289 1458 : ret = getpeereid(sock_fd, &uid, &gid);
290 1458 : if (ret == -1) {
291 0 : status = map_nt_error_from_unix_common(errno);
292 0 : DEBUG(0, ("dcesrv_sock_accept: "
293 : "getpeereid() failed for NCALRPC: %s\n",
294 : nt_errstr(status)));
295 0 : stream_terminate_connection(srv_conn, nt_errstr(status));
296 0 : return;
297 : }
298 1458 : if (uid == dcesrv_conn->dce_ctx->initial_euid) {
299 1458 : struct tsocket_address *r = NULL;
300 :
301 1458 : ret = tsocket_address_unix_from_path(dcesrv_conn,
302 : AS_SYSTEM_MAGIC_PATH_TOKEN,
303 : &r);
304 1458 : if (ret == -1) {
305 0 : status = map_nt_error_from_unix_common(errno);
306 0 : DEBUG(0, ("dcesrv_sock_accept: "
307 : "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
308 : nt_errstr(status)));
309 0 : stream_terminate_connection(srv_conn, nt_errstr(status));
310 0 : return;
311 : }
312 1458 : dcesrv_conn->remote_address = r;
313 : }
314 : }
315 :
316 16375 : srv_conn->private_data = dcesrv_conn;
317 :
318 16375 : status = dcesrv_connection_loop_start(dcesrv_conn);
319 16375 : if (!NT_STATUS_IS_OK(status)) {
320 0 : DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
321 : nt_errstr(status)));
322 0 : stream_terminate_connection(srv_conn, nt_errstr(status));
323 0 : return;
324 : }
325 :
326 16375 : return;
327 : }
328 :
329 0 : static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
330 : {
331 0 : struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
332 : struct dcesrv_connection);
333 0 : dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
334 0 : }
335 :
336 0 : static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
337 : {
338 0 : struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
339 : struct dcesrv_connection);
340 0 : dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
341 0 : }
342 :
343 :
344 : static const struct stream_server_ops dcesrv_stream_ops = {
345 : .name = "rpc",
346 : .accept_connection = dcesrv_sock_accept,
347 : .recv_handler = dcesrv_sock_recv,
348 : .send_handler = dcesrv_sock_send,
349 : };
350 :
351 0 : static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
352 : struct loadparm_context *lp_ctx,
353 : struct dcesrv_endpoint *e,
354 : struct tevent_context *event_ctx,
355 : const struct model_ops *model_ops,
356 : void *process_context)
357 : {
358 : struct dcesrv_socket_context *dcesrv_sock;
359 0 : uint16_t port = 1;
360 : NTSTATUS status;
361 : const char *endpoint;
362 :
363 0 : dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
364 0 : NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
365 :
366 : /* remember the endpoint of this socket */
367 0 : dcesrv_sock->endpoint = e;
368 0 : dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
369 :
370 0 : endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
371 :
372 0 : status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
373 : model_ops, &dcesrv_stream_ops,
374 : "unix", endpoint, &port,
375 : lpcfg_socket_options(lp_ctx),
376 : dcesrv_sock, process_context);
377 0 : if (!NT_STATUS_IS_OK(status)) {
378 0 : DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
379 : endpoint, nt_errstr(status)));
380 : }
381 :
382 0 : return status;
383 : }
384 :
385 118 : static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
386 : struct loadparm_context *lp_ctx,
387 : struct dcesrv_endpoint *e,
388 : struct tevent_context *event_ctx,
389 : const struct model_ops *model_ops,
390 : void *process_context)
391 : {
392 : struct dcesrv_socket_context *dcesrv_sock;
393 118 : uint16_t port = 1;
394 : char *full_path;
395 : NTSTATUS status;
396 : const char *endpoint;
397 :
398 118 : endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
399 :
400 118 : if (endpoint == NULL) {
401 : /*
402 : * No identifier specified: use DEFAULT.
403 : *
404 : * TODO: DO NOT hardcode this value anywhere else. Rather, specify
405 : * no endpoint and let the epmapper worry about it.
406 : */
407 60 : endpoint = "DEFAULT";
408 60 : status = dcerpc_binding_set_string_option(e->ep_description,
409 : "endpoint",
410 : endpoint);
411 60 : if (!NT_STATUS_IS_OK(status)) {
412 0 : DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
413 : nt_errstr(status)));
414 0 : return status;
415 : }
416 : }
417 :
418 118 : full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
419 : endpoint);
420 :
421 118 : dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
422 118 : NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
423 :
424 : /* remember the endpoint of this socket */
425 118 : dcesrv_sock->endpoint = e;
426 118 : dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
427 :
428 118 : status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
429 : model_ops, &dcesrv_stream_ops,
430 : "unix", full_path, &port,
431 : lpcfg_socket_options(lp_ctx),
432 : dcesrv_sock, process_context);
433 118 : if (!NT_STATUS_IS_OK(status)) {
434 0 : DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
435 : endpoint, full_path, nt_errstr(status)));
436 : }
437 118 : return status;
438 : }
439 :
440 692 : static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
441 : struct loadparm_context *lp_ctx,
442 : struct dcesrv_endpoint *e,
443 : struct tevent_context *event_ctx,
444 : const struct model_ops *model_ops,
445 : void *process_context)
446 : {
447 : struct dcesrv_socket_context *dcesrv_sock;
448 : NTSTATUS status;
449 : const char *endpoint;
450 :
451 692 : endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
452 692 : if (endpoint == NULL) {
453 0 : DEBUG(0, ("Endpoint mandatory for named pipes\n"));
454 0 : return NT_STATUS_INVALID_PARAMETER;
455 : }
456 :
457 692 : dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
458 692 : NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
459 :
460 : /* remember the endpoint of this socket */
461 692 : dcesrv_sock->endpoint = e;
462 692 : dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
463 :
464 692 : status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
465 : model_ops, &dcesrv_stream_ops,
466 : endpoint,
467 : dcesrv_sock, process_context);
468 692 : if (!NT_STATUS_IS_OK(status)) {
469 0 : DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
470 : endpoint, nt_errstr(status)));
471 0 : return status;
472 : }
473 :
474 692 : return NT_STATUS_OK;
475 : }
476 :
477 : /*
478 : add a socket address to the list of events, one event per dcerpc endpoint
479 : */
480 340 : static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
481 : struct dcesrv_endpoint *e,
482 : struct tevent_context *event_ctx,
483 : const struct model_ops *model_ops,
484 : const char *address,
485 : void *process_context)
486 : {
487 : struct dcesrv_socket_context *dcesrv_sock;
488 340 : uint16_t port = 0;
489 : NTSTATUS status;
490 : const char *endpoint;
491 : char port_str[6];
492 :
493 340 : endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
494 340 : if (endpoint != NULL) {
495 282 : port = atoi(endpoint);
496 : }
497 :
498 340 : dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
499 340 : NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
500 :
501 : /* remember the endpoint of this socket */
502 340 : dcesrv_sock->endpoint = e;
503 340 : dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
504 :
505 340 : status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
506 : model_ops, &dcesrv_stream_ops,
507 : "ip", address, &port,
508 : lpcfg_socket_options(dce_ctx->lp_ctx),
509 : dcesrv_sock, process_context);
510 340 : if (!NT_STATUS_IS_OK(status)) {
511 : struct dcesrv_if_list *iface;
512 0 : DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
513 : address, port));
514 0 : for (iface = e->interface_list; iface; iface = iface->next) {
515 0 : DEBUGADD(0, ("%s ", iface->iface->name));
516 : }
517 0 : DEBUGADD(0, ("failed - %s\n",
518 : nt_errstr(status)));
519 0 : return status;
520 : }
521 :
522 340 : snprintf(port_str, sizeof(port_str), "%u", port);
523 :
524 340 : status = dcerpc_binding_set_string_option(e->ep_description,
525 : "endpoint", port_str);
526 340 : if (!NT_STATUS_IS_OK(status)) {
527 0 : DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
528 : port_str, nt_errstr(status)));
529 0 : return status;
530 : } else {
531 : struct dcesrv_if_list *iface;
532 340 : DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
533 : address, port_str));
534 2284 : for (iface = e->interface_list; iface; iface = iface->next) {
535 1944 : DEBUGADD(4, ("%s ", iface->iface->name));
536 : }
537 340 : DEBUGADD(4, ("\n"));
538 : }
539 :
540 340 : return NT_STATUS_OK;
541 : }
542 :
543 : #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
544 :
545 170 : static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
546 : struct loadparm_context *lp_ctx,
547 : struct dcesrv_endpoint *e,
548 : struct tevent_context *event_ctx,
549 : const struct model_ops *model_ops,
550 : void *process_context)
551 : {
552 : NTSTATUS status;
553 :
554 : /* Add TCP/IP sockets */
555 170 : if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
556 : int num_interfaces;
557 : int i;
558 : struct interface *ifaces;
559 :
560 0 : load_interface_list(dce_ctx, lp_ctx, &ifaces);
561 :
562 0 : num_interfaces = iface_list_count(ifaces);
563 0 : for(i = 0; i < num_interfaces; i++) {
564 0 : const char *address = iface_list_n_ip(ifaces, i);
565 0 : status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
566 : model_ops, address,
567 : process_context);
568 0 : NT_STATUS_NOT_OK_RETURN(status);
569 : }
570 : } else {
571 : char **wcard;
572 : size_t i;
573 170 : size_t num_binds = 0;
574 170 : wcard = iface_list_wildcard(dce_ctx);
575 170 : NT_STATUS_HAVE_NO_MEMORY(wcard);
576 510 : for (i=0; wcard[i]; i++) {
577 340 : status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
578 340 : model_ops, wcard[i],
579 : process_context);
580 340 : if (NT_STATUS_IS_OK(status)) {
581 340 : num_binds++;
582 : }
583 : }
584 170 : talloc_free(wcard);
585 170 : if (num_binds == 0) {
586 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
587 : }
588 : }
589 :
590 170 : return NT_STATUS_OK;
591 : }
592 :
593 980 : NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
594 : struct loadparm_context *lp_ctx,
595 : struct dcesrv_endpoint *e,
596 : struct tevent_context *event_ctx,
597 : const struct model_ops *model_ops,
598 : void *process_context)
599 : {
600 : enum dcerpc_transport_t transport =
601 980 : dcerpc_binding_get_transport(e->ep_description);
602 :
603 980 : switch (transport) {
604 0 : case NCACN_UNIX_STREAM:
605 0 : return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
606 : model_ops, process_context);
607 :
608 118 : case NCALRPC:
609 118 : return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
610 : model_ops, process_context);
611 :
612 170 : case NCACN_IP_TCP:
613 170 : return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
614 : model_ops, process_context);
615 :
616 692 : case NCACN_NP:
617 692 : return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
618 : model_ops, process_context);
619 :
620 0 : default:
621 0 : return NT_STATUS_NOT_SUPPORTED;
622 : }
623 : }
624 :
625 45331 : _PUBLIC_ struct imessaging_context *dcesrv_imessaging_context(
626 : struct dcesrv_connection *conn)
627 : {
628 : struct stream_connection *srv_conn =
629 45331 : talloc_get_type_abort(conn->transport.private_data,
630 : struct stream_connection);
631 45331 : return srv_conn->msg_ctx;
632 : }
633 :
634 0 : _PUBLIC_ struct server_id dcesrv_server_id(struct dcesrv_connection *conn)
635 : {
636 : struct stream_connection *srv_conn =
637 0 : talloc_get_type_abort(conn->transport.private_data,
638 : struct stream_connection);
639 0 : return srv_conn->server_id;
640 : }
641 :
642 10173 : void log_successful_dcesrv_authz_event(
643 : struct dcesrv_call_state *call,
644 : void *private_data)
645 : {
646 10173 : struct dcesrv_auth *auth = call->auth_state;
647 : enum dcerpc_transport_t transport =
648 10173 : dcerpc_binding_get_transport(call->conn->endpoint->ep_description);
649 : struct imessaging_context *imsg_ctx =
650 10173 : dcesrv_imessaging_context(call->conn);
651 10173 : const char *auth_type = derpc_transport_string_by_transport(transport);
652 10173 : const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
653 :
654 10173 : if (transport == NCACN_NP) {
655 3893 : transport_protection = AUTHZ_TRANSPORT_PROTECTION_SMB;
656 : }
657 :
658 : /*
659 : * Log the authorization to this RPC interface. This
660 : * covered ncacn_np pass-through auth, and anonymous
661 : * DCE/RPC (eg epmapper, netlogon etc)
662 : */
663 10173 : log_successful_authz_event(imsg_ctx,
664 10173 : call->conn->dce_ctx->lp_ctx,
665 10173 : call->conn->remote_address,
666 10173 : call->conn->local_address,
667 : "DCE/RPC",
668 : auth_type,
669 : transport_protection,
670 : auth->session_info);
671 :
672 10173 : auth->auth_audited = true;
673 10173 : }
674 :
675 6853 : NTSTATUS dcesrv_gensec_prepare(
676 : TALLOC_CTX *mem_ctx,
677 : struct dcesrv_call_state *call,
678 : struct gensec_security **out,
679 : void *private_data)
680 : {
681 6853 : struct cli_credentials *server_creds = NULL;
682 : struct imessaging_context *imsg_ctx =
683 6853 : dcesrv_imessaging_context(call->conn);
684 : bool ok;
685 :
686 6853 : server_creds = cli_credentials_init_server(call->auth_state,
687 6853 : call->conn->dce_ctx->lp_ctx);
688 6853 : if (server_creds == NULL) {
689 0 : DEBUG(1, ("Failed to init server credentials\n"));
690 0 : return NT_STATUS_NO_MEMORY;
691 : }
692 : /* This is required for ncalrpc_as_system. */
693 6853 : ok = cli_credentials_set_kerberos_state(server_creds,
694 : CRED_USE_KERBEROS_DESIRED,
695 : CRED_SPECIFIED);
696 6853 : if (!ok) {
697 0 : DBG_WARNING("Failed to set kerberos state\n");
698 0 : return NT_STATUS_INTERNAL_ERROR;
699 : }
700 :
701 6853 : return samba_server_gensec_start(mem_ctx,
702 : call->event_ctx,
703 : imsg_ctx,
704 6853 : call->conn->dce_ctx->lp_ctx,
705 : server_creds,
706 : NULL,
707 : out);
708 : }
709 :
710 16347 : void dcesrv_transport_terminate_connection_s4(struct dcesrv_connection *dce_conn,
711 : const char *reason)
712 : {
713 : struct stream_connection *srv_conn =
714 16347 : talloc_get_type_abort(dce_conn->transport.private_data,
715 : struct stream_connection);
716 16347 : stream_terminate_connection(srv_conn, reason);
717 16036 : }
|