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