s4:rpc_server: implement async ALTER_CONTEXT using gensec_update_send/recv
[samba.git] / source4 / rpc_server / dcerpc_server.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    server side dcerpc core code
5
6    Copyright (C) Andrew Tridgell 2003-2005
7    Copyright (C) Stefan (metze) Metzmacher 2004-2005
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "../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 static void dcesrv_alter_done(struct tevent_req *subreq);
1497
1498 /*
1499   handle a alter context request
1500 */
1501 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1502 {
1503         struct dcesrv_connection *conn = call->conn;
1504         NTSTATUS status;
1505         bool auth_ok = false;
1506         struct ncacn_packet *pkt = &call->ack_pkt;
1507         uint32_t extra_flags = 0;
1508         struct dcesrv_auth *auth = &call->conn->auth_state;
1509         struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1510         struct tevent_req *subreq = NULL;
1511         size_t i;
1512
1513         if (!call->conn->allow_alter) {
1514                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1515         }
1516
1517         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1518                         DCERPC_PKT_ALTER,
1519                         call->pkt.u.alter.auth_info.length,
1520                         0, /* required flags */
1521                         DCERPC_PFC_FLAG_FIRST |
1522                         DCERPC_PFC_FLAG_LAST |
1523                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1524                         0x08 | /* this is not defined, but should be ignored */
1525                         DCERPC_PFC_FLAG_CONC_MPX |
1526                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1527                         DCERPC_PFC_FLAG_MAYBE |
1528                         DCERPC_PFC_FLAG_OBJECT_UUID);
1529         if (!NT_STATUS_IS_OK(status)) {
1530                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1531         }
1532
1533         auth_ok = dcesrv_auth_alter(call);
1534         if (!auth_ok) {
1535                 if (call->fault_code != 0) {
1536                         return dcesrv_fault_disconnect(call, call->fault_code);
1537                 }
1538         }
1539
1540         if (call->pkt.u.alter.num_contexts < 1) {
1541                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1542         }
1543
1544         ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1545                                          call->pkt.u.alter.num_contexts);
1546         if (ack_ctx_list == NULL) {
1547                 return NT_STATUS_NO_MEMORY;
1548         }
1549
1550         /*
1551          * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1552          * dcesrv_check_or_create_context()) and do some protocol validation
1553          * and set sane defaults.
1554          */
1555         for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1556                 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1557                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1558
1559                 if (c->num_transfer_syntaxes == 0) {
1560                         return dcesrv_fault_disconnect(call,
1561                                         DCERPC_NCA_S_PROTO_ERROR);
1562                 }
1563
1564                 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1565                 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1566         }
1567
1568         /*
1569          * Try to negotiate one new presentation context.
1570          */
1571         status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1572         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1573                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1574         }
1575         if (!NT_STATUS_IS_OK(status)) {
1576                 return status;
1577         }
1578
1579         if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1580             (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1581                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1582                 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1583         }
1584
1585         if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1586                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1587         }
1588
1589         /* handle any authentication that is being requested */
1590         if (!auth_ok) {
1591                 if (call->in_auth_info.auth_type !=
1592                     call->conn->auth_state.auth_type)
1593                 {
1594                         return dcesrv_fault_disconnect(call,
1595                                         DCERPC_FAULT_SEC_PKG_ERROR);
1596                 }
1597                 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1598         }
1599
1600         dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1601         pkt->auth_length = 0;
1602         pkt->call_id = call->pkt.call_id;
1603         pkt->ptype = DCERPC_PKT_ALTER_RESP;
1604         pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1605         pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1606         pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1607         pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1608         pkt->u.alter_resp.secondary_address = "";
1609         pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1610         pkt->u.alter_resp.ctx_list = ack_ctx_list;
1611         pkt->u.alter_resp.auth_info = data_blob_null;
1612
1613         status = dcesrv_auth_prepare_alter_ack(call, pkt);
1614         if (!NT_STATUS_IS_OK(status)) {
1615                 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1616         }
1617
1618         if (auth->auth_finished) {
1619                 return dcesrv_auth_reply(call);
1620         }
1621
1622         subreq = gensec_update_send(call, call->event_ctx,
1623                                     auth->gensec_security,
1624                                     call->in_auth_info.credentials);
1625         if (subreq == NULL) {
1626                 return NT_STATUS_NO_MEMORY;
1627         }
1628         tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1629
1630         return dcesrv_conn_auth_wait_setup(conn);
1631 }
1632
1633 static void dcesrv_alter_done(struct tevent_req *subreq)
1634 {
1635         struct dcesrv_call_state *call =
1636                 tevent_req_callback_data(subreq,
1637                 struct dcesrv_call_state);
1638         struct dcesrv_connection *conn = call->conn;
1639         NTSTATUS status;
1640
1641         status = gensec_update_recv(subreq, call,
1642                                     &call->out_auth_info->credentials);
1643         TALLOC_FREE(subreq);
1644
1645         status = dcesrv_auth_complete(call, status);
1646         if (!NT_STATUS_IS_OK(status)) {
1647                 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1648                 dcesrv_conn_auth_wait_finished(conn, status);
1649                 return;
1650         }
1651
1652         status = dcesrv_auth_reply(call);
1653         dcesrv_conn_auth_wait_finished(conn, status);
1654         return;
1655 }
1656
1657 /*
1658   possibly save the call for inspection with ndrdump
1659  */
1660 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1661 {
1662 #ifdef DEVELOPER
1663         char *fname;
1664         const char *dump_dir;
1665         dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1666         if (!dump_dir) {
1667                 return;
1668         }
1669         fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1670                                 dump_dir,
1671                                 call->context->iface->name,
1672                                 call->pkt.u.request.opnum,
1673                                 why);
1674         if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1675                 DEBUG(0,("RPC SAVED %s\n", fname));
1676         }
1677         talloc_free(fname);
1678 #endif
1679 }
1680
1681 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1682 {
1683         TALLOC_CTX *frame = talloc_stackframe();
1684         const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1685                 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1686         const struct dcerpc_sec_vt_pcontext pcontext = {
1687                 .abstract_syntax = call->context->iface->syntax_id,
1688                 .transfer_syntax = call->context->transfer_syntax,
1689         };
1690         const struct dcerpc_sec_vt_header2 header2 =
1691                 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1692         enum ndr_err_code ndr_err;
1693         struct dcerpc_sec_verification_trailer *vt = NULL;
1694         NTSTATUS status = NT_STATUS_OK;
1695         bool ok;
1696
1697         SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1698
1699         ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1700                                                           frame, &vt);
1701         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1702                 status = ndr_map_error2ntstatus(ndr_err);
1703                 goto done;
1704         }
1705
1706         ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1707                                                    &pcontext, &header2);
1708         if (!ok) {
1709                 status = NT_STATUS_ACCESS_DENIED;
1710                 goto done;
1711         }
1712 done:
1713         TALLOC_FREE(frame);
1714         return status;
1715 }
1716
1717 /*
1718   handle a dcerpc request packet
1719 */
1720 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1721 {
1722         const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1723         enum dcerpc_transport_t transport =
1724                 dcerpc_binding_get_transport(endpoint->ep_description);
1725         struct ndr_pull *pull;
1726         NTSTATUS status;
1727
1728         if (!call->conn->allow_request) {
1729                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1730         }
1731
1732         /* if authenticated, and the mech we use can't do async replies, don't use them... */
1733         if (call->conn->auth_state.gensec_security && 
1734             !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1735                 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1736         }
1737
1738         if (call->context == NULL) {
1739                 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1740                                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1741         }
1742
1743         switch (call->conn->auth_state.auth_level) {
1744         case DCERPC_AUTH_LEVEL_NONE:
1745         case DCERPC_AUTH_LEVEL_PACKET:
1746         case DCERPC_AUTH_LEVEL_INTEGRITY:
1747         case DCERPC_AUTH_LEVEL_PRIVACY:
1748                 break;
1749         default:
1750                 if (!call->context->allow_connect) {
1751                         char *addr;
1752
1753                         addr = tsocket_address_string(call->conn->remote_address,
1754                                                       call);
1755
1756                         DEBUG(2, ("%s: restrict auth_level_connect access "
1757                                   "to [%s] with auth[type=0x%x,level=0x%x] "
1758                                   "on [%s] from [%s]\n",
1759                                   __func__, call->context->iface->name,
1760                                   call->conn->auth_state.auth_type,
1761                                   call->conn->auth_state.auth_level,
1762                                   derpc_transport_string_by_transport(transport),
1763                                   addr));
1764                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1765                 }
1766                 break;
1767         }
1768
1769         if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1770                 char *addr;
1771
1772                 addr = tsocket_address_string(call->conn->remote_address, call);
1773
1774                 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1775                           "to [%s] with auth[type=0x%x,level=0x%x] "
1776                           "on [%s] from [%s]\n",
1777                           __func__,
1778                           call->context->min_auth_level,
1779                           call->context->iface->name,
1780                           call->conn->auth_state.auth_type,
1781                           call->conn->auth_state.auth_level,
1782                           derpc_transport_string_by_transport(transport),
1783                           addr));
1784                 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1785         }
1786
1787         pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1788         NT_STATUS_HAVE_NO_MEMORY(pull);
1789
1790         pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1791
1792         call->ndr_pull  = pull;
1793
1794         if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1795                 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1796         }
1797
1798         status = dcesrv_check_verification_trailer(call);
1799         if (!NT_STATUS_IS_OK(status)) {
1800                 uint32_t faultcode = DCERPC_FAULT_OTHER;
1801                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1802                         faultcode = DCERPC_FAULT_ACCESS_DENIED;
1803                 }
1804                 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1805                            nt_errstr(status)));
1806                 return dcesrv_fault(call, faultcode);
1807         }
1808
1809         /* unravel the NDR for the packet */
1810         status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1811         if (!NT_STATUS_IS_OK(status)) {
1812                 uint8_t extra_flags = 0;
1813                 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1814                         /* we got an unknown call */
1815                         DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1816                                  call->pkt.u.request.opnum,
1817                                  call->context->iface->name));
1818                         dcesrv_save_call(call, "unknown");
1819                         extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1820                 } else {
1821                         dcesrv_save_call(call, "pullfail");
1822                 }
1823                 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1824         }
1825
1826         if (pull->offset != pull->data_size) {
1827                 dcesrv_save_call(call, "extrabytes");
1828                 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n", 
1829                          pull->data_size - pull->offset));
1830         }
1831
1832         /* call the dispatch function */
1833         status = call->context->iface->dispatch(call, call, call->r);
1834         if (!NT_STATUS_IS_OK(status)) {
1835                 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1836                          call->context->iface->name,
1837                          call->pkt.u.request.opnum,
1838                          dcerpc_errstr(pull, call->fault_code)));
1839                 return dcesrv_fault(call, call->fault_code);
1840         }
1841
1842         /* add the call to the pending list */
1843         dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1844
1845         if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1846                 return NT_STATUS_OK;
1847         }
1848
1849         return dcesrv_reply(call);
1850 }
1851
1852
1853 /*
1854   remove the call from the right list when freed
1855  */
1856 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1857 {
1858         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1859         return 0;
1860 }
1861
1862 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1863 {
1864         return conn->local_address;
1865 }
1866
1867 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1868 {
1869         return conn->remote_address;
1870 }
1871
1872 /*
1873   process some input to a dcerpc endpoint server.
1874 */
1875 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1876                                             struct ncacn_packet *pkt,
1877                                             DATA_BLOB blob)
1878 {
1879         NTSTATUS status;
1880         struct dcesrv_call_state *call;
1881         struct dcesrv_call_state *existing = NULL;
1882
1883         call = talloc_zero(dce_conn, struct dcesrv_call_state);
1884         if (!call) {
1885                 data_blob_free(&blob);
1886                 talloc_free(pkt);
1887                 return NT_STATUS_NO_MEMORY;
1888         }
1889         call->conn              = dce_conn;
1890         call->event_ctx         = dce_conn->event_ctx;
1891         call->msg_ctx           = dce_conn->msg_ctx;
1892         call->state_flags       = call->conn->state_flags;
1893         call->time              = timeval_current();
1894         call->list              = DCESRV_LIST_NONE;
1895
1896         talloc_steal(call, pkt);
1897         talloc_steal(call, blob.data);
1898         call->pkt = *pkt;
1899
1900         talloc_set_destructor(call, dcesrv_call_dequeue);
1901
1902         if (call->conn->allow_bind) {
1903                 /*
1904                  * Only one bind is possible per connection
1905                  */
1906                 call->conn->allow_bind = false;
1907                 return dcesrv_bind(call);
1908         }
1909
1910         /* we have to check the signing here, before combining the
1911            pdus */
1912         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1913                 if (!call->conn->allow_request) {
1914                         return dcesrv_fault_disconnect(call,
1915                                         DCERPC_NCA_S_PROTO_ERROR);
1916                 }
1917
1918                 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1919                                 DCERPC_PKT_REQUEST,
1920                                 call->pkt.u.request.stub_and_verifier.length,
1921                                 0, /* required_flags */
1922                                 DCERPC_PFC_FLAG_FIRST |
1923                                 DCERPC_PFC_FLAG_LAST |
1924                                 DCERPC_PFC_FLAG_PENDING_CANCEL |
1925                                 0x08 | /* this is not defined, but should be ignored */
1926                                 DCERPC_PFC_FLAG_CONC_MPX |
1927                                 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1928                                 DCERPC_PFC_FLAG_MAYBE |
1929                                 DCERPC_PFC_FLAG_OBJECT_UUID);
1930                 if (!NT_STATUS_IS_OK(status)) {
1931                         return dcesrv_fault_disconnect(call,
1932                                         DCERPC_NCA_S_PROTO_ERROR);
1933                 }
1934
1935                 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1936                         /*
1937                          * We don't use dcesrv_fault_disconnect()
1938                          * here, because we don't want to set
1939                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1940                          *
1941                          * Note that we don't check against the negotiated
1942                          * max_recv_frag, but a hard coded value.
1943                          */
1944                         dcesrv_call_disconnect_after(call,
1945                                 "dcesrv_auth_request - frag_length too large");
1946                         return dcesrv_fault(call,
1947                                         DCERPC_NCA_S_PROTO_ERROR);
1948                 }
1949
1950                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1951                         if (dce_conn->pending_call_list != NULL) {
1952                                 /*
1953                                  * concurrent requests are only allowed
1954                                  * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1955                                  */
1956                                 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1957                                         dcesrv_call_disconnect_after(call,
1958                                                 "dcesrv_auth_request - "
1959                                                 "existing pending call without CONN_MPX");
1960                                         return dcesrv_fault(call,
1961                                                 DCERPC_NCA_S_PROTO_ERROR);
1962                                 }
1963                         }
1964                         /* only one request is possible in the fragmented list */
1965                         if (dce_conn->incoming_fragmented_call_list != NULL) {
1966                                 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1967                                         /*
1968                                          * Without DCERPC_PFC_FLAG_CONC_MPX
1969                                          * we need to return the FAULT on the
1970                                          * already existing call.
1971                                          *
1972                                          * This is important to get the
1973                                          * call_id and context_id right.
1974                                          */
1975                                         TALLOC_FREE(call);
1976                                         call = dce_conn->incoming_fragmented_call_list;
1977                                 }
1978                                 dcesrv_call_disconnect_after(call,
1979                                         "dcesrv_auth_request - "
1980                                         "existing fragmented call");
1981                                 return dcesrv_fault(call,
1982                                                 DCERPC_NCA_S_PROTO_ERROR);
1983                         }
1984                         if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1985                                 return dcesrv_fault_disconnect(call,
1986                                                 DCERPC_FAULT_NO_CALL_ACTIVE);
1987                         }
1988                         call->context = dcesrv_find_context(call->conn,
1989                                                 call->pkt.u.request.context_id);
1990                         if (call->context == NULL) {
1991                                 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1992                                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1993                         }
1994                 } else {
1995                         const struct dcerpc_request *nr = &call->pkt.u.request;
1996                         const struct dcerpc_request *er = NULL;
1997                         int cmp;
1998
1999                         existing = dcesrv_find_fragmented_call(dce_conn,
2000                                                         call->pkt.call_id);
2001                         if (existing == NULL) {
2002                                 dcesrv_call_disconnect_after(call,
2003                                         "dcesrv_auth_request - "
2004                                         "no existing fragmented call");
2005                                 return dcesrv_fault(call,
2006                                                 DCERPC_NCA_S_PROTO_ERROR);
2007                         }
2008                         er = &existing->pkt.u.request;
2009
2010                         if (call->pkt.ptype != existing->pkt.ptype) {
2011                                 /* trying to play silly buggers are we? */
2012                                 return dcesrv_fault_disconnect(existing,
2013                                                 DCERPC_NCA_S_PROTO_ERROR);
2014                         }
2015                         cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2016                                      sizeof(pkt->drep));
2017                         if (cmp != 0) {
2018                                 return dcesrv_fault_disconnect(existing,
2019                                                 DCERPC_NCA_S_PROTO_ERROR);
2020                         }
2021                         if (nr->context_id != er->context_id)  {
2022                                 return dcesrv_fault_disconnect(existing,
2023                                                 DCERPC_NCA_S_PROTO_ERROR);
2024                         }
2025                         if (nr->opnum != er->opnum)  {
2026                                 return dcesrv_fault_disconnect(existing,
2027                                                 DCERPC_NCA_S_PROTO_ERROR);
2028                         }
2029                 }
2030         }
2031
2032         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2033                 bool ok;
2034                 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2035
2036                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2037                         payload_offset += 16;
2038                 }
2039
2040                 ok = dcesrv_auth_pkt_pull(call, &blob,
2041                                           0, /* required_flags */
2042                                           DCERPC_PFC_FLAG_FIRST |
2043                                           DCERPC_PFC_FLAG_LAST |
2044                                           DCERPC_PFC_FLAG_PENDING_CANCEL |
2045                                           0x08 | /* this is not defined, but should be ignored */
2046                                           DCERPC_PFC_FLAG_CONC_MPX |
2047                                           DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2048                                           DCERPC_PFC_FLAG_MAYBE |
2049                                           DCERPC_PFC_FLAG_OBJECT_UUID,
2050                                           payload_offset,
2051                                           &call->pkt.u.request.stub_and_verifier);
2052                 if (!ok) {
2053                         /*
2054                          * We don't use dcesrv_fault_disconnect()
2055                          * here, because we don't want to set
2056                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2057                          */
2058                         dcesrv_call_disconnect_after(call,
2059                                                 "dcesrv_auth_request - failed");
2060                         if (call->fault_code == 0) {
2061                                 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2062                         }
2063                         return dcesrv_fault(call, call->fault_code);
2064                 }
2065         }
2066
2067         /* see if this is a continued packet */
2068         if (existing != NULL) {
2069                 struct dcerpc_request *er = &existing->pkt.u.request;
2070                 const struct dcerpc_request *nr = &call->pkt.u.request;
2071                 size_t available;
2072                 size_t alloc_size;
2073                 size_t alloc_hint;
2074
2075                 /*
2076                  * Up to 4 MByte are allowed by all fragments
2077                  */
2078                 available = dce_conn->max_total_request_size;
2079                 if (er->stub_and_verifier.length > available) {
2080                         dcesrv_call_disconnect_after(existing,
2081                                 "dcesrv_auth_request - existing payload too large");
2082                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2083                 }
2084                 available -= er->stub_and_verifier.length;
2085                 if (nr->alloc_hint > available) {
2086                         dcesrv_call_disconnect_after(existing,
2087                                 "dcesrv_auth_request - alloc hint too large");
2088                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2089                 }
2090                 if (nr->stub_and_verifier.length > available) {
2091                         dcesrv_call_disconnect_after(existing,
2092                                 "dcesrv_auth_request - new payload too large");
2093                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2094                 }
2095                 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2096                 /* allocate at least 1 byte */
2097                 alloc_hint = MAX(alloc_hint, 1);
2098                 alloc_size = er->stub_and_verifier.length +
2099                              nr->stub_and_verifier.length;
2100                 alloc_size = MAX(alloc_size, alloc_hint);
2101
2102                 er->stub_and_verifier.data =
2103                         talloc_realloc(existing,
2104                                        er->stub_and_verifier.data,
2105                                        uint8_t, alloc_size);
2106                 if (er->stub_and_verifier.data == NULL) {
2107                         TALLOC_FREE(call);
2108                         return dcesrv_fault_with_flags(existing,
2109                                                        DCERPC_FAULT_OUT_OF_RESOURCES,
2110                                                        DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2111                 }
2112                 memcpy(er->stub_and_verifier.data +
2113                        er->stub_and_verifier.length,
2114                        nr->stub_and_verifier.data,
2115                        nr->stub_and_verifier.length);
2116                 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2117
2118                 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2119
2120                 TALLOC_FREE(call);
2121                 call = existing;
2122         }
2123
2124         /* this may not be the last pdu in the chain - if its isn't then
2125            just put it on the incoming_fragmented_call_list and wait for the rest */
2126         if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2127             !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2128                 /*
2129                  * Up to 4 MByte are allowed by all fragments
2130                  */
2131                 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2132                         dcesrv_call_disconnect_after(call,
2133                                 "dcesrv_auth_request - initial alloc hint too large");
2134                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2135                 }
2136                 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2137                 return NT_STATUS_OK;
2138         } 
2139         
2140         /* This removes any fragments we may have had stashed away */
2141         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2142
2143         switch (call->pkt.ptype) {
2144         case DCERPC_PKT_BIND:
2145                 status = dcesrv_bind_nak(call,
2146                         DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2147                 break;
2148         case DCERPC_PKT_AUTH3:
2149                 status = dcesrv_auth3(call);
2150                 break;
2151         case DCERPC_PKT_ALTER:
2152                 status = dcesrv_alter(call);
2153                 break;
2154         case DCERPC_PKT_REQUEST:
2155                 status = dcesrv_request(call);
2156                 break;
2157         case DCERPC_PKT_CO_CANCEL:
2158         case DCERPC_PKT_ORPHANED:
2159                 /*
2160                  * Window just ignores CO_CANCEL and ORPHANED,
2161                  * so we do...
2162                  */
2163                 status = NT_STATUS_OK;
2164                 TALLOC_FREE(call);
2165                 break;
2166         case DCERPC_PKT_BIND_ACK:
2167         case DCERPC_PKT_BIND_NAK:
2168         case DCERPC_PKT_ALTER_RESP:
2169         case DCERPC_PKT_RESPONSE:
2170         case DCERPC_PKT_FAULT:
2171         case DCERPC_PKT_SHUTDOWN:
2172         default:
2173                 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2174                 break;
2175         }
2176
2177         /* if we are going to be sending a reply then add
2178            it to the list of pending calls. We add it to the end to keep the call
2179            list in the order we will answer */
2180         if (!NT_STATUS_IS_OK(status)) {
2181                 talloc_free(call);
2182         }
2183
2184         return status;
2185 }
2186
2187 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, 
2188                                       struct loadparm_context *lp_ctx,
2189                                       const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2190 {
2191         NTSTATUS status;
2192         struct dcesrv_context *dce_ctx;
2193         int i;
2194
2195         if (!endpoint_servers) {
2196                 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2197                 return NT_STATUS_INTERNAL_ERROR;
2198         }
2199
2200         dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2201         NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2202
2203         if (uid_wrapper_enabled()) {
2204                 setenv("UID_WRAPPER_MYUID", "1", 1);
2205         }
2206         dce_ctx->initial_euid = geteuid();
2207         if (uid_wrapper_enabled()) {
2208                 unsetenv("UID_WRAPPER_MYUID");
2209         }
2210
2211         dce_ctx->endpoint_list  = NULL;
2212         dce_ctx->lp_ctx = lp_ctx;
2213         dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2214         NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2215         dce_ctx->broken_connections = NULL;
2216
2217         for (i=0;endpoint_servers[i];i++) {
2218                 const struct dcesrv_endpoint_server *ep_server;
2219
2220                 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2221                 if (!ep_server) {
2222                         DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2223                         return NT_STATUS_INTERNAL_ERROR;
2224                 }
2225
2226                 status = ep_server->init_server(dce_ctx, ep_server);
2227                 if (!NT_STATUS_IS_OK(status)) {
2228                         DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2229                                 nt_errstr(status)));
2230                         return status;
2231                 }
2232         }
2233
2234         *_dce_ctx = dce_ctx;
2235         return NT_STATUS_OK;
2236 }
2237
2238 /* the list of currently registered DCERPC endpoint servers.
2239  */
2240 static struct ep_server {
2241         struct dcesrv_endpoint_server *ep_server;
2242 } *ep_servers = NULL;
2243 static int num_ep_servers;
2244
2245 /*
2246   register a DCERPC endpoint server. 
2247
2248   The 'name' can be later used by other backends to find the operations
2249   structure for this backend.  
2250
2251 */
2252 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2253 {
2254         
2255         if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2256                 /* its already registered! */
2257                 DEBUG(0,("DCERPC endpoint server '%s' already registered\n", 
2258                          ep_server->name));
2259                 return NT_STATUS_OBJECT_NAME_COLLISION;
2260         }
2261
2262         ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2263         if (!ep_servers) {
2264                 smb_panic("out of memory in dcerpc_register");
2265         }
2266
2267         ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2268         ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2269
2270         num_ep_servers++;
2271
2272         DEBUG(3,("DCERPC endpoint server '%s' registered\n", 
2273                  ep_server->name));
2274
2275         return NT_STATUS_OK;
2276 }
2277
2278 /*
2279   return the operations structure for a named backend of the specified type
2280 */
2281 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2282 {
2283         int i;
2284
2285         for (i=0;i<num_ep_servers;i++) {
2286                 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2287                         return ep_servers[i].ep_server;
2288                 }
2289         }
2290
2291         return NULL;
2292 }
2293
2294 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2295 {
2296         static bool initialized;
2297 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2298         STATIC_dcerpc_server_MODULES_PROTO;
2299         init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2300         init_module_fn *shared_init;
2301
2302         if (initialized) {
2303                 return;
2304         }
2305         initialized = true;
2306
2307         shared_init = load_samba_modules(NULL, "dcerpc_server");
2308
2309         run_init_functions(NULL, static_init);
2310         run_init_functions(NULL, shared_init);
2311
2312         talloc_free(shared_init);
2313 }
2314
2315 /*
2316   return the DCERPC module version, and the size of some critical types
2317   This can be used by endpoint server modules to either detect compilation errors, or provide
2318   multiple implementations for different smbd compilation options in one module
2319 */
2320 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2321 {
2322         static const struct dcesrv_critical_sizes critical_sizes = {
2323                 DCERPC_MODULE_VERSION,
2324                 sizeof(struct dcesrv_context),
2325                 sizeof(struct dcesrv_endpoint),
2326                 sizeof(struct dcesrv_endpoint_server),
2327                 sizeof(struct dcesrv_interface),
2328                 sizeof(struct dcesrv_if_list),
2329                 sizeof(struct dcesrv_connection),
2330                 sizeof(struct dcesrv_call_state),
2331                 sizeof(struct dcesrv_auth),
2332                 sizeof(struct dcesrv_handle)
2333         };
2334
2335         return &critical_sizes;
2336 }
2337
2338 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2339 {
2340         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2341         struct stream_connection *srv_conn;
2342         srv_conn = talloc_get_type(dce_conn->transport.private_data,
2343                                    struct stream_connection);
2344
2345         dce_conn->wait_send = NULL;
2346         dce_conn->wait_recv = NULL;
2347         dce_conn->wait_private = NULL;
2348
2349         dce_conn->allow_bind = false;
2350         dce_conn->allow_auth3 = false;
2351         dce_conn->allow_alter = false;
2352         dce_conn->allow_request = false;
2353
2354         if (dce_conn->pending_call_list == NULL) {
2355                 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2356
2357                 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2358                 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2359                 return;
2360         }
2361
2362         if (dce_conn->terminate != NULL) {
2363                 return;
2364         }
2365
2366         DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2367                  reason));
2368         dce_conn->terminate = talloc_strdup(dce_conn, reason);
2369         if (dce_conn->terminate == NULL) {
2370                 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2371         }
2372         DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2373 }
2374
2375 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2376 {
2377         struct dcesrv_connection *cur, *next;
2378
2379         next = dce_ctx->broken_connections;
2380         while (next != NULL) {
2381                 cur = next;
2382                 next = cur->next;
2383
2384                 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2385                         struct dcesrv_connection_context *context_cur, *context_next;
2386
2387                         context_next = cur->contexts;
2388                         while (context_next != NULL) {
2389                                 context_cur = context_next;
2390                                 context_next = context_cur->next;
2391
2392                                 dcesrv_connection_context_destructor(context_cur);
2393                         }
2394                 }
2395
2396                 dcesrv_terminate_connection(cur, cur->terminate);
2397         }
2398 }
2399
2400 /* We need this include to be able to compile on some plateforms
2401  * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2402  * correctly.
2403  * It has to be that deep because otherwise we have a conflict on
2404  * const struct dcesrv_interface declaration.
2405  * This is mostly due to socket_wrapper defining #define bind swrap_bind
2406  * which conflict with the bind used before.
2407  */
2408 #include "system/network.h"
2409
2410 struct dcesrv_sock_reply_state {
2411         struct dcesrv_connection *dce_conn;
2412         struct dcesrv_call_state *call;
2413         struct iovec iov;
2414 };
2415
2416 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2417 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2418
2419 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2420 {
2421         struct dcesrv_call_state *call;
2422
2423         call = dce_conn->call_list;
2424         if (!call || !call->replies) {
2425                 return;
2426         }
2427
2428         while (call->replies) {
2429                 struct data_blob_list_item *rep = call->replies;
2430                 struct dcesrv_sock_reply_state *substate;
2431                 struct tevent_req *subreq;
2432
2433                 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2434                 if (!substate) {
2435                         dcesrv_terminate_connection(dce_conn, "no memory");
2436                         return;
2437                 }
2438
2439                 substate->dce_conn = dce_conn;
2440                 substate->call = NULL;
2441
2442                 DLIST_REMOVE(call->replies, rep);
2443
2444                 if (call->replies == NULL && call->terminate_reason == NULL) {
2445                         substate->call = call;
2446                 }
2447
2448                 substate->iov.iov_base = (void *) rep->blob.data;
2449                 substate->iov.iov_len = rep->blob.length;
2450
2451                 subreq = tstream_writev_queue_send(substate,
2452                                                    dce_conn->event_ctx,
2453                                                    dce_conn->stream,
2454                                                    dce_conn->send_queue,
2455                                                    &substate->iov, 1);
2456                 if (!subreq) {
2457                         dcesrv_terminate_connection(dce_conn, "no memory");
2458                         return;
2459                 }
2460                 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2461                                         substate);
2462         }
2463
2464         if (call->terminate_reason != NULL) {
2465                 struct tevent_req *subreq;
2466
2467                 subreq = tevent_queue_wait_send(call,
2468                                                 dce_conn->event_ctx,
2469                                                 dce_conn->send_queue);
2470                 if (!subreq) {
2471                         dcesrv_terminate_connection(dce_conn, __location__);
2472                         return;
2473                 }
2474                 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2475                                         call);
2476         }
2477
2478         DLIST_REMOVE(call->conn->call_list, call);
2479         call->list = DCESRV_LIST_NONE;
2480 }
2481
2482 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2483 {
2484         struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2485                                                 struct dcesrv_sock_reply_state);
2486         int ret;
2487         int sys_errno;
2488         NTSTATUS status;
2489         struct dcesrv_call_state *call = substate->call;
2490
2491         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2492         TALLOC_FREE(subreq);
2493         if (ret == -1) {
2494                 status = map_nt_error_from_unix_common(sys_errno);
2495                 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2496                 return;
2497         }
2498
2499         talloc_free(substate);
2500         if (call) {
2501                 talloc_free(call);
2502         }
2503 }
2504
2505 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2506
2507 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2508 {
2509         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2510                                                 struct dcesrv_call_state);
2511         bool ok;
2512         struct timeval tv;
2513
2514         /* make sure we stop send queue before removing subreq */
2515         tevent_queue_stop(call->conn->send_queue);
2516
2517         ok = tevent_queue_wait_recv(subreq);
2518         TALLOC_FREE(subreq);
2519         if (!ok) {
2520                 dcesrv_terminate_connection(call->conn, __location__);
2521                 return;
2522         }
2523
2524         /* disconnect after 200 usecs */
2525         tv = timeval_current_ofs_usec(200);
2526         subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2527         if (subreq == NULL) {
2528                 dcesrv_terminate_connection(call->conn, __location__);
2529                 return;
2530         }
2531         tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2532                                 call);
2533 }
2534
2535 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2536 {
2537         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2538                                                 struct dcesrv_call_state);
2539         bool ok;
2540
2541         ok = tevent_wakeup_recv(subreq);
2542         TALLOC_FREE(subreq);
2543         if (!ok) {
2544                 dcesrv_terminate_connection(call->conn, __location__);
2545                 return;
2546         }
2547
2548         dcesrv_terminate_connection(call->conn, call->terminate_reason);
2549 }
2550
2551 struct dcesrv_socket_context {
2552         const struct dcesrv_endpoint *endpoint;
2553         struct dcesrv_context *dcesrv_ctx;
2554 };
2555
2556
2557 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2558
2559 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2560 {
2561         NTSTATUS status;
2562         struct dcesrv_socket_context *dcesrv_sock = 
2563                 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2564         enum dcerpc_transport_t transport =
2565                 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2566         struct dcesrv_connection *dcesrv_conn = NULL;
2567         int ret;
2568         struct tevent_req *subreq;
2569         struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2570
2571         dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2572
2573         if (!srv_conn->session_info) {
2574                 status = auth_anonymous_session_info(srv_conn,
2575                                                      lp_ctx,
2576                                                      &srv_conn->session_info);
2577                 if (!NT_STATUS_IS_OK(status)) {
2578                         DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2579                                 nt_errstr(status)));
2580                         stream_terminate_connection(srv_conn, nt_errstr(status));
2581                         return;
2582                 }
2583         }
2584
2585         /*
2586          * This fills in dcesrv_conn->endpoint with the endpoint
2587          * associated with the socket.  From this point on we know
2588          * which (group of) services we are handling, but not the
2589          * specific interface.
2590          */
2591
2592         status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2593                                          srv_conn,
2594                                          dcesrv_sock->endpoint,
2595                                          srv_conn->session_info,
2596                                          srv_conn->event.ctx,
2597                                          srv_conn->msg_ctx,
2598                                          srv_conn->server_id,
2599                                          DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2600                                          &dcesrv_conn);
2601         if (!NT_STATUS_IS_OK(status)) {
2602                 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
2603                         nt_errstr(status)));
2604                 stream_terminate_connection(srv_conn, nt_errstr(status));
2605                 return;
2606         }
2607
2608         dcesrv_conn->transport.private_data             = srv_conn;
2609         dcesrv_conn->transport.report_output_data       = dcesrv_sock_report_output_data;
2610
2611         TALLOC_FREE(srv_conn->event.fde);
2612
2613         dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2614         if (!dcesrv_conn->send_queue) {
2615                 status = NT_STATUS_NO_MEMORY;
2616                 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2617                         nt_errstr(status)));
2618                 stream_terminate_connection(srv_conn, nt_errstr(status));
2619                 return;
2620         }
2621
2622         if (transport == NCACN_NP) {
2623                 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2624                 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2625                                                   &srv_conn->tstream);
2626         } else {
2627                 ret = tstream_bsd_existing_socket(dcesrv_conn,
2628                                                   socket_get_fd(srv_conn->socket),
2629                                                   &dcesrv_conn->stream);
2630                 if (ret == -1) {
2631                         status = map_nt_error_from_unix_common(errno);
2632                         DEBUG(0, ("dcesrv_sock_accept: "
2633                                   "failed to setup tstream: %s\n",
2634                                   nt_errstr(status)));
2635                         stream_terminate_connection(srv_conn, nt_errstr(status));
2636                         return;
2637                 }
2638                 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2639         }
2640
2641         dcesrv_conn->local_address = srv_conn->local_address;
2642         dcesrv_conn->remote_address = srv_conn->remote_address;
2643
2644         if (transport == NCALRPC) {
2645                 uid_t uid;
2646                 gid_t gid;
2647                 int sock_fd;
2648
2649                 sock_fd = socket_get_fd(srv_conn->socket);
2650                 if (sock_fd == -1) {
2651                         stream_terminate_connection(
2652                                 srv_conn, "socket_get_fd failed\n");
2653                         return;
2654                 }
2655
2656                 ret = getpeereid(sock_fd, &uid, &gid);
2657                 if (ret == -1) {
2658                         status = map_nt_error_from_unix_common(errno);
2659                         DEBUG(0, ("dcesrv_sock_accept: "
2660                                   "getpeereid() failed for NCALRPC: %s\n",
2661                                   nt_errstr(status)));
2662                         stream_terminate_connection(srv_conn, nt_errstr(status));
2663                         return;
2664                 }
2665                 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2666                         struct tsocket_address *r = NULL;
2667
2668                         ret = tsocket_address_unix_from_path(dcesrv_conn,
2669                                                              "/root/ncalrpc_as_system",
2670                                                              &r);
2671                         if (ret == -1) {
2672                                 status = map_nt_error_from_unix_common(errno);
2673                                 DEBUG(0, ("dcesrv_sock_accept: "
2674                                           "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2675                                           nt_errstr(status)));
2676                                 stream_terminate_connection(srv_conn, nt_errstr(status));
2677                                 return;
2678                         }
2679                         dcesrv_conn->remote_address = r;
2680                 }
2681         }
2682
2683         srv_conn->private_data = dcesrv_conn;
2684
2685         irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2686
2687         subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2688                                                dcesrv_conn->event_ctx,
2689                                                dcesrv_conn->stream);
2690         if (!subreq) {
2691                 status = NT_STATUS_NO_MEMORY;
2692                 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2693                         nt_errstr(status)));
2694                 stream_terminate_connection(srv_conn, nt_errstr(status));
2695                 return;
2696         }
2697         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2698
2699         return;
2700 }
2701
2702 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2703
2704 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2705 {
2706         struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2707                                              struct dcesrv_connection);
2708         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2709         struct ncacn_packet *pkt;
2710         DATA_BLOB buffer;
2711         NTSTATUS status;
2712
2713         if (dce_conn->terminate) {
2714                 /*
2715                  * if the current connection is broken
2716                  * we need to clean it up before any other connection
2717                  */
2718                 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2719                 dcesrv_cleanup_broken_connections(dce_ctx);
2720                 return;
2721         }
2722
2723         dcesrv_cleanup_broken_connections(dce_ctx);
2724
2725         status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2726                                                &pkt, &buffer);
2727         TALLOC_FREE(subreq);
2728         if (!NT_STATUS_IS_OK(status)) {
2729                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2730                 return;
2731         }
2732
2733         status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2734         if (!NT_STATUS_IS_OK(status)) {
2735                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2736                 return;
2737         }
2738
2739         /*
2740          * This is used to block the connection during
2741          * pending authentication.
2742          */
2743         if (dce_conn->wait_send != NULL) {
2744                 subreq = dce_conn->wait_send(dce_conn,
2745                                              dce_conn->event_ctx,
2746                                              dce_conn->wait_private);
2747                 if (!subreq) {
2748                         status = NT_STATUS_NO_MEMORY;
2749                         dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2750                         return;
2751                 }
2752                 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2753                 return;
2754         }
2755
2756         subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2757                                                dce_conn->event_ctx,
2758                                                dce_conn->stream);
2759         if (!subreq) {
2760                 status = NT_STATUS_NO_MEMORY;
2761                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2762                 return;
2763         }
2764         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2765 }
2766
2767 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2768 {
2769         struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2770                                              struct dcesrv_connection);
2771         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2772         NTSTATUS status;
2773
2774         if (dce_conn->terminate) {
2775                 /*
2776                  * if the current connection is broken
2777                  * we need to clean it up before any other connection
2778                  */
2779                 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2780                 dcesrv_cleanup_broken_connections(dce_ctx);
2781                 return;
2782         }
2783
2784         dcesrv_cleanup_broken_connections(dce_ctx);
2785
2786         status = dce_conn->wait_recv(subreq);
2787         dce_conn->wait_send = NULL;
2788         dce_conn->wait_recv = NULL;
2789         dce_conn->wait_private = NULL;
2790         TALLOC_FREE(subreq);
2791         if (!NT_STATUS_IS_OK(status)) {
2792                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2793                 return;
2794         }
2795
2796         subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2797                                                dce_conn->event_ctx,
2798                                                dce_conn->stream);
2799         if (!subreq) {
2800                 status = NT_STATUS_NO_MEMORY;
2801                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2802                 return;
2803         }
2804         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2805 }
2806
2807 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2808 {
2809         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2810                                              struct dcesrv_connection);
2811         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2812 }
2813
2814 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2815 {
2816         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2817                                              struct dcesrv_connection);
2818         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2819 }
2820
2821
2822 static const struct stream_server_ops dcesrv_stream_ops = {
2823         .name                   = "rpc",
2824         .accept_connection      = dcesrv_sock_accept,
2825         .recv_handler           = dcesrv_sock_recv,
2826         .send_handler           = dcesrv_sock_send,
2827 };
2828
2829 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 
2830                                    struct loadparm_context *lp_ctx,
2831                                    struct dcesrv_endpoint *e,
2832                             struct tevent_context *event_ctx, const struct model_ops *model_ops)
2833 {
2834         struct dcesrv_socket_context *dcesrv_sock;
2835         uint16_t port = 1;
2836         NTSTATUS status;
2837         const char *endpoint;
2838
2839         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2840         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2841
2842         /* remember the endpoint of this socket */
2843         dcesrv_sock->endpoint           = e;
2844         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2845
2846         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2847
2848         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2849                                      model_ops, &dcesrv_stream_ops, 
2850                                      "unix", endpoint, &port,
2851                                      lpcfg_socket_options(lp_ctx),
2852                                      dcesrv_sock);
2853         if (!NT_STATUS_IS_OK(status)) {
2854                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2855                          endpoint, nt_errstr(status)));
2856         }
2857
2858         return status;
2859 }
2860
2861 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 
2862                                       struct loadparm_context *lp_ctx,
2863                                       struct dcesrv_endpoint *e,
2864                                       struct tevent_context *event_ctx, const struct model_ops *model_ops)
2865 {
2866         struct dcesrv_socket_context *dcesrv_sock;
2867         uint16_t port = 1;
2868         char *full_path;
2869         NTSTATUS status;
2870         const char *endpoint;
2871
2872         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2873
2874         if (endpoint == NULL) {
2875                 /*
2876                  * No identifier specified: use DEFAULT.
2877                  *
2878                  * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2879                  * no endpoint and let the epmapper worry about it.
2880                  */
2881                 endpoint = "DEFAULT";
2882                 status = dcerpc_binding_set_string_option(e->ep_description,
2883                                                           "endpoint",
2884                                                           endpoint);
2885                 if (!NT_STATUS_IS_OK(status)) {
2886                         DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2887                                   nt_errstr(status)));
2888                         return status;
2889                 }
2890         }
2891
2892         full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2893                                     endpoint);
2894
2895         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2896         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2897
2898         /* remember the endpoint of this socket */
2899         dcesrv_sock->endpoint           = e;
2900         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2901
2902         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2903                                      model_ops, &dcesrv_stream_ops, 
2904                                      "unix", full_path, &port, 
2905                                      lpcfg_socket_options(lp_ctx),
2906                                      dcesrv_sock);
2907         if (!NT_STATUS_IS_OK(status)) {
2908                 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2909                          endpoint, full_path, nt_errstr(status)));
2910         }
2911         return status;
2912 }
2913
2914 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2915                                  struct loadparm_context *lp_ctx,
2916                                  struct dcesrv_endpoint *e,
2917                                  struct tevent_context *event_ctx, const struct model_ops *model_ops)
2918 {
2919         struct dcesrv_socket_context *dcesrv_sock;
2920         NTSTATUS status;
2921         const char *endpoint;
2922
2923         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2924         if (endpoint == NULL) {
2925                 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2926                 return NT_STATUS_INVALID_PARAMETER;
2927         }
2928
2929         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2930         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2931
2932         /* remember the endpoint of this socket */
2933         dcesrv_sock->endpoint           = e;
2934         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2935
2936         status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2937                                           model_ops, &dcesrv_stream_ops,
2938                                           endpoint,
2939                                           dcesrv_sock);
2940         if (!NT_STATUS_IS_OK(status)) {
2941                 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2942                          endpoint, nt_errstr(status)));
2943                 return status;
2944         }
2945
2946         return NT_STATUS_OK;
2947 }
2948
2949 /*
2950   add a socket address to the list of events, one event per dcerpc endpoint
2951 */
2952 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2953                                          struct tevent_context *event_ctx, const struct model_ops *model_ops,
2954                                          const char *address)
2955 {
2956         struct dcesrv_socket_context *dcesrv_sock;
2957         uint16_t port = 0;
2958         NTSTATUS status;
2959         const char *endpoint;
2960         char port_str[6];
2961
2962         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2963         if (endpoint != NULL) {
2964                 port = atoi(endpoint);
2965         }
2966
2967         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2968         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2969
2970         /* remember the endpoint of this socket */
2971         dcesrv_sock->endpoint           = e;
2972         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2973
2974         status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2975                                      model_ops, &dcesrv_stream_ops, 
2976                                      "ip", address, &port,
2977                                      lpcfg_socket_options(dce_ctx->lp_ctx),
2978                                      dcesrv_sock);
2979         if (!NT_STATUS_IS_OK(status)) {
2980                 struct dcesrv_if_list *iface;
2981                 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
2982                          address, port));
2983                 for (iface = e->interface_list; iface; iface = iface->next) {
2984                         DEBUGADD(0, ("%s ", iface->iface.name));
2985                 }
2986                 DEBUGADD(0, ("failed - %s",
2987                              nt_errstr(status)));
2988                 return status;
2989         }
2990
2991         snprintf(port_str, sizeof(port_str), "%u", port);
2992
2993         status = dcerpc_binding_set_string_option(e->ep_description,
2994                                                   "endpoint", port_str);
2995         if (!NT_STATUS_IS_OK(status)) {
2996                 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2997                          port_str, nt_errstr(status)));
2998                 return status;
2999         } else {
3000                 struct dcesrv_if_list *iface;
3001                 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3002                          address, port_str));
3003                 for (iface = e->interface_list; iface; iface = iface->next) {
3004                         DEBUGADD(4, ("%s ", iface->iface.name));
3005                 }
3006                 DEBUGADD(4, ("\n"));
3007         }
3008
3009         return NT_STATUS_OK;
3010 }
3011
3012 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3013
3014 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 
3015                                   struct loadparm_context *lp_ctx,
3016                                   struct dcesrv_endpoint *e,
3017                                   struct tevent_context *event_ctx, const struct model_ops *model_ops)
3018 {
3019         NTSTATUS status;
3020
3021         /* Add TCP/IP sockets */
3022         if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3023                 int num_interfaces;
3024                 int i;
3025                 struct interface *ifaces;
3026
3027                 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3028
3029                 num_interfaces = iface_list_count(ifaces);
3030                 for(i = 0; i < num_interfaces; i++) {
3031                         const char *address = iface_list_n_ip(ifaces, i);
3032                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
3033                         NT_STATUS_NOT_OK_RETURN(status);
3034                 }
3035         } else {
3036                 char **wcard;
3037                 int i;
3038                 int num_binds = 0;
3039                 wcard = iface_list_wildcard(dce_ctx);
3040                 NT_STATUS_HAVE_NO_MEMORY(wcard);
3041                 for (i=0; wcard[i]; i++) {
3042                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
3043                         if (NT_STATUS_IS_OK(status)) {
3044                                 num_binds++;
3045                         }
3046                 }
3047                 talloc_free(wcard);
3048                 if (num_binds == 0) {
3049                         return NT_STATUS_INVALID_PARAMETER_MIX;
3050                 }
3051         }
3052
3053         return NT_STATUS_OK;
3054 }
3055
3056 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3057                        struct loadparm_context *lp_ctx,
3058                        struct dcesrv_endpoint *e,
3059                        struct tevent_context *event_ctx,
3060                        const struct model_ops *model_ops)
3061 {
3062         enum dcerpc_transport_t transport =
3063                 dcerpc_binding_get_transport(e->ep_description);
3064
3065         switch (transport) {
3066         case NCACN_UNIX_STREAM:
3067                 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3068
3069         case NCALRPC:
3070                 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3071
3072         case NCACN_IP_TCP:
3073                 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3074
3075         case NCACN_NP:
3076                 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3077
3078         default:
3079                 return NT_STATUS_NOT_SUPPORTED;
3080         }
3081 }
3082
3083
3084 /**
3085  * retrieve credentials from a dce_call
3086  */
3087 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3088 {
3089         return dce_call->conn->auth_state.session_info->credentials;
3090 }
3091
3092 /**
3093  * returns true if this is an authenticated call
3094  */
3095 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3096 {
3097         enum security_user_level level;
3098         level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
3099         return level >= SECURITY_USER;
3100 }
3101
3102 /**
3103  * retrieve account_name for a dce_call
3104  */
3105 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3106 {
3107         return dce_call->context->conn->auth_state.session_info->info->account_name;
3108 }