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