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