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