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