s4:rpc_server: make use of dcesrv_call_state->auth_state in dcerpc_server.c
[samba.git] / source4 / rpc_server / dcerpc_server.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    server side dcerpc core code
5
6    Copyright (C) Andrew Tridgell 2003-2005
7    Copyright (C) Stefan (metze) Metzmacher 2004-2005
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "../lib/util/dlinklist.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/dcerpc_server_proto.h"
29 #include "rpc_server/common/proto.h"
30 #include "librpc/rpc/dcerpc_proto.h"
31 #include "system/filesys.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "../lib/tsocket/tsocket.h"
35 #include "../libcli/named_pipe_auth/npa_tstream.h"
36 #include "smbd/service_stream.h"
37 #include "../lib/tsocket/tsocket.h"
38 #include "lib/socket/socket.h"
39 #include "smbd/process_model.h"
40 #include "lib/messaging/irpc.h"
41 #include "librpc/rpc/rpc_common.h"
42 #include "lib/util/samba_modules.h"
43 #include "librpc/gen_ndr/ndr_dcerpc.h"
44 #include "../lib/util/tevent_ntstatus.h"
45
46 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
47                                 const struct dcerpc_bind *b,
48                                 struct dcerpc_ack_ctx *ack_ctx_list);
49
50 /*
51   find an association group given a assoc_group_id
52  */
53 static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context *dce_ctx,
54                                                           uint32_t id)
55 {
56         void *id_ptr;
57
58         id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
59         if (id_ptr == NULL) {
60                 return NULL;
61         }
62         return talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
63 }
64
65 /*
66   take a reference to an existing association group
67  */
68 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
69                                                                struct dcesrv_context *dce_ctx,
70                                                                uint32_t id)
71 {
72         struct dcesrv_assoc_group *assoc_group;
73
74         assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
75         if (assoc_group == NULL) {
76                 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
77                 return NULL;
78         }
79         return talloc_reference(mem_ctx, assoc_group);
80 }
81
82 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
83 {
84         int ret;
85         ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
86         if (ret != 0) {
87                 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
88                          assoc_group->id));
89         }
90         return 0;
91 }
92
93 /*
94   allocate a new association group
95  */
96 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
97                                                          struct dcesrv_context *dce_ctx)
98 {
99         struct dcesrv_assoc_group *assoc_group;
100         int id;
101
102         assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
103         if (assoc_group == NULL) {
104                 return NULL;
105         }
106         
107         id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
108         if (id == -1) {
109                 talloc_free(assoc_group);
110                 DEBUG(0,(__location__ ": Out of association groups!\n"));
111                 return NULL;
112         }
113
114         assoc_group->id = id;
115         assoc_group->dce_ctx = dce_ctx;
116
117         talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
118
119         return assoc_group;
120 }
121
122
123 /*
124   see if two endpoints match
125 */
126 static bool endpoints_match(const struct dcerpc_binding *ep1,
127                             const struct dcerpc_binding *ep2)
128 {
129         enum dcerpc_transport_t t1;
130         enum dcerpc_transport_t t2;
131         const char *e1;
132         const char *e2;
133
134         t1 = dcerpc_binding_get_transport(ep1);
135         t2 = dcerpc_binding_get_transport(ep2);
136
137         e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
138         e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
139
140         if (t1 != t2) {
141                 return false;
142         }
143
144         if (!e1 || !e2) {
145                 return e1 == e2;
146         }
147
148         if (strcasecmp(e1, e2) != 0) {
149                 return false;
150         }
151
152         return true;
153 }
154
155 /*
156   find an endpoint in the dcesrv_context
157 */
158 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
159                                              const struct dcerpc_binding *ep_description)
160 {
161         struct dcesrv_endpoint *ep;
162         for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
163                 if (endpoints_match(ep->ep_description, ep_description)) {
164                         return ep;
165                 }
166         }
167         return NULL;
168 }
169
170 /*
171   find a registered context_id from a bind or alter_context
172 */
173 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn, 
174                                                              uint16_t context_id)
175 {
176         struct dcesrv_connection_context *c;
177         for (c=conn->contexts;c;c=c->next) {
178                 if (c->context_id == context_id) return c;
179         }
180         return NULL;
181 }
182
183 /*
184   see if a uuid and if_version match to an interface
185 */
186 static bool interface_match(const struct dcesrv_interface *if1,
187                                                         const struct dcesrv_interface *if2)
188 {
189         return (if1->syntax_id.if_version == if2->syntax_id.if_version && 
190                         GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
191 }
192
193 /*
194   find the interface operations on any endpoint with this binding
195 */
196 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
197                                                                 struct dcerpc_binding *binding,
198                                                                 const struct dcesrv_interface *iface)
199 {
200         struct dcesrv_endpoint *ep;
201         for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
202                 if (endpoints_match(ep->ep_description, binding)) {
203                         struct dcesrv_if_list *ifl;
204                         for (ifl=ep->interface_list; ifl; ifl=ifl->next) {
205                                 if (interface_match(&(ifl->iface), iface)) {
206                                         return &(ifl->iface);
207                                 }
208                         }
209                 }
210         }
211         return NULL;
212 }
213
214 /*
215   see if a uuid and if_version match to an interface
216 */
217 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
218                                     const struct GUID *uuid, uint32_t if_version)
219 {
220         return (iface->syntax_id.if_version == if_version && 
221                         GUID_equal(&iface->syntax_id.uuid, uuid));
222 }
223
224 /*
225   find the interface operations on an endpoint by uuid
226 */
227 const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
228                                                       const struct GUID *uuid, uint32_t if_version)
229 {
230         struct dcesrv_if_list *ifl;
231         for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
232                 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
233                         return &(ifl->iface);
234                 }
235         }
236         return NULL;
237 }
238
239 /*
240   find the earlier parts of a fragmented call awaiting reassembily
241 */
242 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint32_t call_id)
243 {
244         struct dcesrv_call_state *c;
245         for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
246                 if (c->pkt.call_id == call_id) {
247                         return c;
248                 }
249         }
250         return NULL;
251 }
252
253 /*
254   register an interface on an endpoint
255
256   An endpoint is one unix domain socket (for ncalrpc), one TCP port
257   (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
258
259   Each endpoint can have many interfaces such as netlogon, lsa or
260   samr.  Some have essentially the full set.
261
262   This is driven from the set of interfaces listed in each IDL file
263   via the PIDL generated *__op_init_server() functions.
264 */
265 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
266                                    const char *ep_name,
267                                    const struct dcesrv_interface *iface,
268                                    const struct security_descriptor *sd)
269 {
270         struct dcesrv_endpoint *ep;
271         struct dcesrv_if_list *ifl;
272         struct dcerpc_binding *binding;
273         bool add_ep = false;
274         NTSTATUS status;
275         enum dcerpc_transport_t transport;
276         char *ep_string = NULL;
277         bool use_single_process = true;
278         const char *ep_process_string;
279
280         /*
281          * If we are not using handles, there is no need for force
282          * this service into using a single process.
283          *
284          * However, due to the way we listen for RPC packets, we can
285          * only do this if we have a single service per pipe or TCP
286          * port, so we still force a single combined process for
287          * ncalrpc.
288          */
289         if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
290                 use_single_process = false;
291         }
292
293         status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
294
295         if (NT_STATUS_IS_ERR(status)) {
296                 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
297                 return status;
298         }
299
300         transport = dcerpc_binding_get_transport(binding);
301         if (transport == NCACN_IP_TCP) {
302                 int port;
303                 char port_str[6];
304
305                 /* 
306                  * First check if there is already a port specified, eg
307                  * for epmapper on ncacn_ip_tcp:[135]
308                  */
309                 const char *endpoint
310                         = dcerpc_binding_get_string_option(binding,
311                                                            "endpoint");
312                 if (endpoint == NULL) {
313                         port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
314                                               "rpc server port", iface->name, 0);
315                         
316                         /*
317                          * For RPC services that are not set to use a single
318                          * process, we do not default to using the 'rpc server
319                          * port' because that would cause a double-bind on
320                          * that port.
321                          */
322                         if (port == 0 && !use_single_process) {
323                                 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
324                         }
325                         if (port != 0) {
326                                 snprintf(port_str, sizeof(port_str), "%u", port);
327                                 status = dcerpc_binding_set_string_option(binding,
328                                                                           "endpoint",
329                                                                           port_str);
330                                 if (!NT_STATUS_IS_OK(status)) {
331                                         return status;
332                                 }
333                         }
334                 }
335         }
336
337         /* see if the interface is already registered on the endpoint */
338         if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
339                 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
340                          iface->name, ep_name));
341                 return NT_STATUS_OBJECT_NAME_COLLISION;
342         }
343
344         /* check if this endpoint exists
345          */
346         ep = find_endpoint(dce_ctx, binding);
347
348         if (ep != NULL) {
349                 /*
350                  * We want a new port on ncacn_ip_tcp for NETLOGON, so
351                  * it can be multi-process.  Other processes can also
352                  * listen on distinct ports, if they have one forced
353                  * in the code above with eg 'rpc server port:drsuapi = 1027'
354                  *
355                  * If we have mulitiple endpoints on port 0, they each
356                  * get an epemeral port (currently by walking up from
357                  * 1024).
358                  *
359                  * Because one endpoint can only have one process
360                  * model, we add a new IP_TCP endpoint for each model.
361                  *
362                  * This works in conjunction with the forced overwrite
363                  * of ep->use_single_process below.
364                  */
365                 if (ep->use_single_process != use_single_process
366                     && transport == NCACN_IP_TCP) {
367                         add_ep = true;
368                 }
369         }
370
371         if (ep == NULL || add_ep) {
372                 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
373                 if (!ep) {
374                         return NT_STATUS_NO_MEMORY;
375                 }
376                 ZERO_STRUCTP(ep);
377                 ep->ep_description = talloc_move(ep, &binding);
378                 add_ep = true;
379
380                 /* add mgmt interface */
381                 ifl = talloc_zero(ep, struct dcesrv_if_list);
382                 if (!ifl) {
383                         return NT_STATUS_NO_MEMORY;
384                 }
385
386                 ifl->iface = dcesrv_get_mgmt_interface();
387
388                 DLIST_ADD(ep->interface_list, ifl);
389         }
390
391         /*
392          * By default don't force into a single process, but if any
393          * interface on this endpoint on this service uses handles
394          * (most do), then we must force into single process mode
395          *
396          * By overwriting this each time a new interface is added to
397          * this endpoint, we end up with the most restrictive setting.
398          */
399         if (use_single_process) {
400                 ep->use_single_process = true;
401         }
402
403         /* talloc a new interface list element */
404         ifl = talloc_zero(ep, struct dcesrv_if_list);
405         if (!ifl) {
406                 return NT_STATUS_NO_MEMORY;
407         }
408
409         /* copy the given interface struct to the one on the endpoints interface list */
410         memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
411
412         /* if we have a security descriptor given,
413          * we should see if we can set it up on the endpoint
414          */
415         if (sd != NULL) {
416                 /* if there's currently no security descriptor given on the endpoint
417                  * we try to set it
418                  */
419                 if (ep->sd == NULL) {
420                         ep->sd = security_descriptor_copy(ep, sd);
421                 }
422
423                 /* if now there's no security descriptor given on the endpoint
424                  * something goes wrong, either we failed to copy the security descriptor
425                  * or there was already one on the endpoint
426                  */
427                 if (ep->sd != NULL) {
428                         DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
429                                  "                           on endpoint '%s'\n",
430                                 iface->name, ep_name));
431                         if (add_ep) free(ep);
432                         free(ifl);
433                         return NT_STATUS_OBJECT_NAME_COLLISION;
434                 }
435         }
436
437         /* finally add the interface on the endpoint */
438         DLIST_ADD(ep->interface_list, ifl);
439
440         /* if it's a new endpoint add it to the dcesrv_context */
441         if (add_ep) {
442                 DLIST_ADD(dce_ctx->endpoint_list, ep);
443         }
444
445         /* Re-get the string as we may have set a port */
446         ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
447
448         if (use_single_process) {
449                 ep_process_string = "single process required";
450         } else {
451                 ep_process_string = "multi process compatible";
452         }
453
454         DBG_INFO("dcesrv_interface_register: interface '%s' "
455                  "registered on endpoint '%s' (%s)\n",
456                  iface->name, ep_string, ep_process_string);
457         TALLOC_FREE(ep_string);
458
459         return NT_STATUS_OK;
460 }
461
462 static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth,
463                                                 DATA_BLOB *session_key)
464 {
465         if (auth->session_info == NULL) {
466                 return NT_STATUS_NO_USER_SESSION_KEY;
467         }
468
469         if (auth->session_info->session_key.length == 0) {
470                 return NT_STATUS_NO_USER_SESSION_KEY;
471         }
472
473         *session_key = auth->session_info->session_key;
474         return NT_STATUS_OK;
475 }
476
477 static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth,
478                                           DATA_BLOB *session_key)
479 {
480         if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
481                 return NT_STATUS_NO_USER_SESSION_KEY;
482         }
483
484         return dcesrv_session_info_session_key(auth, session_key);
485 }
486
487 static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
488                                                DATA_BLOB *session_key)
489 {
490         return dcerpc_generic_session_key(NULL, session_key);
491 }
492
493 /*
494  * Fetch the authentication session key if available.
495  *
496  * This is the key generated by a gensec authentication.
497  *
498  */
499 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
500                                           DATA_BLOB *session_key)
501 {
502         struct dcesrv_auth *auth = call->auth_state;
503
504         return dcesrv_session_info_session_key(auth, session_key);
505 }
506
507 /*
508  * Fetch the transport session key if available.
509  * Typically this is the SMB session key
510  * or a fixed key for local transports.
511  *
512  * The key is always truncated to 16 bytes.
513 */
514 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
515                                                DATA_BLOB *session_key)
516 {
517         struct dcesrv_auth *auth = call->auth_state;
518         NTSTATUS status;
519
520         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->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->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->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->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->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->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         call->auth_state = &dce_conn->auth_state;
2004
2005         talloc_set_destructor(call, dcesrv_call_dequeue);
2006
2007         if (call->conn->allow_bind) {
2008                 /*
2009                  * Only one bind is possible per connection
2010                  */
2011                 call->conn->allow_bind = false;
2012                 return dcesrv_bind(call);
2013         }
2014
2015         /* we have to check the signing here, before combining the
2016            pdus */
2017         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2018                 if (!call->conn->allow_request) {
2019                         return dcesrv_fault_disconnect(call,
2020                                         DCERPC_NCA_S_PROTO_ERROR);
2021                 }
2022
2023                 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2024                                 DCERPC_PKT_REQUEST,
2025                                 call->pkt.u.request.stub_and_verifier.length,
2026                                 0, /* required_flags */
2027                                 DCERPC_PFC_FLAG_FIRST |
2028                                 DCERPC_PFC_FLAG_LAST |
2029                                 DCERPC_PFC_FLAG_PENDING_CANCEL |
2030                                 0x08 | /* this is not defined, but should be ignored */
2031                                 DCERPC_PFC_FLAG_CONC_MPX |
2032                                 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2033                                 DCERPC_PFC_FLAG_MAYBE |
2034                                 DCERPC_PFC_FLAG_OBJECT_UUID);
2035                 if (!NT_STATUS_IS_OK(status)) {
2036                         return dcesrv_fault_disconnect(call,
2037                                         DCERPC_NCA_S_PROTO_ERROR);
2038                 }
2039
2040                 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2041                         /*
2042                          * We don't use dcesrv_fault_disconnect()
2043                          * here, because we don't want to set
2044                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2045                          *
2046                          * Note that we don't check against the negotiated
2047                          * max_recv_frag, but a hard coded value.
2048                          */
2049                         dcesrv_call_disconnect_after(call,
2050                                 "dcesrv_auth_request - frag_length too large");
2051                         return dcesrv_fault(call,
2052                                         DCERPC_NCA_S_PROTO_ERROR);
2053                 }
2054
2055                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2056                         if (dce_conn->pending_call_list != NULL) {
2057                                 /*
2058                                  * concurrent requests are only allowed
2059                                  * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2060                                  */
2061                                 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2062                                         dcesrv_call_disconnect_after(call,
2063                                                 "dcesrv_auth_request - "
2064                                                 "existing pending call without CONN_MPX");
2065                                         return dcesrv_fault(call,
2066                                                 DCERPC_NCA_S_PROTO_ERROR);
2067                                 }
2068                         }
2069                         /* only one request is possible in the fragmented list */
2070                         if (dce_conn->incoming_fragmented_call_list != NULL) {
2071                                 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2072                                         /*
2073                                          * Without DCERPC_PFC_FLAG_CONC_MPX
2074                                          * we need to return the FAULT on the
2075                                          * already existing call.
2076                                          *
2077                                          * This is important to get the
2078                                          * call_id and context_id right.
2079                                          */
2080                                         TALLOC_FREE(call);
2081                                         call = dce_conn->incoming_fragmented_call_list;
2082                                 }
2083                                 dcesrv_call_disconnect_after(call,
2084                                         "dcesrv_auth_request - "
2085                                         "existing fragmented call");
2086                                 return dcesrv_fault(call,
2087                                                 DCERPC_NCA_S_PROTO_ERROR);
2088                         }
2089                         if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2090                                 return dcesrv_fault_disconnect(call,
2091                                                 DCERPC_FAULT_NO_CALL_ACTIVE);
2092                         }
2093                         call->context = dcesrv_find_context(call->conn,
2094                                                 call->pkt.u.request.context_id);
2095                         if (call->context == NULL) {
2096                                 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2097                                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2098                         }
2099                 } else {
2100                         const struct dcerpc_request *nr = &call->pkt.u.request;
2101                         const struct dcerpc_request *er = NULL;
2102                         int cmp;
2103
2104                         existing = dcesrv_find_fragmented_call(dce_conn,
2105                                                         call->pkt.call_id);
2106                         if (existing == NULL) {
2107                                 dcesrv_call_disconnect_after(call,
2108                                         "dcesrv_auth_request - "
2109                                         "no existing fragmented call");
2110                                 return dcesrv_fault(call,
2111                                                 DCERPC_NCA_S_PROTO_ERROR);
2112                         }
2113                         er = &existing->pkt.u.request;
2114
2115                         if (call->pkt.ptype != existing->pkt.ptype) {
2116                                 /* trying to play silly buggers are we? */
2117                                 return dcesrv_fault_disconnect(existing,
2118                                                 DCERPC_NCA_S_PROTO_ERROR);
2119                         }
2120                         cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2121                                      sizeof(pkt->drep));
2122                         if (cmp != 0) {
2123                                 return dcesrv_fault_disconnect(existing,
2124                                                 DCERPC_NCA_S_PROTO_ERROR);
2125                         }
2126                         if (nr->context_id != er->context_id)  {
2127                                 return dcesrv_fault_disconnect(existing,
2128                                                 DCERPC_NCA_S_PROTO_ERROR);
2129                         }
2130                         if (nr->opnum != er->opnum)  {
2131                                 return dcesrv_fault_disconnect(existing,
2132                                                 DCERPC_NCA_S_PROTO_ERROR);
2133                         }
2134                 }
2135         }
2136
2137         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2138                 bool ok;
2139                 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2140
2141                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2142                         payload_offset += 16;
2143                 }
2144
2145                 ok = dcesrv_auth_pkt_pull(call, &blob,
2146                                           0, /* required_flags */
2147                                           DCERPC_PFC_FLAG_FIRST |
2148                                           DCERPC_PFC_FLAG_LAST |
2149                                           DCERPC_PFC_FLAG_PENDING_CANCEL |
2150                                           0x08 | /* this is not defined, but should be ignored */
2151                                           DCERPC_PFC_FLAG_CONC_MPX |
2152                                           DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2153                                           DCERPC_PFC_FLAG_MAYBE |
2154                                           DCERPC_PFC_FLAG_OBJECT_UUID,
2155                                           payload_offset,
2156                                           &call->pkt.u.request.stub_and_verifier);
2157                 if (!ok) {
2158                         /*
2159                          * We don't use dcesrv_fault_disconnect()
2160                          * here, because we don't want to set
2161                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2162                          */
2163                         dcesrv_call_disconnect_after(call,
2164                                                 "dcesrv_auth_request - failed");
2165                         if (call->fault_code == 0) {
2166                                 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2167                         }
2168                         return dcesrv_fault(call, call->fault_code);
2169                 }
2170         }
2171
2172         /* see if this is a continued packet */
2173         if (existing != NULL) {
2174                 struct dcerpc_request *er = &existing->pkt.u.request;
2175                 const struct dcerpc_request *nr = &call->pkt.u.request;
2176                 size_t available;
2177                 size_t alloc_size;
2178                 size_t alloc_hint;
2179
2180                 /*
2181                  * Up to 4 MByte are allowed by all fragments
2182                  */
2183                 available = dce_conn->max_total_request_size;
2184                 if (er->stub_and_verifier.length > available) {
2185                         dcesrv_call_disconnect_after(existing,
2186                                 "dcesrv_auth_request - existing payload too large");
2187                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2188                 }
2189                 available -= er->stub_and_verifier.length;
2190                 if (nr->alloc_hint > available) {
2191                         dcesrv_call_disconnect_after(existing,
2192                                 "dcesrv_auth_request - alloc hint too large");
2193                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2194                 }
2195                 if (nr->stub_and_verifier.length > available) {
2196                         dcesrv_call_disconnect_after(existing,
2197                                 "dcesrv_auth_request - new payload too large");
2198                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2199                 }
2200                 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2201                 /* allocate at least 1 byte */
2202                 alloc_hint = MAX(alloc_hint, 1);
2203                 alloc_size = er->stub_and_verifier.length +
2204                              nr->stub_and_verifier.length;
2205                 alloc_size = MAX(alloc_size, alloc_hint);
2206
2207                 er->stub_and_verifier.data =
2208                         talloc_realloc(existing,
2209                                        er->stub_and_verifier.data,
2210                                        uint8_t, alloc_size);
2211                 if (er->stub_and_verifier.data == NULL) {
2212                         TALLOC_FREE(call);
2213                         return dcesrv_fault_with_flags(existing,
2214                                                        DCERPC_FAULT_OUT_OF_RESOURCES,
2215                                                        DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2216                 }
2217                 memcpy(er->stub_and_verifier.data +
2218                        er->stub_and_verifier.length,
2219                        nr->stub_and_verifier.data,
2220                        nr->stub_and_verifier.length);
2221                 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2222
2223                 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2224
2225                 TALLOC_FREE(call);
2226                 call = existing;
2227         }
2228
2229         /* this may not be the last pdu in the chain - if its isn't then
2230            just put it on the incoming_fragmented_call_list and wait for the rest */
2231         if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2232             !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2233                 /*
2234                  * Up to 4 MByte are allowed by all fragments
2235                  */
2236                 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2237                         dcesrv_call_disconnect_after(call,
2238                                 "dcesrv_auth_request - initial alloc hint too large");
2239                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2240                 }
2241                 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2242                 return NT_STATUS_OK;
2243         } 
2244         
2245         /* This removes any fragments we may have had stashed away */
2246         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2247
2248         switch (call->pkt.ptype) {
2249         case DCERPC_PKT_BIND:
2250                 status = dcesrv_bind_nak(call,
2251                         DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2252                 break;
2253         case DCERPC_PKT_AUTH3:
2254                 status = dcesrv_auth3(call);
2255                 break;
2256         case DCERPC_PKT_ALTER:
2257                 status = dcesrv_alter(call);
2258                 break;
2259         case DCERPC_PKT_REQUEST:
2260                 status = dcesrv_request(call);
2261                 break;
2262         case DCERPC_PKT_CO_CANCEL:
2263         case DCERPC_PKT_ORPHANED:
2264                 /*
2265                  * Window just ignores CO_CANCEL and ORPHANED,
2266                  * so we do...
2267                  */
2268                 status = NT_STATUS_OK;
2269                 TALLOC_FREE(call);
2270                 break;
2271         case DCERPC_PKT_BIND_ACK:
2272         case DCERPC_PKT_BIND_NAK:
2273         case DCERPC_PKT_ALTER_RESP:
2274         case DCERPC_PKT_RESPONSE:
2275         case DCERPC_PKT_FAULT:
2276         case DCERPC_PKT_SHUTDOWN:
2277         default:
2278                 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2279                 break;
2280         }
2281
2282         /* if we are going to be sending a reply then add
2283            it to the list of pending calls. We add it to the end to keep the call
2284            list in the order we will answer */
2285         if (!NT_STATUS_IS_OK(status)) {
2286                 talloc_free(call);
2287         }
2288
2289         return status;
2290 }
2291
2292 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, 
2293                                       struct loadparm_context *lp_ctx,
2294                                       const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2295 {
2296         NTSTATUS status;
2297         struct dcesrv_context *dce_ctx;
2298         int i;
2299
2300         if (!endpoint_servers) {
2301                 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2302                 return NT_STATUS_INTERNAL_ERROR;
2303         }
2304
2305         dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2306         NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2307
2308         if (uid_wrapper_enabled()) {
2309                 setenv("UID_WRAPPER_MYUID", "1", 1);
2310         }
2311         dce_ctx->initial_euid = geteuid();
2312         if (uid_wrapper_enabled()) {
2313                 unsetenv("UID_WRAPPER_MYUID");
2314         }
2315
2316         dce_ctx->endpoint_list  = NULL;
2317         dce_ctx->lp_ctx = lp_ctx;
2318         dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2319         NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2320         dce_ctx->broken_connections = NULL;
2321
2322         for (i=0;endpoint_servers[i];i++) {
2323                 const struct dcesrv_endpoint_server *ep_server;
2324
2325                 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2326                 if (!ep_server) {
2327                         DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2328                         return NT_STATUS_INTERNAL_ERROR;
2329                 }
2330
2331                 status = ep_server->init_server(dce_ctx, ep_server);
2332                 if (!NT_STATUS_IS_OK(status)) {
2333                         DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2334                                 nt_errstr(status)));
2335                         return status;
2336                 }
2337         }
2338
2339         *_dce_ctx = dce_ctx;
2340         return NT_STATUS_OK;
2341 }
2342
2343 /* the list of currently registered DCERPC endpoint servers.
2344  */
2345 static struct ep_server {
2346         struct dcesrv_endpoint_server *ep_server;
2347 } *ep_servers = NULL;
2348 static int num_ep_servers;
2349
2350 /*
2351   register a DCERPC endpoint server. 
2352
2353   The 'name' can be later used by other backends to find the operations
2354   structure for this backend.  
2355
2356 */
2357 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2358 {
2359         
2360         if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2361                 /* its already registered! */
2362                 DEBUG(0,("DCERPC endpoint server '%s' already registered\n", 
2363                          ep_server->name));
2364                 return NT_STATUS_OBJECT_NAME_COLLISION;
2365         }
2366
2367         ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2368         if (!ep_servers) {
2369                 smb_panic("out of memory in dcerpc_register");
2370         }
2371
2372         ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2373         ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2374
2375         num_ep_servers++;
2376
2377         DEBUG(3,("DCERPC endpoint server '%s' registered\n", 
2378                  ep_server->name));
2379
2380         return NT_STATUS_OK;
2381 }
2382
2383 /*
2384   return the operations structure for a named backend of the specified type
2385 */
2386 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2387 {
2388         int i;
2389
2390         for (i=0;i<num_ep_servers;i++) {
2391                 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2392                         return ep_servers[i].ep_server;
2393                 }
2394         }
2395
2396         return NULL;
2397 }
2398
2399 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2400 {
2401         static bool initialized;
2402 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2403         STATIC_dcerpc_server_MODULES_PROTO;
2404         init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2405         init_module_fn *shared_init;
2406
2407         if (initialized) {
2408                 return;
2409         }
2410         initialized = true;
2411
2412         shared_init = load_samba_modules(NULL, "dcerpc_server");
2413
2414         run_init_functions(NULL, static_init);
2415         run_init_functions(NULL, shared_init);
2416
2417         talloc_free(shared_init);
2418 }
2419
2420 /*
2421   return the DCERPC module version, and the size of some critical types
2422   This can be used by endpoint server modules to either detect compilation errors, or provide
2423   multiple implementations for different smbd compilation options in one module
2424 */
2425 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2426 {
2427         static const struct dcesrv_critical_sizes critical_sizes = {
2428                 DCERPC_MODULE_VERSION,
2429                 sizeof(struct dcesrv_context),
2430                 sizeof(struct dcesrv_endpoint),
2431                 sizeof(struct dcesrv_endpoint_server),
2432                 sizeof(struct dcesrv_interface),
2433                 sizeof(struct dcesrv_if_list),
2434                 sizeof(struct dcesrv_connection),
2435                 sizeof(struct dcesrv_call_state),
2436                 sizeof(struct dcesrv_auth),
2437                 sizeof(struct dcesrv_handle)
2438         };
2439
2440         return &critical_sizes;
2441 }
2442
2443 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2444 {
2445         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2446         struct stream_connection *srv_conn;
2447         srv_conn = talloc_get_type(dce_conn->transport.private_data,
2448                                    struct stream_connection);
2449
2450         dce_conn->wait_send = NULL;
2451         dce_conn->wait_recv = NULL;
2452         dce_conn->wait_private = NULL;
2453
2454         dce_conn->allow_bind = false;
2455         dce_conn->allow_auth3 = false;
2456         dce_conn->allow_alter = false;
2457         dce_conn->allow_request = false;
2458
2459         if (dce_conn->pending_call_list == NULL) {
2460                 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2461
2462                 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2463                 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2464                 return;
2465         }
2466
2467         if (dce_conn->terminate != NULL) {
2468                 return;
2469         }
2470
2471         DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2472                  reason));
2473         dce_conn->terminate = talloc_strdup(dce_conn, reason);
2474         if (dce_conn->terminate == NULL) {
2475                 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2476         }
2477         DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2478 }
2479
2480 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2481 {
2482         struct dcesrv_connection *cur, *next;
2483
2484         next = dce_ctx->broken_connections;
2485         while (next != NULL) {
2486                 cur = next;
2487                 next = cur->next;
2488
2489                 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2490                         struct dcesrv_connection_context *context_cur, *context_next;
2491
2492                         context_next = cur->contexts;
2493                         while (context_next != NULL) {
2494                                 context_cur = context_next;
2495                                 context_next = context_cur->next;
2496
2497                                 dcesrv_connection_context_destructor(context_cur);
2498                         }
2499                 }
2500
2501                 dcesrv_terminate_connection(cur, cur->terminate);
2502         }
2503 }
2504
2505 /* We need this include to be able to compile on some plateforms
2506  * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2507  * correctly.
2508  * It has to be that deep because otherwise we have a conflict on
2509  * const struct dcesrv_interface declaration.
2510  * This is mostly due to socket_wrapper defining #define bind swrap_bind
2511  * which conflict with the bind used before.
2512  */
2513 #include "system/network.h"
2514
2515 struct dcesrv_sock_reply_state {
2516         struct dcesrv_connection *dce_conn;
2517         struct dcesrv_call_state *call;
2518         struct iovec iov;
2519 };
2520
2521 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2522 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2523
2524 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2525 {
2526         struct dcesrv_call_state *call;
2527
2528         call = dce_conn->call_list;
2529         if (!call || !call->replies) {
2530                 return;
2531         }
2532
2533         while (call->replies) {
2534                 struct data_blob_list_item *rep = call->replies;
2535                 struct dcesrv_sock_reply_state *substate;
2536                 struct tevent_req *subreq;
2537
2538                 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2539                 if (!substate) {
2540                         dcesrv_terminate_connection(dce_conn, "no memory");
2541                         return;
2542                 }
2543
2544                 substate->dce_conn = dce_conn;
2545                 substate->call = NULL;
2546
2547                 DLIST_REMOVE(call->replies, rep);
2548
2549                 if (call->replies == NULL && call->terminate_reason == NULL) {
2550                         substate->call = call;
2551                 }
2552
2553                 substate->iov.iov_base = (void *) rep->blob.data;
2554                 substate->iov.iov_len = rep->blob.length;
2555
2556                 subreq = tstream_writev_queue_send(substate,
2557                                                    dce_conn->event_ctx,
2558                                                    dce_conn->stream,
2559                                                    dce_conn->send_queue,
2560                                                    &substate->iov, 1);
2561                 if (!subreq) {
2562                         dcesrv_terminate_connection(dce_conn, "no memory");
2563                         return;
2564                 }
2565                 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2566                                         substate);
2567         }
2568
2569         if (call->terminate_reason != NULL) {
2570                 struct tevent_req *subreq;
2571
2572                 subreq = tevent_queue_wait_send(call,
2573                                                 dce_conn->event_ctx,
2574                                                 dce_conn->send_queue);
2575                 if (!subreq) {
2576                         dcesrv_terminate_connection(dce_conn, __location__);
2577                         return;
2578                 }
2579                 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2580                                         call);
2581         }
2582
2583         DLIST_REMOVE(call->conn->call_list, call);
2584         call->list = DCESRV_LIST_NONE;
2585 }
2586
2587 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2588 {
2589         struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2590                                                 struct dcesrv_sock_reply_state);
2591         int ret;
2592         int sys_errno;
2593         NTSTATUS status;
2594         struct dcesrv_call_state *call = substate->call;
2595
2596         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2597         TALLOC_FREE(subreq);
2598         if (ret == -1) {
2599                 status = map_nt_error_from_unix_common(sys_errno);
2600                 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2601                 return;
2602         }
2603
2604         talloc_free(substate);
2605         if (call) {
2606                 talloc_free(call);
2607         }
2608 }
2609
2610 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2611
2612 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2613 {
2614         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2615                                                 struct dcesrv_call_state);
2616         bool ok;
2617         struct timeval tv;
2618
2619         /* make sure we stop send queue before removing subreq */
2620         tevent_queue_stop(call->conn->send_queue);
2621
2622         ok = tevent_queue_wait_recv(subreq);
2623         TALLOC_FREE(subreq);
2624         if (!ok) {
2625                 dcesrv_terminate_connection(call->conn, __location__);
2626                 return;
2627         }
2628
2629         /* disconnect after 200 usecs */
2630         tv = timeval_current_ofs_usec(200);
2631         subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2632         if (subreq == NULL) {
2633                 dcesrv_terminate_connection(call->conn, __location__);
2634                 return;
2635         }
2636         tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2637                                 call);
2638 }
2639
2640 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2641 {
2642         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2643                                                 struct dcesrv_call_state);
2644         bool ok;
2645
2646         ok = tevent_wakeup_recv(subreq);
2647         TALLOC_FREE(subreq);
2648         if (!ok) {
2649                 dcesrv_terminate_connection(call->conn, __location__);
2650                 return;
2651         }
2652
2653         dcesrv_terminate_connection(call->conn, call->terminate_reason);
2654 }
2655
2656 struct dcesrv_socket_context {
2657         const struct dcesrv_endpoint *endpoint;
2658         struct dcesrv_context *dcesrv_ctx;
2659 };
2660
2661
2662 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2663
2664 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2665 {
2666         NTSTATUS status;
2667         struct dcesrv_socket_context *dcesrv_sock = 
2668                 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2669         enum dcerpc_transport_t transport =
2670                 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2671         struct dcesrv_connection *dcesrv_conn = NULL;
2672         int ret;
2673         struct tevent_req *subreq;
2674         struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2675
2676         dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2677
2678         if (!srv_conn->session_info) {
2679                 status = auth_anonymous_session_info(srv_conn,
2680                                                      lp_ctx,
2681                                                      &srv_conn->session_info);
2682                 if (!NT_STATUS_IS_OK(status)) {
2683                         DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2684                                 nt_errstr(status)));
2685                         stream_terminate_connection(srv_conn, nt_errstr(status));
2686                         return;
2687                 }
2688         }
2689
2690         /*
2691          * This fills in dcesrv_conn->endpoint with the endpoint
2692          * associated with the socket.  From this point on we know
2693          * which (group of) services we are handling, but not the
2694          * specific interface.
2695          */
2696
2697         status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2698                                          srv_conn,
2699                                          dcesrv_sock->endpoint,
2700                                          srv_conn->session_info,
2701                                          srv_conn->event.ctx,
2702                                          srv_conn->msg_ctx,
2703                                          srv_conn->server_id,
2704                                          DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2705                                          &dcesrv_conn);
2706         if (!NT_STATUS_IS_OK(status)) {
2707                 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
2708                         nt_errstr(status)));
2709                 stream_terminate_connection(srv_conn, nt_errstr(status));
2710                 return;
2711         }
2712
2713         dcesrv_conn->transport.private_data             = srv_conn;
2714         dcesrv_conn->transport.report_output_data       = dcesrv_sock_report_output_data;
2715
2716         TALLOC_FREE(srv_conn->event.fde);
2717
2718         dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2719         if (!dcesrv_conn->send_queue) {
2720                 status = NT_STATUS_NO_MEMORY;
2721                 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2722                         nt_errstr(status)));
2723                 stream_terminate_connection(srv_conn, nt_errstr(status));
2724                 return;
2725         }
2726
2727         if (transport == NCACN_NP) {
2728                 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2729                                                   &srv_conn->tstream);
2730         } else {
2731                 ret = tstream_bsd_existing_socket(dcesrv_conn,
2732                                                   socket_get_fd(srv_conn->socket),
2733                                                   &dcesrv_conn->stream);
2734                 if (ret == -1) {
2735                         status = map_nt_error_from_unix_common(errno);
2736                         DEBUG(0, ("dcesrv_sock_accept: "
2737                                   "failed to setup tstream: %s\n",
2738                                   nt_errstr(status)));
2739                         stream_terminate_connection(srv_conn, nt_errstr(status));
2740                         return;
2741                 }
2742                 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2743         }
2744
2745         dcesrv_conn->local_address = srv_conn->local_address;
2746         dcesrv_conn->remote_address = srv_conn->remote_address;
2747
2748         if (transport == NCALRPC) {
2749                 uid_t uid;
2750                 gid_t gid;
2751                 int sock_fd;
2752
2753                 sock_fd = socket_get_fd(srv_conn->socket);
2754                 if (sock_fd == -1) {
2755                         stream_terminate_connection(
2756                                 srv_conn, "socket_get_fd failed\n");
2757                         return;
2758                 }
2759
2760                 ret = getpeereid(sock_fd, &uid, &gid);
2761                 if (ret == -1) {
2762                         status = map_nt_error_from_unix_common(errno);
2763                         DEBUG(0, ("dcesrv_sock_accept: "
2764                                   "getpeereid() failed for NCALRPC: %s\n",
2765                                   nt_errstr(status)));
2766                         stream_terminate_connection(srv_conn, nt_errstr(status));
2767                         return;
2768                 }
2769                 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2770                         struct tsocket_address *r = NULL;
2771
2772                         ret = tsocket_address_unix_from_path(dcesrv_conn,
2773                                                              AS_SYSTEM_MAGIC_PATH_TOKEN,
2774                                                              &r);
2775                         if (ret == -1) {
2776                                 status = map_nt_error_from_unix_common(errno);
2777                                 DEBUG(0, ("dcesrv_sock_accept: "
2778                                           "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2779                                           nt_errstr(status)));
2780                                 stream_terminate_connection(srv_conn, nt_errstr(status));
2781                                 return;
2782                         }
2783                         dcesrv_conn->remote_address = r;
2784                 }
2785         }
2786
2787         srv_conn->private_data = dcesrv_conn;
2788
2789         subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2790                                                dcesrv_conn->event_ctx,
2791                                                dcesrv_conn->stream);
2792         if (!subreq) {
2793                 status = NT_STATUS_NO_MEMORY;
2794                 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2795                         nt_errstr(status)));
2796                 stream_terminate_connection(srv_conn, nt_errstr(status));
2797                 return;
2798         }
2799         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2800
2801         return;
2802 }
2803
2804 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2805
2806 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2807 {
2808         struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2809                                              struct dcesrv_connection);
2810         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2811         struct ncacn_packet *pkt;
2812         DATA_BLOB buffer;
2813         NTSTATUS status;
2814
2815         if (dce_conn->terminate) {
2816                 /*
2817                  * if the current connection is broken
2818                  * we need to clean it up before any other connection
2819                  */
2820                 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2821                 dcesrv_cleanup_broken_connections(dce_ctx);
2822                 return;
2823         }
2824
2825         dcesrv_cleanup_broken_connections(dce_ctx);
2826
2827         status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2828                                                &pkt, &buffer);
2829         TALLOC_FREE(subreq);
2830         if (!NT_STATUS_IS_OK(status)) {
2831                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2832                 return;
2833         }
2834
2835         status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2836         if (!NT_STATUS_IS_OK(status)) {
2837                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2838                 return;
2839         }
2840
2841         /*
2842          * This is used to block the connection during
2843          * pending authentication.
2844          */
2845         if (dce_conn->wait_send != NULL) {
2846                 subreq = dce_conn->wait_send(dce_conn,
2847                                              dce_conn->event_ctx,
2848                                              dce_conn->wait_private);
2849                 if (!subreq) {
2850                         status = NT_STATUS_NO_MEMORY;
2851                         dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2852                         return;
2853                 }
2854                 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2855                 return;
2856         }
2857
2858         subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2859                                                dce_conn->event_ctx,
2860                                                dce_conn->stream);
2861         if (!subreq) {
2862                 status = NT_STATUS_NO_MEMORY;
2863                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2864                 return;
2865         }
2866         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2867 }
2868
2869 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2870 {
2871         struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2872                                              struct dcesrv_connection);
2873         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2874         NTSTATUS status;
2875
2876         if (dce_conn->terminate) {
2877                 /*
2878                  * if the current connection is broken
2879                  * we need to clean it up before any other connection
2880                  */
2881                 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2882                 dcesrv_cleanup_broken_connections(dce_ctx);
2883                 return;
2884         }
2885
2886         dcesrv_cleanup_broken_connections(dce_ctx);
2887
2888         status = dce_conn->wait_recv(subreq);
2889         dce_conn->wait_send = NULL;
2890         dce_conn->wait_recv = NULL;
2891         dce_conn->wait_private = NULL;
2892         TALLOC_FREE(subreq);
2893         if (!NT_STATUS_IS_OK(status)) {
2894                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2895                 return;
2896         }
2897
2898         subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2899                                                dce_conn->event_ctx,
2900                                                dce_conn->stream);
2901         if (!subreq) {
2902                 status = NT_STATUS_NO_MEMORY;
2903                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2904                 return;
2905         }
2906         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2907 }
2908
2909 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2910 {
2911         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2912                                              struct dcesrv_connection);
2913         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2914 }
2915
2916 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2917 {
2918         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2919                                              struct dcesrv_connection);
2920         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2921 }
2922
2923
2924 static const struct stream_server_ops dcesrv_stream_ops = {
2925         .name                   = "rpc",
2926         .accept_connection      = dcesrv_sock_accept,
2927         .recv_handler           = dcesrv_sock_recv,
2928         .send_handler           = dcesrv_sock_send,
2929 };
2930
2931 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 
2932                                    struct loadparm_context *lp_ctx,
2933                                    struct dcesrv_endpoint *e,
2934                                    struct tevent_context *event_ctx,
2935                                    const struct model_ops *model_ops,
2936                                    void *process_context)
2937 {
2938         struct dcesrv_socket_context *dcesrv_sock;
2939         uint16_t port = 1;
2940         NTSTATUS status;
2941         const char *endpoint;
2942
2943         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2944         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2945
2946         /* remember the endpoint of this socket */
2947         dcesrv_sock->endpoint           = e;
2948         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2949
2950         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2951
2952         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2953                                      model_ops, &dcesrv_stream_ops, 
2954                                      "unix", endpoint, &port,
2955                                      lpcfg_socket_options(lp_ctx),
2956                                      dcesrv_sock, process_context);
2957         if (!NT_STATUS_IS_OK(status)) {
2958                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2959                          endpoint, nt_errstr(status)));
2960         }
2961
2962         return status;
2963 }
2964
2965 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 
2966                                       struct loadparm_context *lp_ctx,
2967                                       struct dcesrv_endpoint *e,
2968                                       struct tevent_context *event_ctx,
2969                                       const struct model_ops *model_ops,
2970                                       void *process_context)
2971 {
2972         struct dcesrv_socket_context *dcesrv_sock;
2973         uint16_t port = 1;
2974         char *full_path;
2975         NTSTATUS status;
2976         const char *endpoint;
2977
2978         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2979
2980         if (endpoint == NULL) {
2981                 /*
2982                  * No identifier specified: use DEFAULT.
2983                  *
2984                  * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2985                  * no endpoint and let the epmapper worry about it.
2986                  */
2987                 endpoint = "DEFAULT";
2988                 status = dcerpc_binding_set_string_option(e->ep_description,
2989                                                           "endpoint",
2990                                                           endpoint);
2991                 if (!NT_STATUS_IS_OK(status)) {
2992                         DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2993                                   nt_errstr(status)));
2994                         return status;
2995                 }
2996         }
2997
2998         full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2999                                     endpoint);
3000
3001         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3002         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3003
3004         /* remember the endpoint of this socket */
3005         dcesrv_sock->endpoint           = e;
3006         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
3007
3008         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
3009                                      model_ops, &dcesrv_stream_ops, 
3010                                      "unix", full_path, &port, 
3011                                      lpcfg_socket_options(lp_ctx),
3012                                      dcesrv_sock, process_context);
3013         if (!NT_STATUS_IS_OK(status)) {
3014                 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
3015                          endpoint, full_path, nt_errstr(status)));
3016         }
3017         return status;
3018 }
3019
3020 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
3021                                  struct loadparm_context *lp_ctx,
3022                                  struct dcesrv_endpoint *e,
3023                                  struct tevent_context *event_ctx,
3024                                  const struct model_ops *model_ops,
3025                                  void *process_context)
3026 {
3027         struct dcesrv_socket_context *dcesrv_sock;
3028         NTSTATUS status;
3029         const char *endpoint;
3030
3031         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3032         if (endpoint == NULL) {
3033                 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
3034                 return NT_STATUS_INVALID_PARAMETER;
3035         }
3036
3037         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3038         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3039
3040         /* remember the endpoint of this socket */
3041         dcesrv_sock->endpoint           = e;
3042         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
3043
3044         status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
3045                                           model_ops, &dcesrv_stream_ops,
3046                                           endpoint,
3047                                           dcesrv_sock, process_context);
3048         if (!NT_STATUS_IS_OK(status)) {
3049                 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
3050                          endpoint, nt_errstr(status)));
3051                 return status;
3052         }
3053
3054         return NT_STATUS_OK;
3055 }
3056
3057 /*
3058   add a socket address to the list of events, one event per dcerpc endpoint
3059 */
3060 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3061                                          struct dcesrv_endpoint *e,
3062                                          struct tevent_context *event_ctx,
3063                                          const struct model_ops *model_ops,
3064                                          const char *address,
3065                                          void *process_context)
3066 {
3067         struct dcesrv_socket_context *dcesrv_sock;
3068         uint16_t port = 0;
3069         NTSTATUS status;
3070         const char *endpoint;
3071         char port_str[6];
3072
3073         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3074         if (endpoint != NULL) {
3075                 port = atoi(endpoint);
3076         }
3077
3078         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3079         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3080
3081         /* remember the endpoint of this socket */
3082         dcesrv_sock->endpoint           = e;
3083         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
3084
3085         status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3086                                      model_ops, &dcesrv_stream_ops, 
3087                                      "ip", address, &port,
3088                                      lpcfg_socket_options(dce_ctx->lp_ctx),
3089                                      dcesrv_sock, process_context);
3090         if (!NT_STATUS_IS_OK(status)) {
3091                 struct dcesrv_if_list *iface;
3092                 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3093                          address, port));
3094                 for (iface = e->interface_list; iface; iface = iface->next) {
3095                         DEBUGADD(0, ("%s ", iface->iface.name));
3096                 }
3097                 DEBUGADD(0, ("failed - %s",
3098                              nt_errstr(status)));
3099                 return status;
3100         }
3101
3102         snprintf(port_str, sizeof(port_str), "%u", port);
3103
3104         status = dcerpc_binding_set_string_option(e->ep_description,
3105                                                   "endpoint", port_str);
3106         if (!NT_STATUS_IS_OK(status)) {
3107                 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3108                          port_str, nt_errstr(status)));
3109                 return status;
3110         } else {
3111                 struct dcesrv_if_list *iface;
3112                 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3113                          address, port_str));
3114                 for (iface = e->interface_list; iface; iface = iface->next) {
3115                         DEBUGADD(4, ("%s ", iface->iface.name));
3116                 }
3117                 DEBUGADD(4, ("\n"));
3118         }
3119
3120         return NT_STATUS_OK;
3121 }
3122
3123 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3124
3125 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 
3126                                   struct loadparm_context *lp_ctx,
3127                                   struct dcesrv_endpoint *e,
3128                                   struct tevent_context *event_ctx,
3129                                   const struct model_ops *model_ops,
3130                                   void *process_context)
3131 {
3132         NTSTATUS status;
3133
3134         /* Add TCP/IP sockets */
3135         if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3136                 int num_interfaces;
3137                 int i;
3138                 struct interface *ifaces;
3139
3140                 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3141
3142                 num_interfaces = iface_list_count(ifaces);
3143                 for(i = 0; i < num_interfaces; i++) {
3144                         const char *address = iface_list_n_ip(ifaces, i);
3145                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3146                                                           model_ops, address,
3147                                                           process_context);
3148                         NT_STATUS_NOT_OK_RETURN(status);
3149                 }
3150         } else {
3151                 char **wcard;
3152                 size_t i;
3153                 size_t num_binds = 0;
3154                 wcard = iface_list_wildcard(dce_ctx);
3155                 NT_STATUS_HAVE_NO_MEMORY(wcard);
3156                 for (i=0; wcard[i]; i++) {
3157                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3158                                                           model_ops, wcard[i],
3159                                                           process_context);
3160                         if (NT_STATUS_IS_OK(status)) {
3161                                 num_binds++;
3162                         }
3163                 }
3164                 talloc_free(wcard);
3165                 if (num_binds == 0) {
3166                         return NT_STATUS_INVALID_PARAMETER_MIX;
3167                 }
3168         }
3169
3170         return NT_STATUS_OK;
3171 }
3172
3173 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3174                        struct loadparm_context *lp_ctx,
3175                        struct dcesrv_endpoint *e,
3176                        struct tevent_context *event_ctx,
3177                        const struct model_ops *model_ops,
3178                        void *process_context)
3179 {
3180         enum dcerpc_transport_t transport =
3181                 dcerpc_binding_get_transport(e->ep_description);
3182
3183         switch (transport) {
3184         case NCACN_UNIX_STREAM:
3185                 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3186                                           model_ops, process_context);
3187
3188         case NCALRPC:
3189                 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3190                                              model_ops, process_context);
3191
3192         case NCACN_IP_TCP:
3193                 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3194                                          model_ops, process_context);
3195
3196         case NCACN_NP:
3197                 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3198                                         model_ops, process_context);
3199
3200         default:
3201                 return NT_STATUS_NOT_SUPPORTED;
3202         }
3203 }
3204
3205
3206 /**
3207  * retrieve credentials from a dce_call
3208  */
3209 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3210 {
3211         struct dcesrv_auth *auth = dce_call->auth_state;
3212         return auth->session_info->credentials;
3213 }
3214
3215 /**
3216  * returns true if this is an authenticated call
3217  */
3218 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3219 {
3220         struct dcesrv_auth *auth = dce_call->auth_state;
3221         enum security_user_level level;
3222         level = security_session_user_level(auth->session_info, NULL);
3223         return level >= SECURITY_USER;
3224 }
3225
3226 /**
3227  * retrieve account_name for a dce_call
3228  */
3229 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3230 {
3231         struct dcesrv_auth *auth = dce_call->auth_state;
3232         return auth->session_info->info->account_name;
3233 }
3234
3235 /**
3236  * retrieve session_info from a dce_call
3237  */
3238 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3239 {
3240         struct dcesrv_auth *auth = dce_call->auth_state;
3241         return auth->session_info;
3242 }
3243
3244 /**
3245  * retrieve auth type/level from a dce_call
3246  */
3247 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
3248                                     enum dcerpc_AuthType *auth_type,
3249                                     enum dcerpc_AuthLevel *auth_level)
3250 {
3251         struct dcesrv_auth *auth = dce_call->auth_state;
3252
3253         if (auth_type != NULL) {
3254                 *auth_type = auth->auth_type;
3255         }
3256         if (auth_level != NULL) {
3257                 *auth_level = auth->auth_level;
3258         }
3259 }