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