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 : Copyright (C) Samuel Cabrero <scabrero@samba.org> 2019
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 "librpc/rpc/dcesrv_core.h"
26 : #include "librpc/rpc/dcesrv_core_proto.h"
27 : #include "librpc/rpc/dcerpc_util.h"
28 : #include "librpc/gen_ndr/auth.h"
29 : #include "auth/gensec/gensec.h"
30 : #include "lib/util/dlinklist.h"
31 : #include "libcli/security/security.h"
32 : #include "param/param.h"
33 : #include "lib/tsocket/tsocket.h"
34 : #include "librpc/gen_ndr/ndr_dcerpc.h"
35 : #include "lib/util/tevent_ntstatus.h"
36 : #include "system/network.h"
37 : #include "lib/util/idtree_random.h"
38 : #include "nsswitch/winbind_client.h"
39 :
40 : /**
41 : * @file
42 : * @brief DCERPC server
43 : */
44 :
45 : #undef DBGC_CLASS
46 : #define DBGC_CLASS DBGC_RPC_SRV
47 :
48 : #undef strcasecmp
49 :
50 : static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
51 : const struct dcerpc_bind *b,
52 : struct dcerpc_ack_ctx *ack_ctx_list);
53 :
54 : /*
55 : see if two endpoints match
56 : */
57 197977 : static bool endpoints_match(const struct dcerpc_binding *ep1,
58 : const struct dcerpc_binding *ep2)
59 : {
60 1428 : enum dcerpc_transport_t t1;
61 1428 : enum dcerpc_transport_t t2;
62 1428 : const char *e1;
63 1428 : const char *e2;
64 :
65 197977 : t1 = dcerpc_binding_get_transport(ep1);
66 197977 : t2 = dcerpc_binding_get_transport(ep2);
67 :
68 197977 : e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
69 197977 : e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
70 :
71 197977 : if (t1 != t2) {
72 124891 : return false;
73 : }
74 :
75 72114 : if (!e1 || !e2) {
76 8542 : return e1 == e2;
77 : }
78 :
79 63572 : if (strcasecmp(e1, e2) != 0) {
80 27249 : return false;
81 : }
82 :
83 36307 : return true;
84 : }
85 :
86 : /*
87 : find an endpoint in the dcesrv_context
88 : */
89 42547 : _PUBLIC_ NTSTATUS dcesrv_find_endpoint(struct dcesrv_context *dce_ctx,
90 : const struct dcerpc_binding *ep_description,
91 : struct dcesrv_endpoint **_out)
92 : {
93 42547 : struct dcesrv_endpoint *ep = NULL;
94 150437 : for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
95 146252 : if (endpoints_match(ep->ep_description, ep_description)) {
96 38362 : *_out = ep;
97 38362 : return NT_STATUS_OK;
98 : }
99 : }
100 4185 : return NT_STATUS_NOT_FOUND;
101 : }
102 :
103 : /*
104 : find a registered context_id from a bind or alter_context
105 : */
106 897669 : static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
107 : uint16_t context_id)
108 : {
109 7723 : struct dcesrv_connection_context *c;
110 897882 : for (c=conn->contexts;c;c=c->next) {
111 842636 : if (c->context_id == context_id) return c;
112 : }
113 54386 : return NULL;
114 : }
115 :
116 : /*
117 : find the interface operations on any endpoint with this binding
118 : */
119 7670 : static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
120 : struct dcerpc_binding *binding,
121 : const struct dcesrv_interface *iface)
122 : {
123 78 : struct dcesrv_endpoint *ep;
124 59395 : for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
125 51725 : if (endpoints_match(ep->ep_description, binding)) {
126 3502 : const struct dcesrv_interface *ret = NULL;
127 :
128 3502 : ret = find_interface_by_syntax_id(
129 : ep, &iface->syntax_id);
130 3502 : if (ret != NULL) {
131 0 : return ret;
132 : }
133 : }
134 : }
135 7592 : return NULL;
136 : }
137 :
138 : /*
139 : find the interface operations on an endpoint by uuid
140 : */
141 65210 : _PUBLIC_ const struct dcesrv_interface *find_interface_by_syntax_id(
142 : const struct dcesrv_endpoint *endpoint,
143 : const struct ndr_syntax_id *interface)
144 : {
145 1021 : struct dcesrv_if_list *ifl;
146 150731 : for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
147 147178 : if (ndr_syntax_id_equal(&ifl->iface->syntax_id, interface)) {
148 61657 : return ifl->iface;
149 : }
150 : }
151 3503 : return NULL;
152 : }
153 :
154 : /*
155 : find the earlier parts of a fragmented call awaiting reassembly
156 : */
157 16659 : static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint32_t call_id)
158 : {
159 83 : struct dcesrv_call_state *c;
160 16708 : for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
161 16621 : if (c->pkt.call_id == call_id) {
162 16489 : return c;
163 : }
164 : }
165 87 : return NULL;
166 : }
167 :
168 : /*
169 : * register a principal for an auth_type
170 : *
171 : * In order to get used in dcesrv_mgmt_inq_princ_name()
172 : */
173 876 : _PUBLIC_ NTSTATUS dcesrv_auth_type_principal_register(struct dcesrv_context *dce_ctx,
174 : enum dcerpc_AuthType auth_type,
175 : const char *principal_name)
176 : {
177 876 : const char *existing = NULL;
178 876 : struct dcesrv_ctx_principal *p = NULL;
179 :
180 876 : existing = dcesrv_auth_type_principal_find(dce_ctx, auth_type);
181 876 : if (existing != NULL) {
182 0 : DBG_ERR("auth_type[%u] already registered with principal_name[%s]\n",
183 : auth_type, existing);
184 0 : return NT_STATUS_ALREADY_REGISTERED;
185 : }
186 :
187 876 : p = talloc_zero(dce_ctx, struct dcesrv_ctx_principal);
188 876 : if (p == NULL) {
189 0 : return NT_STATUS_NO_MEMORY;
190 : }
191 876 : p->auth_type = auth_type;
192 876 : p->principal_name = talloc_strdup(p, principal_name);
193 876 : if (p->principal_name == NULL) {
194 0 : TALLOC_FREE(p);
195 0 : return NT_STATUS_NO_MEMORY;
196 : }
197 :
198 876 : DLIST_ADD_END(dce_ctx->principal_list, p);
199 876 : return NT_STATUS_OK;
200 : }
201 :
202 37522 : _PUBLIC_ const char *dcesrv_auth_type_principal_find(struct dcesrv_context *dce_ctx,
203 : enum dcerpc_AuthType auth_type)
204 : {
205 37522 : struct dcesrv_ctx_principal *p = NULL;
206 :
207 67291 : for (p = dce_ctx->principal_list; p != NULL; p = p->next) {
208 31196 : if (p->auth_type == auth_type) {
209 1427 : return p->principal_name;
210 : }
211 : }
212 :
213 36095 : return NULL;
214 : }
215 :
216 326 : _PUBLIC_ NTSTATUS dcesrv_register_default_auth_types(struct dcesrv_context *dce_ctx,
217 : const char *principal)
218 : {
219 326 : const char *realm = lpcfg_realm(dce_ctx->lp_ctx);
220 0 : NTSTATUS status;
221 :
222 326 : status = dcesrv_auth_type_principal_register(dce_ctx,
223 : DCERPC_AUTH_TYPE_NTLMSSP,
224 : principal);
225 326 : if (!NT_STATUS_IS_OK(status)) {
226 0 : return status;
227 : }
228 326 : status = dcesrv_auth_type_principal_register(dce_ctx,
229 : DCERPC_AUTH_TYPE_SPNEGO,
230 : principal);
231 326 : if (!NT_STATUS_IS_OK(status)) {
232 0 : return status;
233 : }
234 :
235 326 : if (realm == NULL || realm[0] == '\0') {
236 209 : return NT_STATUS_OK;
237 : }
238 :
239 117 : status = dcesrv_auth_type_principal_register(dce_ctx,
240 : DCERPC_AUTH_TYPE_KRB5,
241 : principal);
242 117 : if (!NT_STATUS_IS_OK(status)) {
243 0 : return status;
244 : }
245 :
246 117 : return NT_STATUS_OK;
247 : }
248 :
249 300 : _PUBLIC_ NTSTATUS dcesrv_register_default_auth_types_machine_principal(struct dcesrv_context *dce_ctx)
250 : {
251 300 : const char *realm = lpcfg_realm(dce_ctx->lp_ctx);
252 300 : const char *nb = lpcfg_netbios_name(dce_ctx->lp_ctx);
253 300 : char *principal = NULL;
254 0 : NTSTATUS status;
255 :
256 300 : if (realm == NULL || realm[0] == '\0') {
257 191 : return dcesrv_register_default_auth_types(dce_ctx, "");
258 : }
259 :
260 109 : principal = talloc_asprintf(talloc_tos(), "%s$@%s", nb, realm);
261 109 : if (principal == NULL) {
262 0 : return NT_STATUS_NO_MEMORY;
263 : }
264 :
265 109 : status = dcesrv_register_default_auth_types(dce_ctx, principal);
266 109 : TALLOC_FREE(principal);
267 109 : if (!NT_STATUS_IS_OK(status)) {
268 0 : return status;
269 : }
270 :
271 109 : return NT_STATUS_OK;
272 : }
273 :
274 : /*
275 : register an interface on an endpoint
276 :
277 : An endpoint is one unix domain socket (for ncalrpc), one TCP port
278 : (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
279 :
280 : Each endpoint can have many interfaces such as netlogon, lsa or
281 : samr. Some have essentially the full set.
282 :
283 : This is driven from the set of interfaces listed in each IDL file
284 : via the PIDL generated *__op_init_server() functions.
285 : */
286 7670 : _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
287 : const char *ep_name,
288 : const char *ncacn_np_secondary_endpoint,
289 : const struct dcesrv_interface *iface,
290 : const struct security_descriptor *sd)
291 : {
292 7670 : struct dcerpc_binding *binding = NULL;
293 7670 : struct dcerpc_binding *binding2 = NULL;
294 78 : NTSTATUS ret;
295 :
296 7670 : ret = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
297 7670 : if (NT_STATUS_IS_ERR(ret)) {
298 0 : DBG_ERR("Trouble parsing binding string '%s'\n", ep_name);
299 0 : goto out;
300 : }
301 :
302 7670 : if (ncacn_np_secondary_endpoint != NULL) {
303 1185 : ret = dcerpc_parse_binding(dce_ctx,
304 : ncacn_np_secondary_endpoint,
305 : &binding2);
306 1185 : if (NT_STATUS_IS_ERR(ret)) {
307 0 : DBG_ERR("Trouble parsing 2nd binding string '%s'\n",
308 : ncacn_np_secondary_endpoint);
309 0 : goto out;
310 : }
311 : }
312 :
313 7670 : ret = dcesrv_interface_register_b(dce_ctx,
314 : binding,
315 : binding2,
316 : iface,
317 : sd);
318 7670 : out:
319 7670 : TALLOC_FREE(binding);
320 7670 : TALLOC_FREE(binding2);
321 7670 : return ret;
322 : }
323 :
324 7670 : _PUBLIC_ NTSTATUS dcesrv_interface_register_b(struct dcesrv_context *dce_ctx,
325 : struct dcerpc_binding *binding,
326 : struct dcerpc_binding *binding2,
327 : const struct dcesrv_interface *iface,
328 : const struct security_descriptor *sd)
329 : {
330 78 : struct dcesrv_endpoint *ep;
331 78 : struct dcesrv_if_list *ifl;
332 7670 : bool add_ep = false;
333 78 : NTSTATUS status;
334 78 : enum dcerpc_transport_t transport;
335 7670 : char *ep_string = NULL;
336 7670 : bool use_single_process = true;
337 78 : const char *ep_process_string;
338 :
339 : /*
340 : * If we are not using handles, there is no need for force
341 : * this service into using a single process.
342 : *
343 : * However, due to the way we listen for RPC packets, we can
344 : * only do this if we have a single service per pipe or TCP
345 : * port, so we still force a single combined process for
346 : * ncalrpc.
347 : */
348 7670 : if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
349 192 : use_single_process = false;
350 : }
351 :
352 7670 : transport = dcerpc_binding_get_transport(binding);
353 7670 : if (transport == NCACN_IP_TCP) {
354 26 : int port;
355 :
356 : /*
357 : * First check if there is already a port specified, eg
358 : * for epmapper on ncacn_ip_tcp:[135]
359 : */
360 26 : const char *endpoint
361 2088 : = dcerpc_binding_get_string_option(binding,
362 : "endpoint");
363 2088 : if (endpoint == NULL) {
364 2020 : port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
365 1996 : "rpc server port", iface->name, 0);
366 :
367 : /*
368 : * For RPC services that are not set to use a single
369 : * process, we do not default to using the 'rpc server
370 : * port' because that would cause a double-bind on
371 : * that port.
372 : */
373 1996 : if (port == 0 && !use_single_process) {
374 0 : port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
375 : }
376 1996 : if (port != 0) {
377 2 : char port_str[6];
378 64 : snprintf(port_str, sizeof(port_str), "%u", port);
379 64 : status = dcerpc_binding_set_string_option(binding,
380 : "endpoint",
381 : port_str);
382 64 : if (!NT_STATUS_IS_OK(status)) {
383 0 : return status;
384 : }
385 : }
386 : }
387 : }
388 :
389 7670 : if (transport == NCACN_NP && binding2 != NULL) {
390 4 : enum dcerpc_transport_t transport2;
391 :
392 689 : transport2 = dcerpc_binding_get_transport(binding2);
393 689 : SMB_ASSERT(transport2 == transport);
394 : }
395 :
396 : /* see if the interface is already registered on the endpoint */
397 7670 : if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
398 0 : char *binding_string = dcerpc_binding_string(dce_ctx, binding);
399 0 : DBG_ERR("Interface '%s' already registered on endpoint '%s'\n",
400 : iface->name, binding_string);
401 0 : TALLOC_FREE(binding_string);
402 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
403 : }
404 :
405 : /* check if this endpoint exists
406 : */
407 7670 : status = dcesrv_find_endpoint(dce_ctx, binding, &ep);
408 7670 : if (NT_STATUS_IS_OK(status)) {
409 : /*
410 : * We want a new port on ncacn_ip_tcp for NETLOGON, so
411 : * it can be multi-process. Other processes can also
412 : * listen on distinct ports, if they have one forced
413 : * in the code above with eg 'rpc server port:drsuapi = 1027'
414 : *
415 : * If we have multiple endpoints on port 0, they each
416 : * get an epemeral port (currently by walking up from
417 : * 1024).
418 : *
419 : * Because one endpoint can only have one process
420 : * model, we add a new IP_TCP endpoint for each model.
421 : *
422 : * This works in conjunction with the forced overwrite
423 : * of ep->use_single_process below.
424 : */
425 3502 : if (ep->use_single_process != use_single_process
426 73 : && transport == NCACN_IP_TCP) {
427 0 : add_ep = true;
428 : }
429 : }
430 :
431 7670 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) || add_ep) {
432 4168 : ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
433 4168 : if (!ep) {
434 0 : return NT_STATUS_NO_MEMORY;
435 : }
436 4168 : ep->ep_description = dcerpc_binding_dup(ep, binding);
437 4168 : if (transport == NCACN_NP && binding2 != NULL) {
438 680 : ep->ep_2nd_description =
439 680 : dcerpc_binding_dup(ep, binding2);
440 : }
441 4168 : add_ep = true;
442 :
443 : /* add mgmt interface */
444 4168 : ifl = talloc_zero(ep, struct dcesrv_if_list);
445 4168 : if (!ifl) {
446 0 : TALLOC_FREE(ep);
447 0 : return NT_STATUS_NO_MEMORY;
448 : }
449 :
450 4168 : ifl->iface = talloc_memdup(ifl,
451 : dcesrv_get_mgmt_interface(),
452 : sizeof(struct dcesrv_interface));
453 4168 : if (ifl->iface == NULL) {
454 0 : talloc_free(ep);
455 0 : return NT_STATUS_NO_MEMORY;
456 : }
457 :
458 4168 : DLIST_ADD(ep->interface_list, ifl);
459 3502 : } else if (!NT_STATUS_IS_OK(status)) {
460 0 : DBG_NOTICE("Failed to find endpoint: %s\n", nt_errstr(status));
461 0 : return status;
462 : }
463 :
464 : /*
465 : * By default don't force into a single process, but if any
466 : * interface on this endpoint on this service uses handles
467 : * (most do), then we must force into single process mode
468 : *
469 : * By overwriting this each time a new interface is added to
470 : * this endpoint, we end up with the most restrictive setting.
471 : */
472 7670 : if (use_single_process) {
473 7478 : ep->use_single_process = true;
474 : }
475 :
476 : /* talloc a new interface list element */
477 7670 : ifl = talloc_zero(ep, struct dcesrv_if_list);
478 7670 : if (!ifl) {
479 0 : return NT_STATUS_NO_MEMORY;
480 : }
481 :
482 : /* copy the given interface struct to the one on the endpoints interface list */
483 7670 : ifl->iface = talloc_memdup(ifl,
484 : iface,
485 : sizeof(struct dcesrv_interface));
486 7670 : if (ifl->iface == NULL) {
487 0 : talloc_free(ep);
488 0 : return NT_STATUS_NO_MEMORY;
489 : }
490 :
491 : /* if we have a security descriptor given,
492 : * we should see if we can set it up on the endpoint
493 : */
494 7670 : if (sd != NULL) {
495 : /* if there's currently no security descriptor given on the endpoint
496 : * we try to set it
497 : */
498 0 : if (ep->sd == NULL) {
499 0 : ep->sd = security_descriptor_copy(ep, sd);
500 : }
501 :
502 : /* if now there's no security descriptor given on the endpoint
503 : * something goes wrong, either we failed to copy the security descriptor
504 : * or there was already one on the endpoint
505 : */
506 0 : if (ep->sd != NULL) {
507 0 : char *binding_string =
508 0 : dcerpc_binding_string(dce_ctx, binding);
509 0 : DBG_ERR("Interface '%s' failed to setup a security "
510 : "descriptor on endpoint '%s'\n",
511 : iface->name, binding_string);
512 0 : TALLOC_FREE(binding_string);
513 0 : if (add_ep) free(ep);
514 0 : free(ifl);
515 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
516 : }
517 : }
518 :
519 : /* finally add the interface on the endpoint */
520 7670 : DLIST_ADD(ep->interface_list, ifl);
521 :
522 : /* if it's a new endpoint add it to the dcesrv_context */
523 7670 : if (add_ep) {
524 4168 : DLIST_ADD(dce_ctx->endpoint_list, ep);
525 : }
526 :
527 : /* Re-get the string as we may have set a port */
528 7670 : ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
529 :
530 7670 : if (use_single_process) {
531 7406 : ep_process_string = "single process required";
532 : } else {
533 192 : ep_process_string = "multi process compatible";
534 : }
535 :
536 7670 : DBG_INFO("Interface '%s' registered on endpoint '%s' (%s)\n",
537 : iface->name, ep_string, ep_process_string);
538 7670 : TALLOC_FREE(ep_string);
539 :
540 7670 : return NT_STATUS_OK;
541 : }
542 :
543 12722 : static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth,
544 : DATA_BLOB *session_key)
545 : {
546 12722 : if (auth->session_info == NULL) {
547 0 : return NT_STATUS_NO_USER_SESSION_KEY;
548 : }
549 :
550 12722 : if (auth->session_info->session_key.length == 0) {
551 0 : return NT_STATUS_NO_USER_SESSION_KEY;
552 : }
553 :
554 12722 : *session_key = auth->session_info->session_key;
555 12722 : return NT_STATUS_OK;
556 : }
557 :
558 4868 : static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth,
559 : DATA_BLOB *session_key)
560 : {
561 4868 : if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
562 0 : return NT_STATUS_NO_USER_SESSION_KEY;
563 : }
564 :
565 4868 : return dcesrv_session_info_session_key(auth, session_key);
566 : }
567 :
568 113 : static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
569 : DATA_BLOB *session_key)
570 : {
571 113 : return dcerpc_generic_session_key(session_key);
572 : }
573 :
574 : /*
575 : * Fetch the authentication session key if available.
576 : *
577 : * This is the key generated by a gensec authentication.
578 : *
579 : */
580 7854 : _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
581 : DATA_BLOB *session_key)
582 : {
583 7854 : struct dcesrv_auth *auth = call->auth_state;
584 7854 : SMB_ASSERT(auth->auth_finished);
585 7854 : return dcesrv_session_info_session_key(auth, session_key);
586 : }
587 :
588 : /*
589 : * Fetch the transport session key if available.
590 : * Typically this is the SMB session key
591 : * or a fixed key for local transports.
592 : *
593 : * The key is always truncated to 16 bytes.
594 : */
595 4981 : _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
596 : DATA_BLOB *session_key)
597 : {
598 4981 : struct dcesrv_auth *auth = call->auth_state;
599 72 : NTSTATUS status;
600 :
601 4981 : SMB_ASSERT(auth->auth_finished);
602 :
603 4981 : if (auth->session_key_fn == NULL) {
604 0 : return NT_STATUS_NO_USER_SESSION_KEY;
605 : }
606 :
607 4981 : status = auth->session_key_fn(auth, session_key);
608 4981 : if (!NT_STATUS_IS_OK(status)) {
609 0 : return status;
610 : }
611 :
612 4981 : session_key->length = MIN(session_key->length, 16);
613 :
614 4981 : return NT_STATUS_OK;
615 : }
616 :
617 64273 : static struct dcesrv_auth *dcesrv_auth_create(struct dcesrv_connection *conn)
618 : {
619 64273 : const struct dcesrv_endpoint *ep = conn->endpoint;
620 1308 : enum dcerpc_transport_t transport =
621 64273 : dcerpc_binding_get_transport(ep->ep_description);
622 64273 : struct dcesrv_auth *auth = NULL;
623 :
624 64273 : auth = talloc_zero(conn, struct dcesrv_auth);
625 64273 : if (auth == NULL) {
626 0 : return NULL;
627 : }
628 :
629 64273 : switch (transport) {
630 44393 : case NCACN_NP:
631 44393 : auth->session_key_fn = dcesrv_remote_session_key;
632 44393 : break;
633 2559 : case NCALRPC:
634 : case NCACN_UNIX_STREAM:
635 2559 : auth->session_key_fn = dcesrv_local_fixed_session_key;
636 2559 : break;
637 16958 : default:
638 : /*
639 : * All other's get a NULL pointer, which
640 : * results in NT_STATUS_NO_USER_SESSION_KEY
641 : */
642 16958 : break;
643 : }
644 :
645 62965 : return auth;
646 : }
647 :
648 : /*
649 : connect to a dcerpc endpoint
650 : */
651 55355 : _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
652 : TALLOC_CTX *mem_ctx,
653 : const struct dcesrv_endpoint *ep,
654 : struct auth_session_info *session_info,
655 : struct tevent_context *event_ctx,
656 : uint32_t state_flags,
657 : struct dcesrv_connection **_p)
658 : {
659 55355 : struct dcesrv_auth *auth = NULL;
660 55355 : struct dcesrv_connection *p = NULL;
661 :
662 55355 : if (!session_info) {
663 0 : return NT_STATUS_ACCESS_DENIED;
664 : }
665 :
666 55355 : p = talloc_zero(mem_ctx, struct dcesrv_connection);
667 55355 : if (p == NULL) {
668 0 : goto nomem;
669 : }
670 :
671 55355 : p->dce_ctx = dce_ctx;
672 55355 : p->endpoint = ep;
673 55355 : p->packet_log_dir = lpcfg_parm_string(dce_ctx->lp_ctx,
674 : NULL,
675 : "dcesrv",
676 : "stubs directory");
677 55355 : p->event_ctx = event_ctx;
678 55355 : p->state_flags = state_flags;
679 55355 : p->allow_bind = true;
680 55355 : p->max_recv_frag = 5840;
681 55355 : p->max_xmit_frag = 5840;
682 55355 : p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
683 :
684 55355 : p->support_hdr_signing = lpcfg_parm_bool(dce_ctx->lp_ctx,
685 : NULL,
686 : "dcesrv",
687 : "header signing",
688 : true);
689 55355 : p->max_auth_states = lpcfg_parm_ulong(dce_ctx->lp_ctx,
690 : NULL,
691 : "dcesrv",
692 : "max auth states",
693 : 2049);
694 :
695 55355 : auth = dcesrv_auth_create(p);
696 55355 : if (auth == NULL) {
697 0 : goto nomem;
698 : }
699 :
700 55355 : auth->session_info = talloc_reference(auth, session_info);
701 55355 : if (auth->session_info == NULL) {
702 0 : goto nomem;
703 : }
704 :
705 55355 : p->default_auth_state = auth;
706 :
707 55355 : p->preferred_transfer = dce_ctx->preferred_transfer;
708 :
709 55355 : *_p = p;
710 55355 : return NT_STATUS_OK;
711 0 : nomem:
712 0 : TALLOC_FREE(p);
713 0 : return NT_STATUS_NO_MEMORY;
714 : }
715 :
716 : /*
717 : move a call from an existing linked list to the specified list. This
718 : prevents bugs where we forget to remove the call from a previous
719 : list when moving it.
720 : */
721 2668932 : static void dcesrv_call_set_list(struct dcesrv_call_state *call,
722 : enum dcesrv_call_list list)
723 : {
724 2668932 : switch (call->list) {
725 2630260 : case DCESRV_LIST_NONE:
726 2630260 : break;
727 0 : case DCESRV_LIST_CALL_LIST:
728 0 : DLIST_REMOVE(call->conn->call_list, call);
729 0 : break;
730 16575 : case DCESRV_LIST_FRAGMENTED_CALL_LIST:
731 16575 : DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
732 16492 : break;
733 0 : case DCESRV_LIST_PENDING_CALL_LIST:
734 0 : DLIST_REMOVE(call->conn->pending_call_list, call);
735 0 : break;
736 : }
737 2668932 : call->list = list;
738 2668932 : switch (list) {
739 1742637 : case DCESRV_LIST_NONE:
740 1742637 : break;
741 61775 : case DCESRV_LIST_CALL_LIST:
742 61775 : DLIST_ADD_END(call->conn->call_list, call);
743 60783 : break;
744 16621 : case DCESRV_LIST_FRAGMENTED_CALL_LIST:
745 16621 : DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
746 16538 : break;
747 833203 : case DCESRV_LIST_PENDING_CALL_LIST:
748 833203 : DLIST_ADD_END(call->conn->pending_call_list, call);
749 826794 : break;
750 : }
751 2668932 : }
752 :
753 424 : static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
754 : const char *reason)
755 : {
756 424 : struct dcesrv_auth *a = NULL;
757 :
758 424 : if (call->conn->terminate != NULL) {
759 0 : return;
760 : }
761 :
762 424 : call->conn->allow_bind = false;
763 424 : call->conn->allow_alter = false;
764 :
765 424 : call->conn->default_auth_state->auth_invalid = true;
766 :
767 784 : for (a = call->conn->auth_states; a != NULL; a = a->next) {
768 360 : a->auth_invalid = true;
769 : }
770 :
771 424 : call->terminate_reason = talloc_strdup(call, reason);
772 424 : if (call->terminate_reason == NULL) {
773 0 : call->terminate_reason = __location__;
774 : }
775 : }
776 :
777 : /*
778 : return a dcerpc bind_nak
779 : */
780 149 : static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
781 : {
782 18 : struct ncacn_packet pkt;
783 18 : struct dcerpc_bind_nak_version version;
784 18 : struct data_blob_list_item *rep;
785 18 : NTSTATUS status;
786 18 : static const uint8_t _pad[3] = { 0, };
787 :
788 : /*
789 : * We add the call to the pending_call_list
790 : * in order to defer the termination.
791 : */
792 149 : dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
793 :
794 : /* setup a bind_nak */
795 149 : dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
796 149 : pkt.auth_length = 0;
797 149 : pkt.call_id = call->pkt.call_id;
798 149 : pkt.ptype = DCERPC_PKT_BIND_NAK;
799 149 : pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
800 149 : pkt.u.bind_nak.reject_reason = reason;
801 149 : version.rpc_vers = 5;
802 149 : version.rpc_vers_minor = 0;
803 149 : pkt.u.bind_nak.num_versions = 1;
804 149 : pkt.u.bind_nak.versions = &version;
805 149 : pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
806 :
807 149 : rep = talloc_zero(call, struct data_blob_list_item);
808 149 : if (!rep) {
809 0 : return NT_STATUS_NO_MEMORY;
810 : }
811 :
812 149 : status = dcerpc_ncacn_push_auth(&rep->blob, call, &pkt, NULL);
813 149 : if (!NT_STATUS_IS_OK(status)) {
814 0 : return status;
815 : }
816 :
817 149 : dcerpc_set_frag_length(&rep->blob, rep->blob.length);
818 :
819 149 : DLIST_ADD_END(call->replies, rep);
820 149 : dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
821 :
822 149 : if (call->conn->call_list && call->conn->call_list->replies) {
823 149 : if (call->conn->transport.report_output_data) {
824 149 : call->conn->transport.report_output_data(call->conn);
825 : }
826 : }
827 :
828 149 : return NT_STATUS_OK;
829 : }
830 :
831 275 : static NTSTATUS _dcesrv_fault_disconnect_flags(struct dcesrv_call_state *call,
832 : uint32_t fault_code,
833 : uint8_t extra_flags,
834 : const char *func,
835 : const char *location)
836 : {
837 275 : const char *reason = NULL;
838 :
839 275 : reason = talloc_asprintf(call, "%s:%s: fault=%u (%s) flags=0x%x",
840 : func, location,
841 : fault_code,
842 : dcerpc_errstr(call, fault_code),
843 : extra_flags);
844 275 : if (reason == NULL) {
845 0 : reason = location;
846 : }
847 :
848 : /*
849 : * We add the call to the pending_call_list
850 : * in order to defer the termination.
851 : */
852 :
853 275 : dcesrv_call_disconnect_after(call, reason);
854 :
855 275 : return dcesrv_fault_with_flags(call, fault_code, extra_flags);
856 : }
857 :
858 : #define dcesrv_fault_disconnect(call, fault_code) \
859 : _dcesrv_fault_disconnect_flags(call, fault_code, \
860 : DCERPC_PFC_FLAG_DID_NOT_EXECUTE, \
861 : __func__, __location__)
862 : #define dcesrv_fault_disconnect0(call, fault_code) \
863 : _dcesrv_fault_disconnect_flags(call, fault_code, 0, \
864 : __func__, __location__)
865 :
866 56472 : static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
867 : {
868 56472 : DLIST_REMOVE(c->conn->contexts, c);
869 :
870 56472 : if (c->iface && c->iface->unbind) {
871 56468 : c->iface->unbind(c, c->iface);
872 56468 : c->iface = NULL;
873 : }
874 :
875 56472 : return 0;
876 : }
877 :
878 55221 : static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
879 : {
880 55221 : struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
881 55221 : const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
882 860 : enum dcerpc_transport_t transport =
883 55221 : dcerpc_binding_get_transport(endpoint->ep_description);
884 55221 : struct dcesrv_connection_context *context = dce_call->context;
885 55221 : const struct dcesrv_interface *iface = context->iface;
886 :
887 55221 : context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
888 :
889 55221 : if (transport == NCALRPC) {
890 1585 : context->allow_connect = true;
891 1585 : return;
892 : }
893 :
894 : /*
895 : * allow overwrite per interface
896 : * allow dcerpc auth level connect:<interface>
897 : */
898 53636 : context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
899 53636 : context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
900 : "allow dcerpc auth level connect",
901 53636 : iface->name,
902 52784 : context->allow_connect);
903 : }
904 :
905 1609 : NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_connection_context *context,
906 : const struct dcesrv_interface *iface)
907 : {
908 : /*
909 : * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
910 : * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
911 : */
912 1609 : context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
913 1609 : return NT_STATUS_OK;
914 : }
915 :
916 2237 : NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_connection_context *context,
917 : const struct dcesrv_interface *iface)
918 : {
919 2237 : context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
920 2237 : return NT_STATUS_OK;
921 : }
922 :
923 11286 : _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_connection_context *context,
924 : const struct dcesrv_interface *iface)
925 : {
926 11286 : struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
927 11286 : const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
928 652 : enum dcerpc_transport_t transport =
929 11286 : dcerpc_binding_get_transport(endpoint->ep_description);
930 :
931 11286 : if (transport == NCALRPC) {
932 683 : context->allow_connect = true;
933 683 : return NT_STATUS_OK;
934 : }
935 :
936 : /*
937 : * allow overwrite per interface
938 : * allow dcerpc auth level connect:<interface>
939 : */
940 10603 : context->allow_connect = false;
941 21206 : context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
942 : "allow dcerpc auth level connect",
943 10603 : iface->name,
944 9955 : context->allow_connect);
945 10603 : return NT_STATUS_OK;
946 : }
947 :
948 7213 : _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_connection_context *context,
949 : const struct dcesrv_interface *iface)
950 : {
951 7213 : struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
952 7213 : const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
953 127 : enum dcerpc_transport_t transport =
954 7213 : dcerpc_binding_get_transport(endpoint->ep_description);
955 :
956 7213 : if (transport == NCALRPC) {
957 696 : context->allow_connect = true;
958 696 : return NT_STATUS_OK;
959 : }
960 :
961 : /*
962 : * allow overwrite per interface
963 : * allow dcerpc auth level connect:<interface>
964 : */
965 6517 : context->allow_connect = true;
966 13034 : context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
967 : "allow dcerpc auth level connect",
968 6517 : iface->name,
969 6394 : context->allow_connect);
970 6517 : return NT_STATUS_OK;
971 : }
972 :
973 : struct dcesrv_conn_auth_wait_context {
974 : struct tevent_req *req;
975 : bool done;
976 : NTSTATUS status;
977 : };
978 :
979 : struct dcesrv_conn_auth_wait_state {
980 : uint8_t dummy;
981 : };
982 :
983 15663 : static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
984 : struct tevent_context *ev,
985 : void *private_data)
986 : {
987 520 : struct dcesrv_conn_auth_wait_context *auth_wait =
988 15663 : talloc_get_type_abort(private_data,
989 : struct dcesrv_conn_auth_wait_context);
990 15663 : struct tevent_req *req = NULL;
991 15663 : struct dcesrv_conn_auth_wait_state *state = NULL;
992 :
993 15663 : req = tevent_req_create(mem_ctx, &state,
994 : struct dcesrv_conn_auth_wait_state);
995 15663 : if (req == NULL) {
996 0 : return NULL;
997 : }
998 15663 : auth_wait->req = req;
999 :
1000 15663 : tevent_req_defer_callback(req, ev);
1001 :
1002 15663 : if (!auth_wait->done) {
1003 15143 : return req;
1004 : }
1005 :
1006 0 : if (tevent_req_nterror(req, auth_wait->status)) {
1007 0 : return tevent_req_post(req, ev);
1008 : }
1009 :
1010 0 : tevent_req_done(req);
1011 0 : return tevent_req_post(req, ev);
1012 : }
1013 :
1014 15663 : static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
1015 : {
1016 15663 : return tevent_req_simple_recv_ntstatus(req);
1017 : }
1018 :
1019 15663 : static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
1020 : {
1021 15663 : struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
1022 :
1023 15663 : if (conn->wait_send != NULL) {
1024 0 : return NT_STATUS_INTERNAL_ERROR;
1025 : }
1026 :
1027 15663 : auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
1028 15663 : if (auth_wait == NULL) {
1029 0 : return NT_STATUS_NO_MEMORY;
1030 : }
1031 :
1032 15663 : conn->wait_private = auth_wait;
1033 15663 : conn->wait_send = dcesrv_conn_auth_wait_send;
1034 15663 : conn->wait_recv = dcesrv_conn_auth_wait_recv;
1035 15663 : return NT_STATUS_OK;
1036 : }
1037 :
1038 15663 : static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
1039 : NTSTATUS status)
1040 : {
1041 520 : struct dcesrv_conn_auth_wait_context *auth_wait =
1042 15663 : talloc_get_type_abort(conn->wait_private,
1043 : struct dcesrv_conn_auth_wait_context);
1044 :
1045 15663 : auth_wait->done = true;
1046 15663 : auth_wait->status = status;
1047 :
1048 15663 : if (auth_wait->req == NULL) {
1049 0 : return;
1050 : }
1051 :
1052 15663 : if (tevent_req_nterror(auth_wait->req, status)) {
1053 0 : return;
1054 : }
1055 :
1056 15663 : tevent_req_done(auth_wait->req);
1057 : }
1058 :
1059 : static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
1060 :
1061 : static void dcesrv_bind_done(struct tevent_req *subreq);
1062 :
1063 : /*
1064 : handle a bind request
1065 : */
1066 55330 : static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
1067 : {
1068 55330 : struct dcesrv_connection *conn = call->conn;
1069 55330 : struct dcesrv_context *dce_ctx = conn->dce_ctx;
1070 55330 : struct ncacn_packet *pkt = &call->ack_pkt;
1071 878 : NTSTATUS status;
1072 55330 : uint32_t extra_flags = 0;
1073 55330 : uint16_t max_req = 0;
1074 55330 : uint16_t max_rep = 0;
1075 55330 : struct dcerpc_binding *ep_2nd_description = NULL;
1076 55330 : const char *endpoint = NULL;
1077 55330 : struct dcesrv_auth *auth = call->auth_state;
1078 55330 : struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1079 55330 : struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1080 55330 : struct dcerpc_ack_ctx *ack_features = NULL;
1081 55330 : struct tevent_req *subreq = NULL;
1082 878 : size_t i;
1083 :
1084 55330 : status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1085 : DCERPC_PKT_BIND,
1086 : call->pkt.u.bind.auth_info.length,
1087 : 0, /* required flags */
1088 : DCERPC_PFC_FLAG_FIRST |
1089 : DCERPC_PFC_FLAG_LAST |
1090 : DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1091 : 0x08 | /* this is not defined, but should be ignored */
1092 : DCERPC_PFC_FLAG_CONC_MPX |
1093 : DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1094 : DCERPC_PFC_FLAG_MAYBE |
1095 : DCERPC_PFC_FLAG_OBJECT_UUID);
1096 55330 : if (!NT_STATUS_IS_OK(status)) {
1097 3 : return dcesrv_bind_nak(call,
1098 : DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
1099 : }
1100 :
1101 : /* max_recv_frag and max_xmit_frag result always in the same value! */
1102 55327 : max_req = MIN(call->pkt.u.bind.max_xmit_frag,
1103 : call->pkt.u.bind.max_recv_frag);
1104 : /*
1105 : * The values are between 2048 and 5840 tested against Windows 2012R2
1106 : * via ncacn_ip_tcp on port 135.
1107 : */
1108 55327 : max_req = MAX(2048, max_req);
1109 55327 : max_rep = MIN(max_req, conn->max_recv_frag);
1110 : /* They are truncated to an 8 byte boundary. */
1111 55327 : max_rep &= 0xFFF8;
1112 :
1113 : /* max_recv_frag and max_xmit_frag result always in the same value! */
1114 55327 : conn->max_recv_frag = max_rep;
1115 55327 : conn->max_xmit_frag = max_rep;
1116 :
1117 55327 : status = dce_ctx->callbacks->assoc_group.find(
1118 54449 : call, dce_ctx->callbacks->assoc_group.private_data);
1119 55327 : if (!NT_STATUS_IS_OK(status)) {
1120 85 : DBG_NOTICE("Failed to find assoc_group 0x%08x: %s\n",
1121 : call->pkt.u.bind.assoc_group_id, nt_errstr(status));
1122 85 : return dcesrv_bind_nak(call, 0);
1123 : }
1124 :
1125 55242 : if (call->pkt.u.bind.num_contexts < 1) {
1126 6 : return dcesrv_bind_nak(call, 0);
1127 : }
1128 :
1129 55236 : ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1130 : call->pkt.u.bind.num_contexts);
1131 55236 : if (ack_ctx_list == NULL) {
1132 0 : return dcesrv_bind_nak(call, 0);
1133 : }
1134 :
1135 : /*
1136 : * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1137 : * dcesrv_check_or_create_context()) and do some protocol validation
1138 : * and set sane defaults.
1139 : */
1140 129706 : for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1141 74476 : const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1142 74476 : struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1143 74476 : bool is_feature = false;
1144 74476 : uint64_t features = 0;
1145 :
1146 74476 : if (c->num_transfer_syntaxes == 0) {
1147 6 : return dcesrv_bind_nak(call, 0);
1148 : }
1149 :
1150 74473 : a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1151 74473 : a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1152 :
1153 : /*
1154 : * It's only treated as bind time feature request, if the first
1155 : * transfer_syntax matches, all others are ignored.
1156 : */
1157 74473 : is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1158 : &features);
1159 74473 : if (!is_feature) {
1160 55215 : continue;
1161 : }
1162 :
1163 19258 : if (ack_features != NULL) {
1164 : /*
1165 : * Only one bind time feature context is allowed.
1166 : */
1167 3 : return dcesrv_bind_nak(call, 0);
1168 : }
1169 19255 : ack_features = a;
1170 :
1171 19255 : a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1172 19255 : a->reason.negotiate = 0;
1173 19255 : if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1174 19240 : if (conn->max_auth_states != 0) {
1175 18006 : a->reason.negotiate |=
1176 : DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING;
1177 : }
1178 : }
1179 19255 : if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1180 19246 : a->reason.negotiate |=
1181 : DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1182 : }
1183 :
1184 19255 : conn->assoc_group->bind_time_features = a->reason.negotiate;
1185 : }
1186 :
1187 : /*
1188 : * Try to negotiate one new presentation context.
1189 : *
1190 : * Deep in here we locate the iface (by uuid) that the client
1191 : * requested, from the list of interfaces on the
1192 : * call->conn->endpoint, and call iface->bind() on that iface.
1193 : *
1194 : * call->conn was set up at the accept() of the socket, and
1195 : * call->conn->endpoint has a list of interfaces restricted to
1196 : * this port or pipe.
1197 : */
1198 55230 : status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1199 55230 : if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1200 0 : return dcesrv_bind_nak(call, 0);
1201 : }
1202 55230 : if (!NT_STATUS_IS_OK(status)) {
1203 0 : return status;
1204 : }
1205 :
1206 : /*
1207 : * At this point we still don't know which interface (eg
1208 : * netlogon, lsa, drsuapi) the caller requested in this bind!
1209 : * The most recently added context is available as the first
1210 : * element in the linked list at call->conn->contexts, that is
1211 : * call->conn->contexts->iface, but they may not have
1212 : * requested one at all!
1213 : */
1214 :
1215 55230 : if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1216 111 : (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1217 111 : call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1218 111 : extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1219 : }
1220 :
1221 55230 : if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1222 0 : conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1223 : }
1224 :
1225 : /*
1226 : * After finding the interface and setting up the NDR
1227 : * transport negotiation etc, handle any authentication that
1228 : * is being requested.
1229 : */
1230 55230 : if (!dcesrv_auth_bind(call)) {
1231 :
1232 45 : if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1233 : /*
1234 : * With DCERPC_AUTH_LEVEL_NONE, we get the
1235 : * reject_reason in auth->auth_context_id.
1236 : */
1237 45 : return dcesrv_bind_nak(call, auth->auth_context_id);
1238 : }
1239 :
1240 : /*
1241 : * This must a be a temporary failure e.g. talloc or invalid
1242 : * configuration, e.g. no machine account.
1243 : */
1244 0 : return dcesrv_bind_nak(call,
1245 : DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1246 : }
1247 :
1248 : /* setup a bind_ack */
1249 55185 : dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(dce_ctx->lp_ctx));
1250 55185 : pkt->auth_length = 0;
1251 55185 : pkt->call_id = call->pkt.call_id;
1252 55185 : pkt->ptype = DCERPC_PKT_BIND_ACK;
1253 55185 : pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1254 55185 : pkt->u.bind_ack.max_xmit_frag = conn->max_xmit_frag;
1255 55185 : pkt->u.bind_ack.max_recv_frag = conn->max_recv_frag;
1256 55185 : pkt->u.bind_ack.assoc_group_id = conn->assoc_group->id;
1257 :
1258 55185 : ep_2nd_description = conn->endpoint->ep_2nd_description;
1259 55185 : if (ep_2nd_description == NULL) {
1260 49637 : ep_2nd_description = conn->endpoint->ep_description;
1261 : }
1262 :
1263 55185 : endpoint = dcerpc_binding_get_string_option(
1264 : ep_2nd_description,
1265 : "endpoint");
1266 55185 : if (endpoint == NULL) {
1267 17 : endpoint = "";
1268 : }
1269 :
1270 55185 : pkt->u.bind_ack.secondary_address = endpoint;
1271 55185 : pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1272 55185 : pkt->u.bind_ack.ctx_list = ack_ctx_list;
1273 55185 : pkt->u.bind_ack.auth_info = data_blob_null;
1274 :
1275 55185 : status = dcesrv_auth_prepare_bind_ack(call, pkt);
1276 55185 : if (!NT_STATUS_IS_OK(status)) {
1277 0 : return dcesrv_bind_nak(call, 0);
1278 : }
1279 :
1280 55185 : if (auth->auth_finished) {
1281 46003 : return dcesrv_auth_reply(call);
1282 : }
1283 :
1284 9182 : cb->auth.become_root();
1285 9182 : subreq = gensec_update_send(call, call->event_ctx,
1286 : auth->gensec_security,
1287 : call->in_auth_info.credentials);
1288 9182 : cb->auth.unbecome_root();
1289 9182 : if (subreq == NULL) {
1290 0 : return NT_STATUS_NO_MEMORY;
1291 : }
1292 9182 : tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1293 :
1294 9182 : return dcesrv_conn_auth_wait_setup(conn);
1295 : }
1296 :
1297 9182 : static void dcesrv_bind_done(struct tevent_req *subreq)
1298 : {
1299 424 : struct dcesrv_call_state *call =
1300 9182 : tevent_req_callback_data(subreq,
1301 : struct dcesrv_call_state);
1302 9182 : struct dcesrv_connection *conn = call->conn;
1303 9182 : struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1304 424 : NTSTATUS status;
1305 :
1306 9182 : cb->auth.become_root();
1307 9182 : status = gensec_update_recv(subreq, call,
1308 9182 : &call->out_auth_info->credentials);
1309 9182 : cb->auth.unbecome_root();
1310 9182 : TALLOC_FREE(subreq);
1311 :
1312 9182 : status = dcesrv_auth_complete(call, status);
1313 9182 : if (!NT_STATUS_IS_OK(status)) {
1314 1 : status = dcesrv_bind_nak(call, 0);
1315 1 : dcesrv_conn_auth_wait_finished(conn, status);
1316 1 : return;
1317 : }
1318 :
1319 9181 : status = dcesrv_auth_reply(call);
1320 9181 : dcesrv_conn_auth_wait_finished(conn, status);
1321 9181 : return;
1322 : }
1323 :
1324 61626 : static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1325 : {
1326 61626 : struct ncacn_packet *pkt = &call->ack_pkt;
1327 61626 : struct data_blob_list_item *rep = NULL;
1328 974 : NTSTATUS status;
1329 :
1330 61626 : rep = talloc_zero(call, struct data_blob_list_item);
1331 61626 : if (!rep) {
1332 0 : return NT_STATUS_NO_MEMORY;
1333 : }
1334 :
1335 61626 : status = dcerpc_ncacn_push_auth(&rep->blob,
1336 : call,
1337 : pkt,
1338 : call->out_auth_info);
1339 61626 : if (!NT_STATUS_IS_OK(status)) {
1340 0 : return status;
1341 : }
1342 :
1343 61626 : dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1344 :
1345 61626 : DLIST_ADD_END(call->replies, rep);
1346 61626 : dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1347 :
1348 61626 : if (call->conn->call_list && call->conn->call_list->replies) {
1349 61626 : if (call->conn->transport.report_output_data) {
1350 61626 : call->conn->transport.report_output_data(call->conn);
1351 : }
1352 : }
1353 :
1354 61626 : return NT_STATUS_OK;
1355 : }
1356 :
1357 :
1358 : static void dcesrv_auth3_done(struct tevent_req *subreq);
1359 :
1360 : /*
1361 : handle a auth3 request
1362 : */
1363 234 : static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1364 : {
1365 234 : struct dcesrv_connection *conn = call->conn;
1366 234 : struct dcesrv_auth *auth = call->auth_state;
1367 234 : struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1368 234 : struct tevent_req *subreq = NULL;
1369 0 : NTSTATUS status;
1370 :
1371 234 : if (!auth->auth_started) {
1372 0 : return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1373 : }
1374 :
1375 234 : if (auth->auth_finished) {
1376 3 : return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1377 : }
1378 :
1379 231 : status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1380 : DCERPC_PKT_AUTH3,
1381 : call->pkt.u.auth3.auth_info.length,
1382 : 0, /* required flags */
1383 : DCERPC_PFC_FLAG_FIRST |
1384 : DCERPC_PFC_FLAG_LAST |
1385 : DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1386 : 0x08 | /* this is not defined, but should be ignored */
1387 : DCERPC_PFC_FLAG_CONC_MPX |
1388 : DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1389 : DCERPC_PFC_FLAG_MAYBE |
1390 : DCERPC_PFC_FLAG_OBJECT_UUID);
1391 231 : if (!NT_STATUS_IS_OK(status)) {
1392 0 : return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1393 : }
1394 :
1395 : /* handle the auth3 in the auth code */
1396 231 : if (!dcesrv_auth_prepare_auth3(call)) {
1397 : /*
1398 : * we don't send a reply to a auth3 request,
1399 : * except by a fault.
1400 : *
1401 : * In anycase we mark the connection as
1402 : * invalid.
1403 : */
1404 3 : auth->auth_invalid = true;
1405 3 : if (call->fault_code != 0) {
1406 3 : return dcesrv_fault_disconnect(call, call->fault_code);
1407 : }
1408 0 : TALLOC_FREE(call);
1409 0 : return NT_STATUS_OK;
1410 : }
1411 :
1412 228 : cb->auth.become_root();
1413 228 : subreq = gensec_update_send(call, call->event_ctx,
1414 : auth->gensec_security,
1415 : call->in_auth_info.credentials);
1416 228 : cb->auth.unbecome_root();
1417 228 : if (subreq == NULL) {
1418 0 : return NT_STATUS_NO_MEMORY;
1419 : }
1420 228 : tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1421 :
1422 228 : return dcesrv_conn_auth_wait_setup(conn);
1423 : }
1424 :
1425 228 : static void dcesrv_auth3_done(struct tevent_req *subreq)
1426 : {
1427 0 : struct dcesrv_call_state *call =
1428 228 : tevent_req_callback_data(subreq,
1429 : struct dcesrv_call_state);
1430 228 : struct dcesrv_connection *conn = call->conn;
1431 228 : struct dcesrv_auth *auth = call->auth_state;
1432 228 : struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1433 0 : NTSTATUS status;
1434 :
1435 228 : cb->auth.become_root();
1436 228 : status = gensec_update_recv(subreq, call,
1437 228 : &call->out_auth_info->credentials);
1438 228 : cb->auth.unbecome_root();
1439 228 : TALLOC_FREE(subreq);
1440 :
1441 228 : status = dcesrv_auth_complete(call, status);
1442 228 : if (!NT_STATUS_IS_OK(status)) {
1443 : /*
1444 : * we don't send a reply to a auth3 request,
1445 : * except by a fault.
1446 : *
1447 : * In anycase we mark the connection as
1448 : * invalid.
1449 : */
1450 3 : auth->auth_invalid = true;
1451 3 : if (call->fault_code != 0) {
1452 0 : status = dcesrv_fault_disconnect(call, call->fault_code);
1453 0 : dcesrv_conn_auth_wait_finished(conn, status);
1454 0 : return;
1455 : }
1456 3 : TALLOC_FREE(call);
1457 3 : dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1458 3 : return;
1459 : }
1460 :
1461 : /*
1462 : * we don't send a reply to a auth3 request.
1463 : */
1464 225 : TALLOC_FREE(call);
1465 225 : dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1466 225 : return;
1467 : }
1468 :
1469 :
1470 80960 : static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1471 : const struct dcerpc_bind *b,
1472 : const struct dcerpc_ctx_list *ctx,
1473 : struct dcerpc_ack_ctx *ack,
1474 : bool validate_only,
1475 : const struct ndr_syntax_id *supported_transfer)
1476 : {
1477 1829 : struct dcesrv_connection_context *context;
1478 1829 : const struct dcesrv_interface *iface;
1479 1829 : NTSTATUS status;
1480 80960 : const struct ndr_syntax_id *selected_transfer = NULL;
1481 1829 : size_t i;
1482 1829 : bool ok;
1483 :
1484 80960 : if (b == NULL) {
1485 0 : return NT_STATUS_INTERNAL_ERROR;
1486 : }
1487 80960 : if (ctx == NULL) {
1488 0 : return NT_STATUS_INTERNAL_ERROR;
1489 : }
1490 80960 : if (ctx->num_transfer_syntaxes < 1) {
1491 0 : return NT_STATUS_INTERNAL_ERROR;
1492 : }
1493 80960 : if (ack == NULL) {
1494 0 : return NT_STATUS_INTERNAL_ERROR;
1495 : }
1496 80960 : if (supported_transfer == NULL) {
1497 0 : return NT_STATUS_INTERNAL_ERROR;
1498 : }
1499 :
1500 80960 : switch (ack->result) {
1501 19252 : case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1502 : case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1503 : /*
1504 : * We is already completed.
1505 : */
1506 19252 : return NT_STATUS_OK;
1507 60731 : default:
1508 61708 : break;
1509 : }
1510 :
1511 61708 : ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1512 61708 : ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1513 :
1514 62685 : iface = find_interface_by_syntax_id(
1515 61708 : call->conn->endpoint, &ctx->abstract_syntax);
1516 61708 : if (iface == NULL) {
1517 6 : struct ndr_syntax_id_buf buf;
1518 51 : DBG_NOTICE("Request for unknown dcerpc interface %s\n",
1519 : ndr_syntax_id_buf_string(
1520 : &ctx->abstract_syntax, &buf));
1521 : /*
1522 : * We report this only via ack->result
1523 : */
1524 51 : return NT_STATUS_OK;
1525 : }
1526 :
1527 61657 : ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1528 61657 : ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1529 :
1530 61657 : if (validate_only) {
1531 : /*
1532 : * We report this only via ack->result
1533 : */
1534 15 : return NT_STATUS_OK;
1535 : }
1536 :
1537 61675 : for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1538 : /*
1539 : * we only do NDR encoded dcerpc for now.
1540 : */
1541 61669 : ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1542 : supported_transfer);
1543 61669 : if (ok) {
1544 60665 : selected_transfer = supported_transfer;
1545 60665 : break;
1546 : }
1547 : }
1548 :
1549 61642 : context = dcesrv_find_context(call->conn, ctx->context_id);
1550 61642 : if (context != NULL) {
1551 6421 : ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1552 : &ctx->abstract_syntax);
1553 6421 : if (!ok) {
1554 18 : return NT_STATUS_RPC_PROTOCOL_ERROR;
1555 : }
1556 :
1557 6403 : if (selected_transfer != NULL) {
1558 6397 : ok = ndr_syntax_id_equal(&context->transfer_syntax,
1559 : selected_transfer);
1560 6397 : if (!ok) {
1561 0 : return NT_STATUS_RPC_PROTOCOL_ERROR;
1562 : }
1563 :
1564 6397 : ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1565 6397 : ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1566 6397 : ack->syntax = context->transfer_syntax;
1567 : }
1568 :
1569 : /*
1570 : * We report this only via ack->result
1571 : */
1572 6403 : return NT_STATUS_OK;
1573 : }
1574 :
1575 55221 : if (selected_transfer == NULL) {
1576 : /*
1577 : * We report this only via ack->result
1578 : */
1579 0 : return NT_STATUS_OK;
1580 : }
1581 :
1582 55221 : ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1583 55221 : ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1584 :
1585 : /* add this context to the list of available context_ids */
1586 55221 : context = talloc_zero(call->conn, struct dcesrv_connection_context);
1587 55221 : if (context == NULL) {
1588 0 : return NT_STATUS_NO_MEMORY;
1589 : }
1590 55221 : context->conn = call->conn;
1591 55221 : context->context_id = ctx->context_id;
1592 55221 : context->iface = iface;
1593 55221 : context->transfer_syntax = *selected_transfer;
1594 55221 : context->ndr64 = ndr_syntax_id_equal(&context->transfer_syntax,
1595 : &ndr_transfer_syntax_ndr64);
1596 55221 : DLIST_ADD(call->conn->contexts, context);
1597 55221 : call->context = context;
1598 55221 : talloc_set_destructor(context, dcesrv_connection_context_destructor);
1599 :
1600 55221 : dcesrv_prepare_context_auth(call);
1601 :
1602 : /*
1603 : * Multiplex is supported by default
1604 : */
1605 55221 : call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1606 :
1607 55221 : status = iface->bind(context, iface);
1608 55221 : call->context = NULL;
1609 55221 : if (!NT_STATUS_IS_OK(status)) {
1610 : /* we don't want to trigger the iface->unbind() hook */
1611 0 : context->iface = NULL;
1612 0 : talloc_free(context);
1613 : /*
1614 : * We report this only via ack->result
1615 : */
1616 0 : return NT_STATUS_OK;
1617 : }
1618 :
1619 55221 : ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1620 55221 : ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1621 55221 : ack->syntax = context->transfer_syntax;
1622 55221 : return NT_STATUS_OK;
1623 : }
1624 :
1625 61708 : static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1626 : const struct dcerpc_bind *b,
1627 : struct dcerpc_ack_ctx *ack_ctx_list)
1628 : {
1629 977 : NTSTATUS status;
1630 977 : size_t i;
1631 61708 : bool validate_only = false;
1632 977 : bool preferred_ndr32;
1633 :
1634 : /*
1635 : * Try to negotiate one new presentation context,
1636 : * using our preferred transfer syntax.
1637 : */
1638 142650 : for (i = 0; i < b->num_contexts; i++) {
1639 80960 : const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1640 80960 : struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1641 :
1642 82789 : status = dcesrv_check_or_create_context(call, b, c, a,
1643 : validate_only,
1644 80960 : call->conn->preferred_transfer);
1645 80960 : if (!NT_STATUS_IS_OK(status)) {
1646 18 : return status;
1647 : }
1648 :
1649 80942 : if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1650 : /*
1651 : * We managed to negotiate one context.
1652 : *
1653 : * => we're done.
1654 : */
1655 61618 : validate_only = true;
1656 : }
1657 : }
1658 :
1659 62664 : preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1660 61690 : call->conn->preferred_transfer);
1661 61690 : if (preferred_ndr32) {
1662 : /*
1663 : * We're done.
1664 : */
1665 61690 : return NT_STATUS_OK;
1666 : }
1667 :
1668 : /*
1669 : * Try to negotiate one new presentation context,
1670 : * using NDR 32 as fallback.
1671 : */
1672 0 : for (i = 0; i < b->num_contexts; i++) {
1673 0 : const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1674 0 : struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1675 :
1676 0 : status = dcesrv_check_or_create_context(call, b, c, a,
1677 : validate_only,
1678 : &ndr_transfer_syntax_ndr);
1679 0 : if (!NT_STATUS_IS_OK(status)) {
1680 0 : return status;
1681 : }
1682 :
1683 0 : if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1684 : /*
1685 : * We managed to negotiate one context.
1686 : *
1687 : * => we're done.
1688 : */
1689 0 : validate_only = true;
1690 : }
1691 : }
1692 :
1693 0 : return NT_STATUS_OK;
1694 : }
1695 :
1696 : static void dcesrv_alter_done(struct tevent_req *subreq);
1697 :
1698 : /*
1699 : handle a alter context request
1700 : */
1701 6493 : static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1702 : {
1703 6493 : struct dcesrv_connection *conn = call->conn;
1704 117 : NTSTATUS status;
1705 6493 : bool auth_ok = false;
1706 6493 : struct ncacn_packet *pkt = &call->ack_pkt;
1707 6493 : uint32_t extra_flags = 0;
1708 6493 : struct dcesrv_auth *auth = call->auth_state;
1709 6493 : struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1710 6493 : struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1711 6493 : struct tevent_req *subreq = NULL;
1712 117 : size_t i;
1713 :
1714 6493 : if (!call->conn->allow_alter) {
1715 0 : return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1716 : }
1717 :
1718 6493 : status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1719 : DCERPC_PKT_ALTER,
1720 : call->pkt.u.alter.auth_info.length,
1721 : 0, /* required flags */
1722 : DCERPC_PFC_FLAG_FIRST |
1723 : DCERPC_PFC_FLAG_LAST |
1724 : DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1725 : 0x08 | /* this is not defined, but should be ignored */
1726 : DCERPC_PFC_FLAG_CONC_MPX |
1727 : DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1728 : DCERPC_PFC_FLAG_MAYBE |
1729 : DCERPC_PFC_FLAG_OBJECT_UUID);
1730 6493 : if (!NT_STATUS_IS_OK(status)) {
1731 0 : return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1732 : }
1733 :
1734 6493 : auth_ok = dcesrv_auth_alter(call);
1735 6493 : if (!auth_ok) {
1736 24 : if (call->fault_code != 0) {
1737 9 : return dcesrv_fault_disconnect(call, call->fault_code);
1738 : }
1739 : }
1740 :
1741 6484 : if (call->pkt.u.alter.num_contexts < 1) {
1742 3 : return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1743 : }
1744 :
1745 6481 : ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1746 : call->pkt.u.alter.num_contexts);
1747 6481 : if (ack_ctx_list == NULL) {
1748 0 : return NT_STATUS_NO_MEMORY;
1749 : }
1750 :
1751 : /*
1752 : * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1753 : * dcesrv_check_or_create_context()) and do some protocol validation
1754 : * and set sane defaults.
1755 : */
1756 12974 : for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1757 6496 : const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1758 6496 : struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1759 :
1760 6496 : if (c->num_transfer_syntaxes == 0) {
1761 3 : return dcesrv_fault_disconnect(call,
1762 : DCERPC_NCA_S_PROTO_ERROR);
1763 : }
1764 :
1765 6493 : a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1766 6493 : a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1767 : }
1768 :
1769 : /*
1770 : * Try to negotiate one new presentation context.
1771 : */
1772 6478 : status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1773 6478 : if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1774 18 : return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1775 : }
1776 6460 : if (!NT_STATUS_IS_OK(status)) {
1777 0 : return status;
1778 : }
1779 :
1780 6460 : if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1781 16 : (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1782 10 : call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1783 10 : extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1784 : }
1785 :
1786 6460 : if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1787 0 : call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1788 : }
1789 :
1790 : /* handle any authentication that is being requested */
1791 6460 : if (!auth_ok) {
1792 12 : if (call->in_auth_info.auth_type != auth->auth_type) {
1793 6 : return dcesrv_fault_disconnect(call,
1794 : DCERPC_FAULT_SEC_PKG_ERROR);
1795 : }
1796 6 : return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1797 : }
1798 :
1799 6448 : dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1800 6448 : pkt->auth_length = 0;
1801 6448 : pkt->call_id = call->pkt.call_id;
1802 6448 : pkt->ptype = DCERPC_PKT_ALTER_RESP;
1803 6448 : pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1804 6448 : pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1805 6448 : pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1806 6448 : pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1807 6448 : pkt->u.alter_resp.secondary_address = "";
1808 6448 : pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1809 6448 : pkt->u.alter_resp.ctx_list = ack_ctx_list;
1810 6448 : pkt->u.alter_resp.auth_info = data_blob_null;
1811 :
1812 6448 : status = dcesrv_auth_prepare_alter_ack(call, pkt);
1813 6448 : if (!NT_STATUS_IS_OK(status)) {
1814 0 : return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1815 : }
1816 :
1817 6448 : if (auth->auth_finished) {
1818 195 : return dcesrv_auth_reply(call);
1819 : }
1820 :
1821 6253 : cb->auth.become_root();
1822 6253 : subreq = gensec_update_send(call, call->event_ctx,
1823 : auth->gensec_security,
1824 : call->in_auth_info.credentials);
1825 6253 : cb->auth.unbecome_root();
1826 6253 : if (subreq == NULL) {
1827 0 : return NT_STATUS_NO_MEMORY;
1828 : }
1829 6253 : tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1830 :
1831 6253 : return dcesrv_conn_auth_wait_setup(conn);
1832 : }
1833 :
1834 6253 : static void dcesrv_alter_done(struct tevent_req *subreq)
1835 : {
1836 96 : struct dcesrv_call_state *call =
1837 6253 : tevent_req_callback_data(subreq,
1838 : struct dcesrv_call_state);
1839 6253 : struct dcesrv_connection *conn = call->conn;
1840 6253 : struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1841 96 : NTSTATUS status;
1842 :
1843 6253 : cb->auth.become_root();
1844 6253 : status = gensec_update_recv(subreq, call,
1845 6253 : &call->out_auth_info->credentials);
1846 6253 : cb->auth.unbecome_root();
1847 6253 : TALLOC_FREE(subreq);
1848 :
1849 6253 : status = dcesrv_auth_complete(call, status);
1850 6253 : if (!NT_STATUS_IS_OK(status)) {
1851 6 : status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1852 6 : dcesrv_conn_auth_wait_finished(conn, status);
1853 6 : return;
1854 : }
1855 :
1856 6247 : status = dcesrv_auth_reply(call);
1857 6247 : dcesrv_conn_auth_wait_finished(conn, status);
1858 6247 : return;
1859 : }
1860 :
1861 : /*
1862 : possibly save the call for inspection with ndrdump
1863 : */
1864 2104 : static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1865 : {
1866 : #ifdef DEVELOPER
1867 2104 : dcerpc_log_packet(call->conn->packet_log_dir,
1868 2104 : call->context->iface->name,
1869 2104 : call->pkt.u.request.opnum,
1870 : NDR_IN,
1871 2104 : &call->pkt.u.request.stub_and_verifier,
1872 : why);
1873 : #endif
1874 2104 : }
1875 :
1876 : #ifdef DEVELOPER
1877 : /*
1878 : Save the call for use as a seed for fuzzing.
1879 :
1880 : This is only enabled in a developer build, and only has effect if the
1881 : "dcesrv fuzz directory" param is set.
1882 : */
1883 1668805 : void _dcesrv_save_ndr_fuzz_seed(DATA_BLOB call_blob,
1884 : struct dcesrv_call_state *call,
1885 : ndr_flags_type flags)
1886 : {
1887 1668805 : const char *dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx,
1888 : NULL,
1889 : "dcesrv", "fuzz directory");
1890 :
1891 1668805 : dcerpc_save_ndr_fuzz_seed(call,
1892 : call_blob,
1893 : dump_dir,
1894 1668805 : call->context->iface->name,
1895 : flags,
1896 1668805 : call->pkt.u.request.opnum,
1897 1668805 : call->ndr_pull->flags & LIBNDR_FLAG_NDR64);
1898 1668805 : }
1899 : #endif /*if DEVELOPER, enveloping _dcesrv_save_ndr_fuzz_seed() */
1900 :
1901 :
1902 835672 : static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1903 : {
1904 835672 : TALLOC_CTX *frame = talloc_stackframe();
1905 835672 : const uint32_t bitmask1 = call->conn->client_hdr_signing ?
1906 835672 : DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1907 835672 : const struct dcerpc_sec_vt_pcontext pcontext = {
1908 835672 : .abstract_syntax = call->context->iface->syntax_id,
1909 828925 : .transfer_syntax = call->context->transfer_syntax,
1910 : };
1911 6747 : const struct dcerpc_sec_vt_header2 header2 =
1912 835672 : dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1913 6747 : enum ndr_err_code ndr_err;
1914 835672 : struct dcerpc_sec_verification_trailer *vt = NULL;
1915 835672 : NTSTATUS status = NT_STATUS_OK;
1916 6747 : bool ok;
1917 :
1918 835672 : SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1919 :
1920 835672 : ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1921 : frame, &vt);
1922 835672 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1923 0 : status = ndr_map_error2ntstatus(ndr_err);
1924 0 : goto done;
1925 : }
1926 :
1927 835672 : ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1928 : &pcontext, &header2);
1929 835672 : if (!ok) {
1930 0 : status = NT_STATUS_ACCESS_DENIED;
1931 0 : goto done;
1932 : }
1933 835672 : done:
1934 835672 : TALLOC_FREE(frame);
1935 835672 : return status;
1936 : }
1937 :
1938 : /*
1939 : handle a dcerpc request packet
1940 : */
1941 835826 : static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1942 : {
1943 835826 : const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1944 835826 : struct dcesrv_auth *auth = call->auth_state;
1945 6749 : enum dcerpc_transport_t transport =
1946 835826 : dcerpc_binding_get_transport(endpoint->ep_description);
1947 6749 : struct ndr_pull *pull;
1948 835826 : bool turn_winbind_on = false;
1949 6749 : NTSTATUS status;
1950 :
1951 835826 : if (auth->auth_invalid) {
1952 0 : return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1953 : }
1954 :
1955 835826 : if (!auth->auth_finished) {
1956 0 : return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1957 : }
1958 :
1959 : /* if authenticated, and the mech we use can't do async replies, don't use them... */
1960 839351 : if (auth->gensec_security != NULL &&
1961 100527 : !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1962 27970 : call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1963 : }
1964 :
1965 835826 : if (call->context == NULL) {
1966 0 : return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1967 : DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1968 : }
1969 :
1970 835826 : switch (auth->auth_level) {
1971 827681 : case DCERPC_AUTH_LEVEL_NONE:
1972 : case DCERPC_AUTH_LEVEL_PACKET:
1973 : case DCERPC_AUTH_LEVEL_INTEGRITY:
1974 : case DCERPC_AUTH_LEVEL_PRIVACY:
1975 827681 : break;
1976 1410 : default:
1977 1410 : if (!call->context->allow_connect) {
1978 0 : char *addr;
1979 :
1980 30 : addr = tsocket_address_string(call->conn->remote_address,
1981 : call);
1982 :
1983 30 : DEBUG(2, ("%s: restrict auth_level_connect access "
1984 : "to [%s] with auth[type=0x%x,level=0x%x] "
1985 : "on [%s] from [%s]\n",
1986 : __func__, call->context->iface->name,
1987 : auth->auth_type,
1988 : auth->auth_level,
1989 : derpc_transport_string_by_transport(transport),
1990 : addr));
1991 30 : return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1992 : }
1993 1366 : break;
1994 : }
1995 :
1996 835796 : if (auth->auth_level < call->context->min_auth_level) {
1997 2 : char *addr;
1998 :
1999 124 : addr = tsocket_address_string(call->conn->remote_address, call);
2000 :
2001 124 : DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
2002 : "to [%s] with auth[type=0x%x,level=0x%x] "
2003 : "on [%s] from [%s]\n",
2004 : __func__,
2005 : call->context->min_auth_level,
2006 : call->context->iface->name,
2007 : auth->auth_type,
2008 : auth->auth_level,
2009 : derpc_transport_string_by_transport(transport),
2010 : addr));
2011 124 : return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2012 : }
2013 :
2014 835672 : pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
2015 835672 : NT_STATUS_HAVE_NO_MEMORY(pull);
2016 :
2017 835672 : pull->flags |= LIBNDR_FLAG_REF_ALLOC;
2018 :
2019 835672 : call->ndr_pull = pull;
2020 :
2021 835672 : if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
2022 27067 : pull->flags |= LIBNDR_FLAG_BIGENDIAN;
2023 : }
2024 :
2025 835672 : status = dcesrv_check_verification_trailer(call);
2026 835672 : if (!NT_STATUS_IS_OK(status)) {
2027 0 : uint32_t faultcode = DCERPC_FAULT_OTHER;
2028 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2029 0 : faultcode = DCERPC_FAULT_ACCESS_DENIED;
2030 : }
2031 0 : DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
2032 : nt_errstr(status)));
2033 0 : return dcesrv_fault(call, faultcode);
2034 : }
2035 :
2036 835672 : if (call->context->ndr64) {
2037 0 : call->ndr_pull->flags |= LIBNDR_FLAG_NDR64;
2038 : }
2039 :
2040 : /* unravel the NDR for the packet */
2041 835672 : status = call->context->iface->ndr_pull(call, call, pull, &call->r);
2042 835672 : if (!NT_STATUS_IS_OK(status)) {
2043 54 : uint8_t extra_flags = 0;
2044 54 : if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
2045 : /* we got an unknown call */
2046 54 : DEBUG(3,(__location__ ": Unknown RPC call %"PRIu16" on %s\n",
2047 : call->pkt.u.request.opnum,
2048 : call->context->iface->name));
2049 54 : dcesrv_save_call(call, "unknown");
2050 54 : extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
2051 : } else {
2052 0 : dcesrv_save_call(call, "pullfail");
2053 : }
2054 :
2055 54 : return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
2056 : }
2057 :
2058 835618 : dcesrv_save_ndr_fuzz_seed(call->pkt.u.request.stub_and_verifier,
2059 : call,
2060 : NDR_IN);
2061 :
2062 835618 : if (pull->offset != pull->data_size) {
2063 2050 : dcesrv_save_call(call, "extrabytes");
2064 2050 : DEBUG(3,("Warning: %"PRIu32" extra bytes in incoming RPC request\n",
2065 : pull->data_size - pull->offset));
2066 : }
2067 :
2068 835618 : if (call->state_flags & DCESRV_CALL_STATE_FLAG_WINBIND_OFF) {
2069 9950 : bool winbind_active = !winbind_env_set();
2070 9950 : if (winbind_active) {
2071 9950 : DBG_DEBUG("turning winbind off\n");
2072 9950 : (void)winbind_off();
2073 9950 : turn_winbind_on = true;
2074 : }
2075 : }
2076 :
2077 : /* call the dispatch function */
2078 835618 : status = call->context->iface->dispatch(call, call, call->r);
2079 :
2080 835618 : if (turn_winbind_on) {
2081 9950 : DBG_DEBUG("turning winbind on\n");
2082 9950 : (void)winbind_on();
2083 : }
2084 :
2085 835618 : if (!NT_STATUS_IS_OK(status)) {
2086 2415 : DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
2087 : call->context->iface->name,
2088 : call->pkt.u.request.opnum,
2089 : dcerpc_errstr(pull, call->fault_code)));
2090 2415 : return dcesrv_fault(call, call->fault_code);
2091 : }
2092 :
2093 : /* add the call to the pending list */
2094 833203 : dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
2095 :
2096 833203 : if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
2097 17654 : return NT_STATUS_OK;
2098 : }
2099 :
2100 815549 : return dcesrv_reply(call);
2101 : }
2102 :
2103 :
2104 : /*
2105 : remove the call from the right list when freed
2106 : */
2107 914756 : static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
2108 : {
2109 914756 : dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2110 914756 : return 0;
2111 : }
2112 :
2113 1971 : _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
2114 : {
2115 1971 : return conn->local_address;
2116 : }
2117 :
2118 3464 : _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
2119 : {
2120 3464 : return conn->remote_address;
2121 : }
2122 :
2123 : /*
2124 : process some input to a dcerpc endpoint server.
2125 : */
2126 914759 : static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
2127 : struct ncacn_packet *pkt,
2128 : DATA_BLOB blob)
2129 : {
2130 7830 : NTSTATUS status;
2131 7830 : struct dcesrv_call_state *call;
2132 914759 : struct dcesrv_call_state *existing = NULL;
2133 914759 : size_t num_auth_ctx = 0;
2134 914759 : enum dcerpc_AuthType auth_type = 0;
2135 914759 : enum dcerpc_AuthLevel auth_level = 0;
2136 914759 : uint32_t auth_context_id = 0;
2137 914759 : bool auth_invalid = false;
2138 :
2139 914759 : call = talloc_zero(dce_conn, struct dcesrv_call_state);
2140 914759 : if (!call) {
2141 0 : data_blob_free(&blob);
2142 0 : talloc_free(pkt);
2143 0 : return NT_STATUS_NO_MEMORY;
2144 : }
2145 914759 : call->conn = dce_conn;
2146 914759 : call->event_ctx = dce_conn->event_ctx;
2147 914759 : call->state_flags = call->conn->state_flags;
2148 914759 : call->time = timeval_current();
2149 914759 : call->list = DCESRV_LIST_NONE;
2150 :
2151 914759 : talloc_steal(call, pkt);
2152 914759 : talloc_steal(call, blob.data);
2153 914759 : call->pkt = *pkt;
2154 :
2155 914759 : if (dce_conn->max_auth_states == 0) {
2156 17048 : call->auth_state = dce_conn->default_auth_state;
2157 897711 : } else if (call->pkt.auth_length == 0) {
2158 784239 : if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2159 738693 : dce_conn->default_auth_level_connect != NULL)
2160 : {
2161 1392 : call->auth_state = dce_conn->default_auth_level_connect;
2162 : } else {
2163 782847 : call->auth_state = dce_conn->default_auth_state;
2164 : }
2165 : }
2166 :
2167 914759 : if (call->auth_state == NULL) {
2168 113472 : struct dcesrv_auth *a = NULL;
2169 113472 : bool check_type_level = true;
2170 :
2171 113472 : auth_type = dcerpc_get_auth_type(&blob);
2172 113472 : auth_level = dcerpc_get_auth_level(&blob);
2173 113472 : auth_context_id = dcerpc_get_auth_context_id(&blob);
2174 :
2175 113472 : if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2176 98758 : if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) {
2177 7712 : check_type_level = false;
2178 : }
2179 98758 : dce_conn->default_auth_level_connect = NULL;
2180 98758 : if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
2181 58 : dce_conn->got_explicit_auth_level_connect = true;
2182 : }
2183 : }
2184 :
2185 113738 : for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2186 104817 : num_auth_ctx++;
2187 :
2188 104817 : if (a->auth_context_id != auth_context_id) {
2189 266 : continue;
2190 : }
2191 :
2192 104551 : if (a->auth_type != auth_type) {
2193 15 : auth_invalid = true;
2194 : }
2195 104551 : if (a->auth_level != auth_level) {
2196 27 : auth_invalid = true;
2197 : }
2198 :
2199 104551 : if (check_type_level && auth_invalid) {
2200 30 : a->auth_invalid = true;
2201 : }
2202 :
2203 104551 : DLIST_PROMOTE(dce_conn->auth_states, a);
2204 104551 : call->auth_state = a;
2205 104551 : break;
2206 : }
2207 : }
2208 :
2209 914759 : if (call->auth_state == NULL) {
2210 8921 : struct dcesrv_auth *a = NULL;
2211 :
2212 8921 : if (num_auth_ctx >= dce_conn->max_auth_states) {
2213 3 : return dcesrv_fault_disconnect(call,
2214 : DCERPC_NCA_S_PROTO_ERROR);
2215 : }
2216 :
2217 8918 : a = dcesrv_auth_create(dce_conn);
2218 8918 : if (a == NULL) {
2219 0 : talloc_free(call);
2220 0 : return NT_STATUS_NO_MEMORY;
2221 : }
2222 8918 : DLIST_ADD(dce_conn->auth_states, a);
2223 8918 : if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2224 : /*
2225 : * This can never be valid.
2226 : */
2227 51 : auth_invalid = true;
2228 51 : a->auth_invalid = true;
2229 : }
2230 8918 : call->auth_state = a;
2231 : }
2232 :
2233 914756 : talloc_set_destructor(call, dcesrv_call_dequeue);
2234 :
2235 914756 : if (call->conn->allow_bind) {
2236 : /*
2237 : * Only one bind is possible per connection
2238 : */
2239 55330 : call->conn->allow_bind = false;
2240 55330 : return dcesrv_bind(call);
2241 : }
2242 :
2243 : /* we have to check the signing here, before combining the
2244 : pdus */
2245 859426 : if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2246 852675 : dcesrv_default_auth_state_prepare_request(call);
2247 :
2248 852675 : if (call->auth_state->auth_started &&
2249 852624 : !call->auth_state->auth_finished) {
2250 3 : return dcesrv_fault_disconnect(call,
2251 : DCERPC_NCA_S_PROTO_ERROR);
2252 : }
2253 :
2254 852672 : status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2255 : DCERPC_PKT_REQUEST,
2256 : call->pkt.u.request.stub_and_verifier.length,
2257 : 0, /* required_flags */
2258 : DCERPC_PFC_FLAG_FIRST |
2259 : DCERPC_PFC_FLAG_LAST |
2260 : DCERPC_PFC_FLAG_PENDING_CANCEL |
2261 : 0x08 | /* this is not defined, but should be ignored */
2262 : DCERPC_PFC_FLAG_CONC_MPX |
2263 : DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2264 : DCERPC_PFC_FLAG_MAYBE |
2265 : DCERPC_PFC_FLAG_OBJECT_UUID);
2266 852672 : if (!NT_STATUS_IS_OK(status)) {
2267 0 : return dcesrv_fault_disconnect(call,
2268 : DCERPC_NCA_S_PROTO_ERROR);
2269 : }
2270 :
2271 852672 : if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2272 : /*
2273 : * We don't use dcesrv_fault_disconnect()
2274 : * here, because we don't want to set
2275 : * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2276 : *
2277 : * Note that we don't check against the negotiated
2278 : * max_recv_frag, but a hard coded value.
2279 : */
2280 24 : return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR);
2281 : }
2282 :
2283 852648 : if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2284 836043 : if (dce_conn->pending_call_list != NULL) {
2285 : /*
2286 : * concurrent requests are only allowed
2287 : * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2288 : */
2289 94 : if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2290 0 : return dcesrv_fault_disconnect0(call,
2291 : DCERPC_NCA_S_PROTO_ERROR);
2292 : }
2293 : }
2294 : /* only one request is possible in the fragmented list */
2295 836043 : if (dce_conn->incoming_fragmented_call_list != NULL) {
2296 54 : call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
2297 :
2298 54 : existing = dcesrv_find_fragmented_call(dce_conn,
2299 : call->pkt.call_id);
2300 54 : if (existing != NULL && call->auth_state != existing->auth_state) {
2301 42 : call->context = dcesrv_find_context(call->conn,
2302 21 : call->pkt.u.request.context_id);
2303 :
2304 21 : if (call->pkt.auth_length != 0 && existing->context == call->context) {
2305 3 : call->fault_code = DCERPC_FAULT_SEC_PKG_ERROR;
2306 : }
2307 : }
2308 54 : if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2309 : /*
2310 : * Without DCERPC_PFC_FLAG_CONC_MPX
2311 : * we need to return the FAULT on the
2312 : * already existing call.
2313 : *
2314 : * This is important to get the
2315 : * call_id and context_id right.
2316 : */
2317 33 : dce_conn->incoming_fragmented_call_list->fault_code = call->fault_code;
2318 33 : TALLOC_FREE(call);
2319 33 : call = dce_conn->incoming_fragmented_call_list;
2320 : }
2321 54 : if (existing != NULL) {
2322 26 : call->context = existing->context;
2323 : }
2324 54 : return dcesrv_fault_disconnect0(call, call->fault_code);
2325 : }
2326 835989 : if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2327 1 : return dcesrv_fault_disconnect(call,
2328 : DCERPC_FAULT_NO_CALL_ACTIVE);
2329 : }
2330 1671976 : call->context = dcesrv_find_context(call->conn,
2331 835988 : call->pkt.u.request.context_id);
2332 835988 : if (call->context == NULL) {
2333 10 : return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2334 : DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2335 : }
2336 : } else {
2337 83 : int cmp;
2338 :
2339 16605 : existing = dcesrv_find_fragmented_call(dce_conn,
2340 : call->pkt.call_id);
2341 16605 : if (existing == NULL) {
2342 59 : if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2343 : /*
2344 : * Without DCERPC_PFC_FLAG_CONC_MPX
2345 : * we need to return the FAULT on the
2346 : * already existing call.
2347 : *
2348 : * This is important to get the
2349 : * call_id and context_id right.
2350 : */
2351 32 : if (dce_conn->incoming_fragmented_call_list != NULL) {
2352 12 : TALLOC_FREE(call);
2353 12 : call = dce_conn->incoming_fragmented_call_list;
2354 : }
2355 32 : return dcesrv_fault_disconnect0(call,
2356 : DCERPC_NCA_S_PROTO_ERROR);
2357 : }
2358 27 : if (dce_conn->incoming_fragmented_call_list != NULL) {
2359 9 : return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR);
2360 : }
2361 36 : call->context = dcesrv_find_context(call->conn,
2362 18 : call->pkt.u.request.context_id);
2363 18 : if (call->context == NULL) {
2364 3 : return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2365 : DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2366 : }
2367 15 : if (auth_invalid) {
2368 12 : return dcesrv_fault_disconnect0(call,
2369 : DCERPC_FAULT_ACCESS_DENIED);
2370 : }
2371 3 : return dcesrv_fault_disconnect0(call,
2372 : DCERPC_NCA_S_PROTO_ERROR);
2373 : }
2374 :
2375 16546 : if (call->pkt.ptype != existing->pkt.ptype) {
2376 : /* trying to play silly buggers are we? */
2377 0 : return dcesrv_fault_disconnect(existing,
2378 : DCERPC_NCA_S_PROTO_ERROR);
2379 : }
2380 16546 : cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2381 : sizeof(pkt->drep));
2382 16546 : if (cmp != 0) {
2383 0 : return dcesrv_fault_disconnect(existing,
2384 : DCERPC_NCA_S_PROTO_ERROR);
2385 : }
2386 16546 : call->auth_state = existing->auth_state;
2387 16546 : call->context = existing->context;
2388 : }
2389 : }
2390 :
2391 859275 : if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2392 6835 : bool ok;
2393 852524 : uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2394 :
2395 852524 : if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2396 673 : payload_offset += 16;
2397 : }
2398 :
2399 852524 : ok = dcesrv_auth_pkt_pull(call, &blob,
2400 : 0, /* required_flags */
2401 : DCERPC_PFC_FLAG_FIRST |
2402 : DCERPC_PFC_FLAG_LAST |
2403 : DCERPC_PFC_FLAG_PENDING_CANCEL |
2404 : 0x08 | /* this is not defined, but should be ignored */
2405 : DCERPC_PFC_FLAG_CONC_MPX |
2406 : DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2407 : DCERPC_PFC_FLAG_MAYBE |
2408 : DCERPC_PFC_FLAG_OBJECT_UUID,
2409 : payload_offset,
2410 : &call->pkt.u.request.stub_and_verifier);
2411 852524 : if (!ok) {
2412 : /*
2413 : * We don't use dcesrv_fault_disconnect()
2414 : * here, because we don't want to set
2415 : * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2416 : */
2417 75 : if (call->fault_code == 0) {
2418 42 : call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2419 : }
2420 75 : return dcesrv_fault_disconnect0(call, call->fault_code);
2421 : }
2422 : }
2423 :
2424 : /* see if this is a continued packet */
2425 859200 : if (existing != NULL) {
2426 16531 : struct dcerpc_request *er = &existing->pkt.u.request;
2427 16531 : const struct dcerpc_request *nr = &call->pkt.u.request;
2428 83 : size_t available;
2429 83 : size_t alloc_size;
2430 83 : size_t alloc_hint;
2431 :
2432 : /*
2433 : * Up to 4 MByte are allowed by all fragments
2434 : */
2435 16531 : available = dce_conn->max_total_request_size;
2436 16531 : if (er->stub_and_verifier.length > available) {
2437 0 : return dcesrv_fault_disconnect0(existing,
2438 : DCERPC_FAULT_ACCESS_DENIED);
2439 : }
2440 16531 : available -= er->stub_and_verifier.length;
2441 16531 : if (nr->alloc_hint > available) {
2442 0 : return dcesrv_fault_disconnect0(existing,
2443 : DCERPC_FAULT_ACCESS_DENIED);
2444 : }
2445 16531 : if (nr->stub_and_verifier.length > available) {
2446 1 : return dcesrv_fault_disconnect0(existing,
2447 : DCERPC_FAULT_ACCESS_DENIED);
2448 : }
2449 16530 : alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2450 : /* allocate at least 1 byte */
2451 16530 : alloc_hint = MAX(alloc_hint, 1);
2452 16530 : alloc_size = er->stub_and_verifier.length +
2453 16447 : nr->stub_and_verifier.length;
2454 16530 : alloc_size = MAX(alloc_size, alloc_hint);
2455 :
2456 16613 : er->stub_and_verifier.data =
2457 16530 : talloc_realloc(existing,
2458 : er->stub_and_verifier.data,
2459 : uint8_t, alloc_size);
2460 16530 : if (er->stub_and_verifier.data == NULL) {
2461 0 : TALLOC_FREE(call);
2462 0 : return dcesrv_fault_with_flags(existing,
2463 : DCERPC_FAULT_OUT_OF_RESOURCES,
2464 : DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2465 : }
2466 16530 : memcpy(er->stub_and_verifier.data +
2467 16530 : er->stub_and_verifier.length,
2468 16530 : nr->stub_and_verifier.data,
2469 16530 : nr->stub_and_verifier.length);
2470 16530 : er->stub_and_verifier.length += nr->stub_and_verifier.length;
2471 :
2472 16530 : existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2473 :
2474 16530 : TALLOC_FREE(call);
2475 16530 : call = existing;
2476 : }
2477 :
2478 : /* this may not be the last pdu in the chain - if its isn't then
2479 : just put it on the incoming_fragmented_call_list and wait for the rest */
2480 859199 : if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2481 852448 : !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2482 : /*
2483 : * Up to 4 MByte are allowed by all fragments
2484 : */
2485 16622 : if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2486 1 : return dcesrv_fault_disconnect0(call,
2487 : DCERPC_FAULT_ACCESS_DENIED);
2488 : }
2489 16621 : dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2490 16621 : return NT_STATUS_OK;
2491 : }
2492 :
2493 : /* This removes any fragments we may have had stashed away */
2494 842577 : dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2495 :
2496 842577 : switch (call->pkt.ptype) {
2497 3 : case DCERPC_PKT_BIND:
2498 3 : status = dcesrv_bind_nak(call,
2499 : DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2500 3 : break;
2501 234 : case DCERPC_PKT_AUTH3:
2502 234 : status = dcesrv_auth3(call);
2503 234 : break;
2504 6493 : case DCERPC_PKT_ALTER:
2505 6493 : status = dcesrv_alter(call);
2506 6493 : break;
2507 835826 : case DCERPC_PKT_REQUEST:
2508 835826 : status = dcesrv_request(call);
2509 835826 : break;
2510 21 : case DCERPC_PKT_CO_CANCEL:
2511 : case DCERPC_PKT_ORPHANED:
2512 : /*
2513 : * Window just ignores CO_CANCEL and ORPHANED,
2514 : * so we do...
2515 : */
2516 21 : status = NT_STATUS_OK;
2517 21 : TALLOC_FREE(call);
2518 21 : break;
2519 0 : case DCERPC_PKT_BIND_ACK:
2520 : case DCERPC_PKT_BIND_NAK:
2521 : case DCERPC_PKT_ALTER_RESP:
2522 : case DCERPC_PKT_RESPONSE:
2523 : case DCERPC_PKT_FAULT:
2524 : case DCERPC_PKT_SHUTDOWN:
2525 : default:
2526 0 : status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2527 0 : break;
2528 : }
2529 :
2530 : /* if we are going to be sending a reply then add
2531 : it to the list of pending calls. We add it to the end to keep the call
2532 : list in the order we will answer */
2533 842577 : if (!NT_STATUS_IS_OK(status)) {
2534 0 : talloc_free(call);
2535 : }
2536 :
2537 842577 : return status;
2538 : }
2539 :
2540 654 : _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2541 : struct loadparm_context *lp_ctx,
2542 : struct dcesrv_context_callbacks *cb,
2543 : struct dcesrv_context **_dce_ctx)
2544 : {
2545 2 : struct dcesrv_context *dce_ctx;
2546 :
2547 654 : if (cb == NULL) {
2548 0 : return NT_STATUS_INVALID_PARAMETER;
2549 : }
2550 :
2551 654 : dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2552 654 : NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2553 :
2554 654 : if (uid_wrapper_enabled()) {
2555 654 : setenv("UID_WRAPPER_MYUID", "1", 1);
2556 : }
2557 654 : dce_ctx->initial_euid = geteuid();
2558 654 : if (uid_wrapper_enabled()) {
2559 654 : unsetenv("UID_WRAPPER_MYUID");
2560 : }
2561 :
2562 654 : dce_ctx->endpoint_list = NULL;
2563 654 : dce_ctx->lp_ctx = lp_ctx;
2564 654 : dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2565 654 : if (dce_ctx->assoc_groups_idr == NULL) {
2566 0 : TALLOC_FREE(dce_ctx);
2567 0 : return NT_STATUS_NO_MEMORY;
2568 : }
2569 654 : dce_ctx->broken_connections = NULL;
2570 654 : dce_ctx->callbacks = cb;
2571 :
2572 : /*
2573 : * For now we only support NDR32.
2574 : */
2575 654 : dce_ctx->preferred_transfer = &ndr_transfer_syntax_ndr;
2576 :
2577 654 : *_dce_ctx = dce_ctx;
2578 654 : return NT_STATUS_OK;
2579 : }
2580 :
2581 : /**
2582 : * @brief Set callback functions on an existing dcesrv_context
2583 : *
2584 : * This allows to reset callbacks initially set via
2585 : * dcesrv_init_context()
2586 : *
2587 : * @param[in] dce_ctx The context to set the callbacks on
2588 : * @param[in] cb The callbacks to set on dce_ctx
2589 : */
2590 545 : _PUBLIC_ void dcesrv_context_set_callbacks(
2591 : struct dcesrv_context *dce_ctx,
2592 : struct dcesrv_context_callbacks *cb)
2593 : {
2594 545 : dce_ctx->callbacks = cb;
2595 545 : }
2596 :
2597 68 : _PUBLIC_ NTSTATUS dcesrv_init_ep_servers(struct dcesrv_context *dce_ctx,
2598 : const char **endpoint_servers)
2599 : {
2600 2 : NTSTATUS status;
2601 2 : int i;
2602 :
2603 68 : if (endpoint_servers == NULL) {
2604 0 : DBG_ERR("No endpoint servers configured\n");
2605 0 : return NT_STATUS_INTERNAL_ERROR;
2606 : }
2607 :
2608 978 : for (i=0;endpoint_servers[i];i++) {
2609 910 : status = dcesrv_init_ep_server(dce_ctx, endpoint_servers[i]);
2610 910 : if (!NT_STATUS_IS_OK(status)) {
2611 0 : DBG_ERR("failed to init endpoint server = '%s': %s\n",
2612 : endpoint_servers[i], nt_errstr(status));
2613 0 : return status;
2614 : }
2615 : }
2616 :
2617 68 : return NT_STATUS_OK;
2618 : }
2619 :
2620 : /* the list of currently registered DCERPC endpoint servers.
2621 : */
2622 : static struct ep_server {
2623 : struct dcesrv_endpoint_server *ep_server;
2624 : } *ep_servers = NULL;
2625 : static int num_ep_servers = 0;
2626 :
2627 41 : _PUBLIC_ NTSTATUS dcesrv_init_registered_ep_servers(
2628 : struct dcesrv_context *dce_ctx)
2629 : {
2630 0 : NTSTATUS status;
2631 0 : int i;
2632 :
2633 82 : for (i = 0; i < num_ep_servers; i++) {
2634 41 : status = dcesrv_init_ep_server(dce_ctx,
2635 41 : ep_servers[i].ep_server->name);
2636 41 : if (!NT_STATUS_IS_OK(status)) {
2637 0 : return status;
2638 : }
2639 : }
2640 :
2641 41 : return NT_STATUS_OK;
2642 : }
2643 :
2644 2635 : _PUBLIC_ NTSTATUS dcesrv_init_ep_server(struct dcesrv_context *dce_ctx,
2645 : const char *ep_server_name)
2646 : {
2647 2635 : struct dcesrv_endpoint_server *ep_server = NULL;
2648 26 : NTSTATUS status;
2649 :
2650 2635 : ep_server = discard_const_p(struct dcesrv_endpoint_server,
2651 : dcesrv_ep_server_byname(ep_server_name));
2652 2635 : if (ep_server == NULL) {
2653 0 : DBG_ERR("Failed to find endpoint server '%s'\n",
2654 : ep_server_name);
2655 0 : return NT_STATUS_INTERNAL_ERROR;
2656 : }
2657 :
2658 2635 : if (ep_server->initialized) {
2659 0 : return NT_STATUS_OK;
2660 : }
2661 :
2662 2635 : status = ep_server->init_server(dce_ctx, ep_server);
2663 2635 : if (!NT_STATUS_IS_OK(status)) {
2664 0 : DBG_ERR("Failed to init endpoint server '%s': %s\n",
2665 : ep_server_name, nt_errstr(status));
2666 0 : return status;
2667 : }
2668 :
2669 2635 : ep_server->initialized = true;
2670 :
2671 2635 : return NT_STATUS_OK;
2672 : }
2673 :
2674 545 : _PUBLIC_ NTSTATUS dcesrv_shutdown_registered_ep_servers(
2675 : struct dcesrv_context *dce_ctx)
2676 : {
2677 0 : NTSTATUS status;
2678 0 : int i;
2679 :
2680 2229 : for (i = 0; i < num_ep_servers; i++) {
2681 1684 : status = dcesrv_shutdown_ep_server(dce_ctx,
2682 1684 : ep_servers[i].ep_server->name);
2683 1684 : if (!NT_STATUS_IS_OK(status)) {
2684 0 : return status;
2685 : }
2686 : }
2687 :
2688 545 : return NT_STATUS_OK;
2689 : }
2690 :
2691 1684 : _PUBLIC_ NTSTATUS dcesrv_shutdown_ep_server(struct dcesrv_context *dce_ctx,
2692 : const char *ep_server_name)
2693 : {
2694 1684 : struct dcesrv_endpoint_server *ep_server = NULL;
2695 0 : NTSTATUS status;
2696 :
2697 1684 : ep_server = discard_const_p(struct dcesrv_endpoint_server,
2698 : dcesrv_ep_server_byname(ep_server_name));
2699 1684 : if (ep_server == NULL) {
2700 0 : DBG_ERR("Failed to find endpoint server '%s'\n",
2701 : ep_server_name);
2702 0 : return NT_STATUS_INTERNAL_ERROR;
2703 : }
2704 :
2705 1684 : if (!ep_server->initialized) {
2706 0 : return NT_STATUS_OK;
2707 : }
2708 :
2709 1684 : DBG_INFO("Shutting down DCE/RPC endpoint server '%s'\n",
2710 : ep_server_name);
2711 :
2712 1684 : status = ep_server->shutdown_server(dce_ctx, ep_server);
2713 1684 : if (!NT_STATUS_IS_OK(status)) {
2714 0 : DBG_ERR("Failed to shutdown endpoint server '%s': %s\n",
2715 : ep_server_name, nt_errstr(status));
2716 0 : return status;
2717 : }
2718 :
2719 1684 : ep_server->initialized = false;
2720 :
2721 1684 : return NT_STATUS_OK;
2722 : }
2723 :
2724 : /*
2725 : register a DCERPC endpoint server.
2726 :
2727 : The 'name' can be later used by other backends to find the operations
2728 : structure for this backend.
2729 :
2730 : */
2731 2783 : _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2732 : {
2733 :
2734 2783 : if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2735 : /* its already registered! */
2736 0 : DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2737 : ep_server->name));
2738 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
2739 : }
2740 :
2741 2783 : ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2742 2783 : if (!ep_servers) {
2743 0 : smb_panic("out of memory in dcerpc_register");
2744 : }
2745 :
2746 2783 : ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2747 2783 : ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2748 :
2749 2783 : num_ep_servers++;
2750 :
2751 2783 : DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2752 : ep_server->name));
2753 :
2754 2783 : return NT_STATUS_OK;
2755 : }
2756 :
2757 : /*
2758 : return the operations structure for a named backend of the specified type
2759 : */
2760 7102 : _PUBLIC_ const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2761 : {
2762 58 : int i;
2763 :
2764 31651 : for (i=0;i<num_ep_servers;i++) {
2765 28868 : if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2766 4319 : return ep_servers[i].ep_server;
2767 : }
2768 : }
2769 :
2770 2751 : return NULL;
2771 : }
2772 :
2773 : /*
2774 : return the DCERPC module version, and the size of some critical types
2775 : This can be used by endpoint server modules to either detect compilation errors, or provide
2776 : multiple implementations for different smbd compilation options in one module
2777 : */
2778 0 : const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2779 : {
2780 0 : static const struct dcesrv_critical_sizes critical_sizes = {
2781 : DCERPC_MODULE_VERSION,
2782 : sizeof(struct dcesrv_context),
2783 : sizeof(struct dcesrv_endpoint),
2784 : sizeof(struct dcesrv_endpoint_server),
2785 : sizeof(struct dcesrv_interface),
2786 : sizeof(struct dcesrv_if_list),
2787 : sizeof(struct dcesrv_connection),
2788 : sizeof(struct dcesrv_call_state),
2789 : sizeof(struct dcesrv_auth),
2790 : sizeof(struct dcesrv_handle)
2791 : };
2792 :
2793 0 : return &critical_sizes;
2794 : }
2795 :
2796 55328 : _PUBLIC_ void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2797 : {
2798 55328 : struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2799 55328 : struct dcesrv_auth *a = NULL;
2800 :
2801 55328 : dce_conn->wait_send = NULL;
2802 55328 : dce_conn->wait_recv = NULL;
2803 55328 : dce_conn->wait_private = NULL;
2804 :
2805 55328 : dce_conn->allow_bind = false;
2806 55328 : dce_conn->allow_alter = false;
2807 :
2808 55328 : dce_conn->default_auth_state->auth_invalid = true;
2809 :
2810 64227 : for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2811 8899 : a->auth_invalid = true;
2812 : }
2813 :
2814 55328 : if (dce_conn->pending_call_list == NULL) {
2815 55328 : char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2816 :
2817 55328 : DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2818 55328 : dce_conn->transport.terminate_connection(dce_conn,
2819 : full_reason ? full_reason : reason);
2820 54959 : return;
2821 : }
2822 :
2823 0 : if (dce_conn->terminate != NULL) {
2824 0 : return;
2825 : }
2826 :
2827 0 : DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2828 : reason));
2829 0 : dce_conn->terminate = talloc_strdup(dce_conn, reason);
2830 0 : if (dce_conn->terminate == NULL) {
2831 0 : dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2832 : }
2833 0 : DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2834 : }
2835 :
2836 971051 : _PUBLIC_ void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2837 : {
2838 10094 : struct dcesrv_connection *cur, *next;
2839 :
2840 971051 : next = dce_ctx->broken_connections;
2841 971051 : while (next != NULL) {
2842 0 : cur = next;
2843 0 : next = cur->next;
2844 :
2845 0 : if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2846 0 : struct dcesrv_connection_context *context_cur, *context_next;
2847 :
2848 0 : context_next = cur->contexts;
2849 0 : while (context_next != NULL) {
2850 0 : context_cur = context_next;
2851 0 : context_next = context_cur->next;
2852 :
2853 0 : dcesrv_connection_context_destructor(context_cur);
2854 : }
2855 : }
2856 :
2857 0 : dcesrv_terminate_connection(cur, cur->terminate);
2858 : }
2859 971051 : }
2860 :
2861 : struct dcesrv_sock_reply_state {
2862 : struct dcesrv_connection *dce_conn;
2863 : struct dcesrv_call_state *call;
2864 : struct iovec iov;
2865 : };
2866 :
2867 : static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2868 : static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2869 :
2870 897889 : _PUBLIC_ void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2871 : {
2872 7747 : struct dcesrv_call_state *call;
2873 :
2874 897889 : call = dce_conn->call_list;
2875 897889 : if (!call || !call->replies) {
2876 0 : return;
2877 : }
2878 :
2879 2086585 : while (call->replies) {
2880 1188696 : struct data_blob_list_item *rep = call->replies;
2881 7829 : struct dcesrv_sock_reply_state *substate;
2882 7829 : struct tevent_req *subreq;
2883 :
2884 1188696 : substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2885 1188696 : if (!substate) {
2886 0 : dcesrv_terminate_connection(dce_conn, "no memory");
2887 0 : return;
2888 : }
2889 :
2890 1188696 : substate->dce_conn = dce_conn;
2891 1188696 : substate->call = NULL;
2892 :
2893 1188696 : DLIST_REMOVE(call->replies, rep);
2894 :
2895 1188696 : if (call->replies == NULL && call->terminate_reason == NULL) {
2896 897465 : substate->call = call;
2897 : }
2898 :
2899 1188696 : substate->iov.iov_base = (void *) rep->blob.data;
2900 1188696 : substate->iov.iov_len = rep->blob.length;
2901 :
2902 1196525 : subreq = tstream_writev_queue_send(substate,
2903 : dce_conn->event_ctx,
2904 : dce_conn->stream,
2905 : dce_conn->send_queue,
2906 1188696 : &substate->iov, 1);
2907 1188696 : if (!subreq) {
2908 0 : dcesrv_terminate_connection(dce_conn, "no memory");
2909 0 : return;
2910 : }
2911 1188696 : tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2912 : substate);
2913 : }
2914 :
2915 897889 : if (call->terminate_reason != NULL) {
2916 24 : struct tevent_req *subreq;
2917 :
2918 424 : subreq = tevent_queue_wait_send(call,
2919 : dce_conn->event_ctx,
2920 : dce_conn->send_queue);
2921 424 : if (!subreq) {
2922 0 : dcesrv_terminate_connection(dce_conn, __location__);
2923 0 : return;
2924 : }
2925 424 : tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2926 : call);
2927 : }
2928 :
2929 897889 : DLIST_REMOVE(call->conn->call_list, call);
2930 897889 : call->list = DCESRV_LIST_NONE;
2931 : }
2932 :
2933 1188681 : static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2934 : {
2935 1188681 : struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2936 : struct dcesrv_sock_reply_state);
2937 7826 : int ret;
2938 7826 : int sys_errno;
2939 7826 : NTSTATUS status;
2940 1188681 : struct dcesrv_call_state *call = substate->call;
2941 :
2942 1188681 : ret = tstream_writev_queue_recv(subreq, &sys_errno);
2943 1188681 : TALLOC_FREE(subreq);
2944 1188681 : if (ret == -1) {
2945 0 : status = map_nt_error_from_unix_common(sys_errno);
2946 0 : dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2947 0 : return;
2948 : }
2949 :
2950 1188681 : talloc_free(substate);
2951 1188681 : if (call) {
2952 897465 : talloc_free(call);
2953 : }
2954 : }
2955 :
2956 : static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2957 :
2958 409 : static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2959 : {
2960 409 : struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2961 : struct dcesrv_call_state);
2962 21 : bool ok;
2963 21 : struct timeval tv;
2964 :
2965 : /* make sure we stop send queue before removing subreq */
2966 409 : tevent_queue_stop(call->conn->send_queue);
2967 :
2968 409 : ok = tevent_queue_wait_recv(subreq);
2969 409 : TALLOC_FREE(subreq);
2970 409 : if (!ok) {
2971 0 : dcesrv_terminate_connection(call->conn, __location__);
2972 0 : return;
2973 : }
2974 :
2975 : /* disconnect after 200 usecs */
2976 409 : tv = timeval_current_ofs_usec(200);
2977 409 : subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2978 409 : if (subreq == NULL) {
2979 0 : dcesrv_terminate_connection(call->conn, __location__);
2980 0 : return;
2981 : }
2982 409 : tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2983 : call);
2984 : }
2985 :
2986 334 : static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2987 : {
2988 334 : struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2989 : struct dcesrv_call_state);
2990 12 : bool ok;
2991 :
2992 334 : ok = tevent_wakeup_recv(subreq);
2993 334 : TALLOC_FREE(subreq);
2994 334 : if (!ok) {
2995 0 : dcesrv_terminate_connection(call->conn, __location__);
2996 0 : return;
2997 : }
2998 :
2999 334 : dcesrv_terminate_connection(call->conn, call->terminate_reason);
3000 : }
3001 :
3002 : static void dcesrv_conn_wait_done(struct tevent_req *subreq);
3003 :
3004 934893 : static void dcesrv_read_fragment_done(struct tevent_req *subreq)
3005 : {
3006 934893 : struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
3007 : struct dcesrv_connection);
3008 934893 : struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
3009 8696 : struct ncacn_packet *pkt;
3010 8696 : DATA_BLOB buffer;
3011 8696 : NTSTATUS status;
3012 :
3013 934893 : if (dce_conn->terminate) {
3014 : /*
3015 : * if the current connection is broken
3016 : * we need to clean it up before any other connection
3017 : */
3018 0 : dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
3019 0 : dcesrv_cleanup_broken_connections(dce_ctx);
3020 54635 : return;
3021 : }
3022 :
3023 934893 : dcesrv_cleanup_broken_connections(dce_ctx);
3024 :
3025 934893 : status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
3026 : &pkt, &buffer);
3027 934893 : TALLOC_FREE(subreq);
3028 934893 : if (!NT_STATUS_IS_OK(status)) {
3029 54994 : dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3030 54635 : return;
3031 : }
3032 :
3033 879899 : dcesrv_loop_next_packet(dce_conn, pkt, buffer);
3034 : }
3035 :
3036 : /**
3037 : * @brief Start the dcesrv loop, inducing the bind as a blob
3038 : *
3039 : * Like dcesrv_connection_loop_start() but used from connections
3040 : * where the caller has already read the dcerpc bind packet from
3041 : * the socket and is available as a DATA_BLOB.
3042 : *
3043 : * @param[in] dce_conn The connection to start
3044 : * @param[in] pkt The parsed bind packet
3045 : * @param[in] buffer The full binary bind including auth data
3046 : */
3047 914759 : void dcesrv_loop_next_packet(
3048 : struct dcesrv_connection *dce_conn,
3049 : struct ncacn_packet *pkt,
3050 : DATA_BLOB buffer)
3051 : {
3052 914759 : struct tevent_req *subreq = NULL;
3053 7830 : NTSTATUS status;
3054 :
3055 914759 : status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
3056 914759 : if (!NT_STATUS_IS_OK(status)) {
3057 0 : dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3058 15143 : return;
3059 : }
3060 :
3061 : /*
3062 : * This is used to block the connection during
3063 : * pending authentication.
3064 : */
3065 914759 : if (dce_conn->wait_send != NULL) {
3066 15663 : subreq = dce_conn->wait_send(dce_conn,
3067 : dce_conn->event_ctx,
3068 : dce_conn->wait_private);
3069 15663 : if (!subreq) {
3070 0 : status = NT_STATUS_NO_MEMORY;
3071 0 : dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3072 0 : return;
3073 : }
3074 15663 : tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
3075 15663 : return;
3076 : }
3077 :
3078 899096 : subreq = dcerpc_read_ncacn_packet_send(dce_conn,
3079 : dce_conn->event_ctx,
3080 : dce_conn->stream);
3081 899096 : if (!subreq) {
3082 0 : status = NT_STATUS_NO_MEMORY;
3083 0 : dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3084 0 : return;
3085 : }
3086 899096 : tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
3087 : }
3088 :
3089 15663 : static void dcesrv_conn_wait_done(struct tevent_req *subreq)
3090 : {
3091 15663 : struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
3092 : struct dcesrv_connection);
3093 15663 : struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
3094 520 : NTSTATUS status;
3095 :
3096 15663 : if (dce_conn->terminate) {
3097 : /*
3098 : * if the current connection is broken
3099 : * we need to clean it up before any other connection
3100 : */
3101 0 : dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
3102 0 : dcesrv_cleanup_broken_connections(dce_ctx);
3103 0 : return;
3104 : }
3105 :
3106 15663 : dcesrv_cleanup_broken_connections(dce_ctx);
3107 :
3108 15663 : status = dce_conn->wait_recv(subreq);
3109 15663 : dce_conn->wait_send = NULL;
3110 15663 : dce_conn->wait_recv = NULL;
3111 15663 : dce_conn->wait_private = NULL;
3112 15663 : TALLOC_FREE(subreq);
3113 15663 : if (!NT_STATUS_IS_OK(status)) {
3114 0 : dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3115 0 : return;
3116 : }
3117 :
3118 15663 : status = dcesrv_connection_loop_start(dce_conn);
3119 15663 : if (!NT_STATUS_IS_OK(status)) {
3120 0 : dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3121 0 : return;
3122 : }
3123 : }
3124 :
3125 : /**
3126 : * retrieve credentials from a dce_call
3127 : */
3128 4 : _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3129 : {
3130 4 : struct dcesrv_auth *auth = dce_call->auth_state;
3131 4 : SMB_ASSERT(auth->auth_finished);
3132 4 : return auth->session_info->credentials;
3133 : }
3134 :
3135 : /**
3136 : * returns true if this is an authenticated call
3137 : */
3138 0 : _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3139 : {
3140 0 : struct dcesrv_auth *auth = dce_call->auth_state;
3141 0 : enum security_user_level level;
3142 0 : SMB_ASSERT(auth->auth_finished);
3143 0 : level = security_session_user_level(auth->session_info, NULL);
3144 0 : return level >= SECURITY_USER;
3145 : }
3146 :
3147 : /**
3148 : * retrieve account_name for a dce_call
3149 : */
3150 0 : _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3151 : {
3152 0 : struct dcesrv_auth *auth = dce_call->auth_state;
3153 0 : SMB_ASSERT(auth->auth_finished);
3154 0 : return auth->session_info->info->account_name;
3155 : }
3156 :
3157 : /**
3158 : * retrieve session_info from a dce_call
3159 : */
3160 1152650 : _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3161 : {
3162 1152650 : struct dcesrv_auth *auth = dce_call->auth_state;
3163 1152650 : SMB_ASSERT(auth->auth_finished);
3164 1152650 : return auth->session_info;
3165 : }
3166 :
3167 : /**
3168 : * retrieve auth type/level from a dce_call
3169 : */
3170 44621 : _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
3171 : enum dcerpc_AuthType *auth_type,
3172 : enum dcerpc_AuthLevel *auth_level)
3173 : {
3174 44621 : struct dcesrv_auth *auth = dce_call->auth_state;
3175 :
3176 44621 : SMB_ASSERT(auth->auth_finished);
3177 :
3178 44621 : if (auth_type != NULL) {
3179 29331 : *auth_type = auth->auth_type;
3180 : }
3181 44621 : if (auth_level != NULL) {
3182 42381 : *auth_level = auth->auth_level;
3183 : }
3184 44621 : }
3185 :
3186 36158 : _PUBLIC_ NTSTATUS dcesrv_connection_loop_start(struct dcesrv_connection *conn)
3187 : {
3188 1398 : struct tevent_req *subreq;
3189 :
3190 36158 : subreq = dcerpc_read_ncacn_packet_send(conn,
3191 : conn->event_ctx,
3192 : conn->stream);
3193 36158 : if (subreq == NULL) {
3194 0 : return NT_STATUS_NO_MEMORY;
3195 : }
3196 36158 : tevent_req_set_callback(subreq, dcesrv_read_fragment_done, conn);
3197 :
3198 36158 : return NT_STATUS_OK;
3199 : }
3200 :
3201 0 : _PUBLIC_ NTSTATUS dcesrv_call_dispatch_local(struct dcesrv_call_state *call)
3202 : {
3203 0 : NTSTATUS status;
3204 0 : struct ndr_pull *pull = NULL;
3205 0 : struct ndr_push *push = NULL;
3206 0 : struct data_blob_list_item *rep = NULL;
3207 :
3208 0 : pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier,
3209 : call);
3210 0 : if (pull == NULL) {
3211 0 : return NT_STATUS_NO_MEMORY;
3212 : }
3213 :
3214 0 : pull->flags |= LIBNDR_FLAG_REF_ALLOC;
3215 :
3216 0 : call->ndr_pull = pull;
3217 :
3218 : /* unravel the NDR for the packet */
3219 0 : status = call->context->iface->ndr_pull(call, call, pull, &call->r);
3220 0 : if (!NT_STATUS_IS_OK(status)) {
3221 0 : DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3222 : call->context->iface->name,
3223 : call->pkt.u.request.opnum,
3224 : dcerpc_errstr(call, call->fault_code));
3225 0 : return dcerpc_fault_to_nt_status(call->fault_code);
3226 : }
3227 :
3228 0 : status = call->context->iface->local(call, call, call->r);
3229 0 : if (!NT_STATUS_IS_OK(status)) {
3230 0 : DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3231 : call->context->iface->name,
3232 : call->pkt.u.request.opnum,
3233 : dcerpc_errstr(call, call->fault_code));
3234 0 : return dcerpc_fault_to_nt_status(call->fault_code);
3235 : }
3236 :
3237 : /* This can never go async for now! */
3238 0 : SMB_ASSERT(!(call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC));
3239 :
3240 : /* call the reply function */
3241 0 : status = call->context->iface->reply(call, call, call->r);
3242 0 : if (!NT_STATUS_IS_OK(status)) {
3243 0 : DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3244 : call->context->iface->name,
3245 : call->pkt.u.request.opnum,
3246 : dcerpc_errstr(call, call->fault_code));
3247 0 : return dcerpc_fault_to_nt_status(call->fault_code);
3248 : }
3249 :
3250 0 : push = ndr_push_init_ctx(call);
3251 0 : if (push == NULL) {
3252 0 : return NT_STATUS_NO_MEMORY;
3253 : }
3254 :
3255 0 : push->ptr_count = call->ndr_pull->ptr_count;
3256 :
3257 0 : status = call->context->iface->ndr_push(call, call, push, call->r);
3258 0 : if (!NT_STATUS_IS_OK(status)) {
3259 0 : DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3260 : call->context->iface->name,
3261 : call->pkt.u.request.opnum,
3262 : dcerpc_errstr(call, call->fault_code));
3263 0 : return dcerpc_fault_to_nt_status(call->fault_code);
3264 : }
3265 :
3266 0 : rep = talloc_zero(call, struct data_blob_list_item);
3267 0 : if (rep == NULL) {
3268 0 : return NT_STATUS_NO_MEMORY;
3269 : }
3270 :
3271 0 : rep->blob = ndr_push_blob(push);
3272 0 : DLIST_ADD_END(call->replies, rep);
3273 :
3274 0 : return NT_STATUS_OK;
3275 : }
|