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