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