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