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