s4:rpc_server: implement DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN support
[metze/samba/wip.git] / source4 / rpc_server / dcerpc_server.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    server side dcerpc core code
5
6    Copyright (C) Andrew Tridgell 2003-2005
7    Copyright (C) Stefan (metze) Metzmacher 2004-2005
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "../lib/util/dlinklist.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/dcerpc_server_proto.h"
29 #include "rpc_server/common/proto.h"
30 #include "librpc/rpc/dcerpc_proto.h"
31 #include "system/filesys.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "../lib/tsocket/tsocket.h"
35 #include "../libcli/named_pipe_auth/npa_tstream.h"
36 #include "smbd/service_stream.h"
37 #include "../lib/tsocket/tsocket.h"
38 #include "lib/socket/socket.h"
39 #include "smbd/process_model.h"
40 #include "lib/messaging/irpc.h"
41 #include "librpc/rpc/rpc_common.h"
42 #include "lib/util/samba_modules.h"
43 #include "librpc/gen_ndr/ndr_dcerpc.h"
44
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                         a->reason.negotiate |=
790                                 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
791                 }
792
793                 call->conn->bind_time_features = a->reason.negotiate;
794         }
795
796         /*
797          * Try to negotiate one new presentation context.
798          */
799         status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
800         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
801                 return dcesrv_bind_nak(call, 0);
802         }
803         if (!NT_STATUS_IS_OK(status)) {
804                 return status;
805         }
806
807         if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
808             (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
809                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
810                 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
811         }
812
813         if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
814                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
815         }
816
817         /* handle any authentication that is being requested */
818         if (!dcesrv_auth_bind(call)) {
819                 struct dcesrv_auth *auth = &call->conn->auth_state;
820
821                 TALLOC_FREE(call->context);
822
823                 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
824                         /*
825                          * With DCERPC_AUTH_LEVEL_NONE, we get the
826                          * reject_reason in auth->auth_context_id.
827                          */
828                         return dcesrv_bind_nak(call, auth->auth_context_id);
829                 }
830
831                 /*
832                  * This must a be a temporary failure e.g. talloc or invalid
833                  * configuration, e.g. no machine account.
834                  */
835                 return dcesrv_bind_nak(call,
836                                 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
837         }
838
839         /* setup a bind_ack */
840         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
841         pkt.auth_length = 0;
842         pkt.call_id = call->pkt.call_id;
843         pkt.ptype = DCERPC_PKT_BIND_ACK;
844         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
845         pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
846         pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
847         pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
848
849         endpoint = dcerpc_binding_get_string_option(
850                                 call->conn->endpoint->ep_description,
851                                 "endpoint");
852         if (endpoint == NULL) {
853                 endpoint = "";
854         }
855
856         if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
857                 /*
858                  * TODO: check if this is really needed
859                  *
860                  * Or if we should fix this in our idl files.
861                  */
862                 ep_prefix = "\\PIPE\\";
863                 endpoint += 6;
864         }
865
866         pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
867                                                            ep_prefix,
868                                                            endpoint);
869         if (pkt.u.bind_ack.secondary_address == NULL) {
870                 TALLOC_FREE(call->context);
871                 return NT_STATUS_NO_MEMORY;
872         }
873         pkt.u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
874         pkt.u.bind_ack.ctx_list = ack_ctx_list;
875         pkt.u.bind_ack.auth_info = data_blob_null;
876
877         status = dcesrv_auth_bind_ack(call, &pkt);
878         if (!NT_STATUS_IS_OK(status)) {
879                 TALLOC_FREE(call->context);
880                 return dcesrv_bind_nak(call, 0);
881         }
882
883         rep = talloc_zero(call, struct data_blob_list_item);
884         if (!rep) {
885                 TALLOC_FREE(call->context);
886                 return NT_STATUS_NO_MEMORY;
887         }
888
889         status = ncacn_push_auth(&rep->blob, call, &pkt,
890                                  call->out_auth_info);
891         if (!NT_STATUS_IS_OK(status)) {
892                 TALLOC_FREE(call->context);
893                 return status;
894         }
895
896         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
897
898         DLIST_ADD_END(call->replies, rep);
899         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
900
901         if (call->conn->call_list && call->conn->call_list->replies) {
902                 if (call->conn->transport.report_output_data) {
903                         call->conn->transport.report_output_data(call->conn);
904                 }
905         }
906
907         return NT_STATUS_OK;
908 }
909
910
911 /*
912   handle a auth3 request
913 */
914 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
915 {
916         NTSTATUS status;
917
918         if (!call->conn->allow_auth3) {
919                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
920         }
921
922         if (call->conn->auth_state.auth_finished) {
923                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
924         }
925
926         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
927                         DCERPC_PKT_AUTH3,
928                         call->pkt.u.auth3.auth_info.length,
929                         0, /* required flags */
930                         DCERPC_PFC_FLAG_FIRST |
931                         DCERPC_PFC_FLAG_LAST |
932                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
933                         0x08 | /* this is not defined, but should be ignored */
934                         DCERPC_PFC_FLAG_CONC_MPX |
935                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
936                         DCERPC_PFC_FLAG_MAYBE |
937                         DCERPC_PFC_FLAG_OBJECT_UUID);
938         if (!NT_STATUS_IS_OK(status)) {
939                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
940         }
941
942         /* handle the auth3 in the auth code */
943         if (!dcesrv_auth_auth3(call)) {
944                 call->conn->auth_state.auth_invalid = true;
945                 if (call->fault_code != 0) {
946                         return dcesrv_fault_disconnect(call, call->fault_code);
947                 }
948         }
949
950         talloc_free(call);
951
952         /* we don't send a reply to a auth3 request, except by a
953            fault */
954         return NT_STATUS_OK;
955 }
956
957
958 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
959                                 const struct dcerpc_bind *b,
960                                 const struct dcerpc_ctx_list *ctx,
961                                 struct dcerpc_ack_ctx *ack,
962                                 bool validate_only,
963                                 const struct ndr_syntax_id *supported_transfer)
964 {
965         uint32_t if_version;
966         struct dcesrv_connection_context *context;
967         const struct dcesrv_interface *iface;
968         struct GUID uuid;
969         NTSTATUS status;
970         const struct ndr_syntax_id *selected_transfer = NULL;
971         size_t i;
972         bool ok;
973
974         if (b == NULL) {
975                 return NT_STATUS_INTERNAL_ERROR;
976         }
977         if (ctx == NULL) {
978                 return NT_STATUS_INTERNAL_ERROR;
979         }
980         if (ctx->num_transfer_syntaxes < 1) {
981                 return NT_STATUS_INTERNAL_ERROR;
982         }
983         if (ack == NULL) {
984                 return NT_STATUS_INTERNAL_ERROR;
985         }
986         if (supported_transfer == NULL) {
987                 return NT_STATUS_INTERNAL_ERROR;
988         }
989
990         switch (ack->result) {
991         case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
992         case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
993                 /*
994                  * We is already completed.
995                  */
996                 return NT_STATUS_OK;
997         default:
998                 break;
999         }
1000
1001         ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1002         ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1003
1004         if_version = ctx->abstract_syntax.if_version;
1005         uuid = ctx->abstract_syntax.uuid;
1006
1007         iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1008         if (iface == NULL) {
1009                 char *uuid_str = GUID_string(call, &uuid);
1010                 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1011                 talloc_free(uuid_str);
1012                 /*
1013                  * We report this only via ack->result
1014                  */
1015                 return NT_STATUS_OK;
1016         }
1017
1018         ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1019         ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1020
1021         if (validate_only) {
1022                 /*
1023                  * We report this only via ack->result
1024                  */
1025                 return NT_STATUS_OK;
1026         }
1027
1028         for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1029                 /*
1030                  * we only do NDR encoded dcerpc for now.
1031                  */
1032                 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1033                                          supported_transfer);
1034                 if (ok) {
1035                         selected_transfer = supported_transfer;
1036                         break;
1037                 }
1038         }
1039
1040         context = dcesrv_find_context(call->conn, ctx->context_id);
1041         if (context != NULL) {
1042                 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1043                                          &ctx->abstract_syntax);
1044                 if (!ok) {
1045                         return NT_STATUS_RPC_PROTOCOL_ERROR;
1046                 }
1047
1048                 if (selected_transfer != NULL) {
1049                         ok = ndr_syntax_id_equal(&context->transfer_syntax,
1050                                                  selected_transfer);
1051                         if (!ok) {
1052                                 return NT_STATUS_RPC_PROTOCOL_ERROR;
1053                         }
1054
1055                         ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1056                         ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1057                         ack->syntax = context->transfer_syntax;
1058                 }
1059
1060                 /*
1061                  * We report this only via ack->result
1062                  */
1063                 return NT_STATUS_OK;
1064         }
1065
1066         if (selected_transfer == NULL) {
1067                 /*
1068                  * We report this only via ack->result
1069                  */
1070                 return NT_STATUS_OK;
1071         }
1072
1073         ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1074         ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1075
1076         /* add this context to the list of available context_ids */
1077         context = talloc_zero(call->conn, struct dcesrv_connection_context);
1078         if (context == NULL) {
1079                 return NT_STATUS_NO_MEMORY;
1080         }
1081         context->conn = call->conn;
1082         context->context_id = ctx->context_id;
1083         context->iface = iface;
1084         context->transfer_syntax = *selected_transfer;
1085         context->private_data = NULL;
1086         DLIST_ADD(call->conn->contexts, context);
1087         call->context = context;
1088         talloc_set_destructor(context, dcesrv_connection_context_destructor);
1089
1090         dcesrv_prepare_context_auth(call);
1091
1092         status = iface->bind(call, iface, if_version);
1093         call->context = NULL;
1094         if (!NT_STATUS_IS_OK(status)) {
1095                 /* we don't want to trigger the iface->unbind() hook */
1096                 context->iface = NULL;
1097                 talloc_free(context);
1098                 /*
1099                  * We report this only via ack->result
1100                  */
1101                 return NT_STATUS_OK;
1102         }
1103
1104         ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1105         ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1106         ack->syntax = context->transfer_syntax;
1107         return NT_STATUS_OK;
1108 }
1109
1110 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1111                                 const struct dcerpc_bind *b,
1112                                 struct dcerpc_ack_ctx *ack_ctx_list)
1113 {
1114         NTSTATUS status;
1115         size_t i;
1116         bool validate_only = false;
1117         bool preferred_ndr32;
1118
1119         /*
1120          * Try to negotiate one new presentation context,
1121          * using our preferred transfer syntax.
1122          */
1123         for (i = 0; i < b->num_contexts; i++) {
1124                 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1125                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1126
1127                 status = dcesrv_check_or_create_context(call, b, c, a,
1128                                                 validate_only,
1129                                                 call->conn->preferred_transfer);
1130                 if (!NT_STATUS_IS_OK(status)) {
1131                         return status;
1132                 }
1133
1134                 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1135                         /*
1136                          * We managed to negotiate one context.
1137                          *
1138                          * => we're done.
1139                          */
1140                         validate_only = true;
1141                 }
1142         }
1143
1144         preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1145                                         call->conn->preferred_transfer);
1146         if (preferred_ndr32) {
1147                 /*
1148                  * We're done.
1149                  */
1150                 return NT_STATUS_OK;
1151         }
1152
1153         /*
1154          * Try to negotiate one new presentation context,
1155          * using NDR 32 as fallback.
1156          */
1157         for (i = 0; i < b->num_contexts; i++) {
1158                 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1159                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1160
1161                 status = dcesrv_check_or_create_context(call, b, c, a,
1162                                                 validate_only,
1163                                                 &ndr_transfer_syntax_ndr);
1164                 if (!NT_STATUS_IS_OK(status)) {
1165                         return status;
1166                 }
1167
1168                 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1169                         /*
1170                          * We managed to negotiate one context.
1171                          *
1172                          * => we're done.
1173                          */
1174                         validate_only = true;
1175                 }
1176         }
1177
1178         return NT_STATUS_OK;
1179 }
1180
1181 /*
1182   handle a alter context request
1183 */
1184 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1185 {
1186         NTSTATUS status;
1187         bool auth_ok = false;
1188         struct ncacn_packet pkt;
1189         uint32_t extra_flags = 0;
1190         struct data_blob_list_item *rep = NULL;
1191         struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1192         size_t i;
1193
1194         if (!call->conn->allow_alter) {
1195                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1196         }
1197
1198         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1199                         DCERPC_PKT_ALTER,
1200                         call->pkt.u.alter.auth_info.length,
1201                         0, /* required flags */
1202                         DCERPC_PFC_FLAG_FIRST |
1203                         DCERPC_PFC_FLAG_LAST |
1204                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1205                         0x08 | /* this is not defined, but should be ignored */
1206                         DCERPC_PFC_FLAG_CONC_MPX |
1207                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1208                         DCERPC_PFC_FLAG_MAYBE |
1209                         DCERPC_PFC_FLAG_OBJECT_UUID);
1210         if (!NT_STATUS_IS_OK(status)) {
1211                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1212         }
1213
1214         auth_ok = dcesrv_auth_alter(call);
1215         if (!auth_ok) {
1216                 if (call->fault_code != 0) {
1217                         return dcesrv_fault_disconnect(call, call->fault_code);
1218                 }
1219         }
1220
1221         if (call->pkt.u.alter.num_contexts < 1) {
1222                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1223         }
1224
1225         ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1226                                          call->pkt.u.alter.num_contexts);
1227         if (ack_ctx_list == NULL) {
1228                 return NT_STATUS_NO_MEMORY;
1229         }
1230
1231         /*
1232          * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1233          * dcesrv_check_or_create_context()) and do some protocol validation
1234          * and set sane defaults.
1235          */
1236         for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1237                 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1238                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1239
1240                 if (c->num_transfer_syntaxes == 0) {
1241                         return dcesrv_fault_disconnect(call,
1242                                         DCERPC_NCA_S_PROTO_ERROR);
1243                 }
1244
1245                 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1246                 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1247         }
1248
1249         /*
1250          * Try to negotiate one new presentation context.
1251          */
1252         status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1253         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1254                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1255         }
1256         if (!NT_STATUS_IS_OK(status)) {
1257                 return status;
1258         }
1259
1260         if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1261             (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1262                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1263                 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1264         }
1265
1266         if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1267                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1268         }
1269
1270         /* handle any authentication that is being requested */
1271         if (!auth_ok) {
1272                 if (call->in_auth_info.auth_type !=
1273                     call->conn->auth_state.auth_type)
1274                 {
1275                         return dcesrv_fault_disconnect(call,
1276                                         DCERPC_FAULT_SEC_PKG_ERROR);
1277                 }
1278                 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1279         }
1280
1281         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1282         pkt.auth_length = 0;
1283         pkt.call_id = call->pkt.call_id;
1284         pkt.ptype = DCERPC_PKT_ALTER_RESP;
1285         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1286         pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1287         pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1288         pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1289         pkt.u.alter_resp.secondary_address = "";
1290         pkt.u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1291         pkt.u.alter_resp.ctx_list = ack_ctx_list;
1292         pkt.u.alter_resp.auth_info = data_blob_null;
1293
1294         status = dcesrv_auth_alter_ack(call, &pkt);
1295         if (!NT_STATUS_IS_OK(status)) {
1296                 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1297         }
1298
1299         rep = talloc_zero(call, struct data_blob_list_item);
1300         if (!rep) {
1301                 return NT_STATUS_NO_MEMORY;
1302         }
1303
1304         status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1305         if (!NT_STATUS_IS_OK(status)) {
1306                 return status;
1307         }
1308
1309         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1310
1311         DLIST_ADD_END(call->replies, rep);
1312         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1313
1314         if (call->conn->call_list && call->conn->call_list->replies) {
1315                 if (call->conn->transport.report_output_data) {
1316                         call->conn->transport.report_output_data(call->conn);
1317                 }
1318         }
1319
1320         return NT_STATUS_OK;
1321 }
1322
1323 /*
1324   possibly save the call for inspection with ndrdump
1325  */
1326 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1327 {
1328 #ifdef DEVELOPER
1329         char *fname;
1330         const char *dump_dir;
1331         dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1332         if (!dump_dir) {
1333                 return;
1334         }
1335         fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1336                                 dump_dir,
1337                                 call->context->iface->name,
1338                                 call->pkt.u.request.opnum,
1339                                 why);
1340         if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1341                 DEBUG(0,("RPC SAVED %s\n", fname));
1342         }
1343         talloc_free(fname);
1344 #endif
1345 }
1346
1347 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1348 {
1349         TALLOC_CTX *frame = talloc_stackframe();
1350         const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1351                 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1352         const struct dcerpc_sec_vt_pcontext pcontext = {
1353                 .abstract_syntax = call->context->iface->syntax_id,
1354                 .transfer_syntax = call->context->transfer_syntax,
1355         };
1356         const struct dcerpc_sec_vt_header2 header2 =
1357                 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1358         enum ndr_err_code ndr_err;
1359         struct dcerpc_sec_verification_trailer *vt = NULL;
1360         NTSTATUS status = NT_STATUS_OK;
1361         bool ok;
1362
1363         SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1364
1365         ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1366                                                           frame, &vt);
1367         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1368                 status = ndr_map_error2ntstatus(ndr_err);
1369                 goto done;
1370         }
1371
1372         ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1373                                                    &pcontext, &header2);
1374         if (!ok) {
1375                 status = NT_STATUS_ACCESS_DENIED;
1376                 goto done;
1377         }
1378 done:
1379         TALLOC_FREE(frame);
1380         return status;
1381 }
1382
1383 /*
1384   handle a dcerpc request packet
1385 */
1386 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1387 {
1388         const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1389         enum dcerpc_transport_t transport =
1390                 dcerpc_binding_get_transport(endpoint->ep_description);
1391         struct ndr_pull *pull;
1392         NTSTATUS status;
1393         struct dcesrv_connection_context *context;
1394
1395         if (!call->conn->allow_request) {
1396                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1397         }
1398
1399         /* if authenticated, and the mech we use can't do async replies, don't use them... */
1400         if (call->conn->auth_state.gensec_security && 
1401             !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1402                 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1403         }
1404
1405         context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id);
1406         if (context == NULL) {
1407                 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1408                                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1409         }
1410
1411         switch (call->conn->auth_state.auth_level) {
1412         case DCERPC_AUTH_LEVEL_NONE:
1413         case DCERPC_AUTH_LEVEL_PACKET:
1414         case DCERPC_AUTH_LEVEL_INTEGRITY:
1415         case DCERPC_AUTH_LEVEL_PRIVACY:
1416                 break;
1417         default:
1418                 if (!context->allow_connect) {
1419                         char *addr;
1420
1421                         addr = tsocket_address_string(call->conn->remote_address,
1422                                                       call);
1423
1424                         DEBUG(2, ("%s: restrict auth_level_connect access "
1425                                   "to [%s] with auth[type=0x%x,level=0x%x] "
1426                                   "on [%s] from [%s]\n",
1427                                   __func__, context->iface->name,
1428                                   call->conn->auth_state.auth_type,
1429                                   call->conn->auth_state.auth_level,
1430                                   derpc_transport_string_by_transport(transport),
1431                                   addr));
1432                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1433                 }
1434                 break;
1435         }
1436
1437         if (call->conn->auth_state.auth_level < context->min_auth_level) {
1438                 char *addr;
1439
1440                 addr = tsocket_address_string(call->conn->remote_address, call);
1441
1442                 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1443                           "to [%s] with auth[type=0x%x,level=0x%x] "
1444                           "on [%s] from [%s]\n",
1445                           __func__,
1446                           context->min_auth_level,
1447                           context->iface->name,
1448                           call->conn->auth_state.auth_type,
1449                           call->conn->auth_state.auth_level,
1450                           derpc_transport_string_by_transport(transport),
1451                           addr));
1452                 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1453         }
1454
1455         pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1456         NT_STATUS_HAVE_NO_MEMORY(pull);
1457
1458         pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1459
1460         call->context   = context;
1461         call->ndr_pull  = pull;
1462
1463         if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1464                 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1465         }
1466
1467         status = dcesrv_check_verification_trailer(call);
1468         if (!NT_STATUS_IS_OK(status)) {
1469                 uint32_t faultcode = DCERPC_FAULT_OTHER;
1470                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1471                         faultcode = DCERPC_FAULT_ACCESS_DENIED;
1472                 }
1473                 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1474                            nt_errstr(status)));
1475                 return dcesrv_fault(call, faultcode);
1476         }
1477
1478         /* unravel the NDR for the packet */
1479         status = context->iface->ndr_pull(call, call, pull, &call->r);
1480         if (!NT_STATUS_IS_OK(status)) {
1481                 uint8_t extra_flags = 0;
1482                 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1483                         /* we got an unknown call */
1484                         DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1485                                  call->pkt.u.request.opnum, context->iface->name));
1486                         dcesrv_save_call(call, "unknown");
1487                         extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1488                 } else {
1489                         dcesrv_save_call(call, "pullfail");
1490                 }
1491                 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1492         }
1493
1494         if (pull->offset != pull->data_size) {
1495                 dcesrv_save_call(call, "extrabytes");
1496                 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n", 
1497                          pull->data_size - pull->offset));
1498         }
1499
1500         /* call the dispatch function */
1501         status = context->iface->dispatch(call, call, call->r);
1502         if (!NT_STATUS_IS_OK(status)) {
1503                 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1504                          context->iface->name, 
1505                          call->pkt.u.request.opnum,
1506                          dcerpc_errstr(pull, call->fault_code)));
1507                 return dcesrv_fault(call, call->fault_code);
1508         }
1509
1510         /* add the call to the pending list */
1511         dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1512
1513         if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1514                 return NT_STATUS_OK;
1515         }
1516
1517         return dcesrv_reply(call);
1518 }
1519
1520
1521 /*
1522   remove the call from the right list when freed
1523  */
1524 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1525 {
1526         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1527         return 0;
1528 }
1529
1530 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1531 {
1532         return conn->local_address;
1533 }
1534
1535 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1536 {
1537         return conn->remote_address;
1538 }
1539
1540 /*
1541   process some input to a dcerpc endpoint server.
1542 */
1543 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1544                                             struct ncacn_packet *pkt,
1545                                             DATA_BLOB blob)
1546 {
1547         NTSTATUS status;
1548         struct dcesrv_call_state *call;
1549         struct dcesrv_call_state *existing = NULL;
1550
1551         call = talloc_zero(dce_conn, struct dcesrv_call_state);
1552         if (!call) {
1553                 data_blob_free(&blob);
1554                 talloc_free(pkt);
1555                 return NT_STATUS_NO_MEMORY;
1556         }
1557         call->conn              = dce_conn;
1558         call->event_ctx         = dce_conn->event_ctx;
1559         call->msg_ctx           = dce_conn->msg_ctx;
1560         call->state_flags       = call->conn->state_flags;
1561         call->time              = timeval_current();
1562         call->list              = DCESRV_LIST_NONE;
1563
1564         talloc_steal(call, pkt);
1565         talloc_steal(call, blob.data);
1566         call->pkt = *pkt;
1567
1568         talloc_set_destructor(call, dcesrv_call_dequeue);
1569
1570         if (call->conn->allow_bind) {
1571                 /*
1572                  * Only one bind is possible per connection
1573                  */
1574                 call->conn->allow_bind = false;
1575                 return dcesrv_bind(call);
1576         }
1577
1578         /* we have to check the signing here, before combining the
1579            pdus */
1580         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1581                 if (!call->conn->allow_request) {
1582                         return dcesrv_fault_disconnect(call,
1583                                         DCERPC_NCA_S_PROTO_ERROR);
1584                 }
1585
1586                 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1587                                 DCERPC_PKT_REQUEST,
1588                                 call->pkt.u.request.stub_and_verifier.length,
1589                                 0, /* required_flags */
1590                                 DCERPC_PFC_FLAG_FIRST |
1591                                 DCERPC_PFC_FLAG_LAST |
1592                                 DCERPC_PFC_FLAG_PENDING_CANCEL |
1593                                 0x08 | /* this is not defined, but should be ignored */
1594                                 DCERPC_PFC_FLAG_CONC_MPX |
1595                                 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1596                                 DCERPC_PFC_FLAG_MAYBE |
1597                                 DCERPC_PFC_FLAG_OBJECT_UUID);
1598                 if (!NT_STATUS_IS_OK(status)) {
1599                         return dcesrv_fault_disconnect(call,
1600                                         DCERPC_NCA_S_PROTO_ERROR);
1601                 }
1602
1603                 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1604                         /*
1605                          * We don't use dcesrv_fault_disconnect()
1606                          * here, because we don't want to set
1607                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1608                          *
1609                          * Note that we don't check against the negotiated
1610                          * max_recv_frag, but a hard coded value.
1611                          */
1612                         dcesrv_call_disconnect_after(call,
1613                                 "dcesrv_auth_request - frag_length too large");
1614                         return dcesrv_fault(call,
1615                                         DCERPC_NCA_S_PROTO_ERROR);
1616                 }
1617
1618                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1619                         /* only one request is possible in the fragmented list */
1620                         if (dce_conn->incoming_fragmented_call_list != NULL) {
1621                                 TALLOC_FREE(call);
1622                                 call = dce_conn->incoming_fragmented_call_list;
1623                                 dcesrv_call_disconnect_after(call,
1624                                         "dcesrv_auth_request - "
1625                                         "existing fragmented call");
1626                                 return dcesrv_fault(call,
1627                                                 DCERPC_NCA_S_PROTO_ERROR);
1628                         }
1629                         if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1630                                 return dcesrv_fault_disconnect(call,
1631                                                 DCERPC_FAULT_NO_CALL_ACTIVE);
1632                         }
1633                 } else {
1634                         const struct dcerpc_request *nr = &call->pkt.u.request;
1635                         const struct dcerpc_request *er = NULL;
1636                         int cmp;
1637
1638                         existing = dcesrv_find_fragmented_call(dce_conn,
1639                                                         call->pkt.call_id);
1640                         if (existing == NULL) {
1641                                 dcesrv_call_disconnect_after(call,
1642                                         "dcesrv_auth_request - "
1643                                         "no existing fragmented call");
1644                                 return dcesrv_fault(call,
1645                                                 DCERPC_NCA_S_PROTO_ERROR);
1646                         }
1647                         er = &existing->pkt.u.request;
1648
1649                         if (call->pkt.ptype != existing->pkt.ptype) {
1650                                 /* trying to play silly buggers are we? */
1651                                 return dcesrv_fault_disconnect(existing,
1652                                                 DCERPC_NCA_S_PROTO_ERROR);
1653                         }
1654                         cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1655                                      sizeof(pkt->drep));
1656                         if (cmp != 0) {
1657                                 return dcesrv_fault_disconnect(existing,
1658                                                 DCERPC_NCA_S_PROTO_ERROR);
1659                         }
1660                         if (nr->context_id != er->context_id)  {
1661                                 return dcesrv_fault_disconnect(existing,
1662                                                 DCERPC_NCA_S_PROTO_ERROR);
1663                         }
1664                         if (nr->opnum != er->opnum)  {
1665                                 return dcesrv_fault_disconnect(existing,
1666                                                 DCERPC_NCA_S_PROTO_ERROR);
1667                         }
1668                 }
1669         }
1670
1671         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1672                 bool ok;
1673                 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1674
1675                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1676                         payload_offset += 16;
1677                 }
1678
1679                 ok = dcesrv_auth_pkt_pull(call, &blob,
1680                                           0, /* required_flags */
1681                                           DCERPC_PFC_FLAG_FIRST |
1682                                           DCERPC_PFC_FLAG_LAST |
1683                                           DCERPC_PFC_FLAG_PENDING_CANCEL |
1684                                           0x08 | /* this is not defined, but should be ignored */
1685                                           DCERPC_PFC_FLAG_CONC_MPX |
1686                                           DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1687                                           DCERPC_PFC_FLAG_MAYBE |
1688                                           DCERPC_PFC_FLAG_OBJECT_UUID,
1689                                           payload_offset,
1690                                           &call->pkt.u.request.stub_and_verifier);
1691                 if (!ok) {
1692                         /*
1693                          * We don't use dcesrv_fault_disconnect()
1694                          * here, because we don't want to set
1695                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1696                          */
1697                         dcesrv_call_disconnect_after(call,
1698                                                 "dcesrv_auth_request - failed");
1699                         if (call->fault_code == 0) {
1700                                 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1701                         }
1702                         return dcesrv_fault(call, call->fault_code);
1703                 }
1704         }
1705
1706         /* see if this is a continued packet */
1707         if (existing != NULL) {
1708                 struct dcerpc_request *er = &existing->pkt.u.request;
1709                 const struct dcerpc_request *nr = &call->pkt.u.request;
1710                 size_t available;
1711                 size_t alloc_size;
1712                 size_t alloc_hint;
1713
1714                 /*
1715                  * Up to 4 MByte are allowed by all fragments
1716                  */
1717                 available = dce_conn->max_total_request_size;
1718                 if (er->stub_and_verifier.length > available) {
1719                         dcesrv_call_disconnect_after(existing,
1720                                 "dcesrv_auth_request - existing payload too large");
1721                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1722                 }
1723                 available -= er->stub_and_verifier.length;
1724                 if (nr->alloc_hint > available) {
1725                         dcesrv_call_disconnect_after(existing,
1726                                 "dcesrv_auth_request - alloc hint too large");
1727                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1728                 }
1729                 if (nr->stub_and_verifier.length > available) {
1730                         dcesrv_call_disconnect_after(existing,
1731                                 "dcesrv_auth_request - new payload too large");
1732                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1733                 }
1734                 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1735                 /* allocate at least 1 byte */
1736                 alloc_hint = MAX(alloc_hint, 1);
1737                 alloc_size = er->stub_and_verifier.length +
1738                              nr->stub_and_verifier.length;
1739                 alloc_size = MAX(alloc_size, alloc_hint);
1740
1741                 er->stub_and_verifier.data =
1742                         talloc_realloc(existing,
1743                                        er->stub_and_verifier.data,
1744                                        uint8_t, alloc_size);
1745                 if (er->stub_and_verifier.data == NULL) {
1746                         TALLOC_FREE(call);
1747                         return dcesrv_fault_with_flags(existing,
1748                                                        DCERPC_FAULT_OUT_OF_RESOURCES,
1749                                                        DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1750                 }
1751                 memcpy(er->stub_and_verifier.data +
1752                        er->stub_and_verifier.length,
1753                        nr->stub_and_verifier.data,
1754                        nr->stub_and_verifier.length);
1755                 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1756
1757                 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1758
1759                 TALLOC_FREE(call);
1760                 call = existing;
1761         }
1762
1763         /* this may not be the last pdu in the chain - if its isn't then
1764            just put it on the incoming_fragmented_call_list and wait for the rest */
1765         if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1766             !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1767                 /*
1768                  * Up to 4 MByte are allowed by all fragments
1769                  */
1770                 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1771                         dcesrv_call_disconnect_after(call,
1772                                 "dcesrv_auth_request - initial alloc hint too large");
1773                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1774                 }
1775                 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1776                 return NT_STATUS_OK;
1777         } 
1778         
1779         /* This removes any fragments we may have had stashed away */
1780         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1781
1782         switch (call->pkt.ptype) {
1783         case DCERPC_PKT_BIND:
1784                 status = dcesrv_bind_nak(call,
1785                         DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1786                 break;
1787         case DCERPC_PKT_AUTH3:
1788                 status = dcesrv_auth3(call);
1789                 break;
1790         case DCERPC_PKT_ALTER:
1791                 status = dcesrv_alter(call);
1792                 break;
1793         case DCERPC_PKT_REQUEST:
1794                 status = dcesrv_request(call);
1795                 break;
1796         case DCERPC_PKT_CO_CANCEL:
1797         case DCERPC_PKT_ORPHANED:
1798                 /*
1799                  * Window just ignores CO_CANCEL and ORPHANED,
1800                  * so we do...
1801                  */
1802                 status = NT_STATUS_OK;
1803                 TALLOC_FREE(call);
1804                 break;
1805         case DCERPC_PKT_BIND_ACK:
1806         case DCERPC_PKT_BIND_NAK:
1807         case DCERPC_PKT_ALTER_RESP:
1808         case DCERPC_PKT_RESPONSE:
1809         case DCERPC_PKT_FAULT:
1810         case DCERPC_PKT_SHUTDOWN:
1811         default:
1812                 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1813                 break;
1814         }
1815
1816         /* if we are going to be sending a reply then add
1817            it to the list of pending calls. We add it to the end to keep the call
1818            list in the order we will answer */
1819         if (!NT_STATUS_IS_OK(status)) {
1820                 talloc_free(call);
1821         }
1822
1823         return status;
1824 }
1825
1826 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, 
1827                                       struct loadparm_context *lp_ctx,
1828                                       const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1829 {
1830         NTSTATUS status;
1831         struct dcesrv_context *dce_ctx;
1832         int i;
1833
1834         if (!endpoint_servers) {
1835                 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1836                 return NT_STATUS_INTERNAL_ERROR;
1837         }
1838
1839         dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
1840         NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
1841
1842         if (uid_wrapper_enabled()) {
1843                 setenv("UID_WRAPPER_MYUID", "1", 1);
1844         }
1845         dce_ctx->initial_euid = geteuid();
1846         if (uid_wrapper_enabled()) {
1847                 unsetenv("UID_WRAPPER_MYUID");
1848         }
1849
1850         dce_ctx->endpoint_list  = NULL;
1851         dce_ctx->lp_ctx = lp_ctx;
1852         dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
1853         NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
1854         dce_ctx->broken_connections = NULL;
1855
1856         for (i=0;endpoint_servers[i];i++) {
1857                 const struct dcesrv_endpoint_server *ep_server;
1858
1859                 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
1860                 if (!ep_server) {
1861                         DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
1862                         return NT_STATUS_INTERNAL_ERROR;
1863                 }
1864
1865                 status = ep_server->init_server(dce_ctx, ep_server);
1866                 if (!NT_STATUS_IS_OK(status)) {
1867                         DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
1868                                 nt_errstr(status)));
1869                         return status;
1870                 }
1871         }
1872
1873         *_dce_ctx = dce_ctx;
1874         return NT_STATUS_OK;
1875 }
1876
1877 /* the list of currently registered DCERPC endpoint servers.
1878  */
1879 static struct ep_server {
1880         struct dcesrv_endpoint_server *ep_server;
1881 } *ep_servers = NULL;
1882 static int num_ep_servers;
1883
1884 /*
1885   register a DCERPC endpoint server. 
1886
1887   The 'name' can be later used by other backends to find the operations
1888   structure for this backend.  
1889
1890   The 'type' is used to specify whether this is for a disk, printer or IPC$ share
1891 */
1892 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const void *_ep_server)
1893 {
1894         const struct dcesrv_endpoint_server *ep_server = _ep_server;
1895         
1896         if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1897                 /* its already registered! */
1898                 DEBUG(0,("DCERPC endpoint server '%s' already registered\n", 
1899                          ep_server->name));
1900                 return NT_STATUS_OBJECT_NAME_COLLISION;
1901         }
1902
1903         ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1904         if (!ep_servers) {
1905                 smb_panic("out of memory in dcerpc_register");
1906         }
1907
1908         ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1909         ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1910
1911         num_ep_servers++;
1912
1913         DEBUG(3,("DCERPC endpoint server '%s' registered\n", 
1914                  ep_server->name));
1915
1916         return NT_STATUS_OK;
1917 }
1918
1919 /*
1920   return the operations structure for a named backend of the specified type
1921 */
1922 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1923 {
1924         int i;
1925
1926         for (i=0;i<num_ep_servers;i++) {
1927                 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1928                         return ep_servers[i].ep_server;
1929                 }
1930         }
1931
1932         return NULL;
1933 }
1934
1935 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1936 {
1937         static bool initialized;
1938 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1939         STATIC_dcerpc_server_MODULES_PROTO;
1940         init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1941         init_module_fn *shared_init;
1942
1943         if (initialized) {
1944                 return;
1945         }
1946         initialized = true;
1947
1948         shared_init = load_samba_modules(NULL, "dcerpc_server");
1949
1950         run_init_functions(static_init);
1951         run_init_functions(shared_init);
1952
1953         talloc_free(shared_init);
1954 }
1955
1956 /*
1957   return the DCERPC module version, and the size of some critical types
1958   This can be used by endpoint server modules to either detect compilation errors, or provide
1959   multiple implementations for different smbd compilation options in one module
1960 */
1961 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1962 {
1963         static const struct dcesrv_critical_sizes critical_sizes = {
1964                 DCERPC_MODULE_VERSION,
1965                 sizeof(struct dcesrv_context),
1966                 sizeof(struct dcesrv_endpoint),
1967                 sizeof(struct dcesrv_endpoint_server),
1968                 sizeof(struct dcesrv_interface),
1969                 sizeof(struct dcesrv_if_list),
1970                 sizeof(struct dcesrv_connection),
1971                 sizeof(struct dcesrv_call_state),
1972                 sizeof(struct dcesrv_auth),
1973                 sizeof(struct dcesrv_handle)
1974         };
1975
1976         return &critical_sizes;
1977 }
1978
1979 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
1980 {
1981         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
1982         struct stream_connection *srv_conn;
1983         srv_conn = talloc_get_type(dce_conn->transport.private_data,
1984                                    struct stream_connection);
1985
1986         dce_conn->allow_bind = false;
1987         dce_conn->allow_auth3 = false;
1988         dce_conn->allow_alter = false;
1989         dce_conn->allow_request = false;
1990
1991         if (dce_conn->pending_call_list == NULL) {
1992                 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
1993
1994                 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
1995                 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
1996                 return;
1997         }
1998
1999         if (dce_conn->terminate != NULL) {
2000                 return;
2001         }
2002
2003         DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
2004                  reason));
2005         dce_conn->terminate = talloc_strdup(dce_conn, reason);
2006         if (dce_conn->terminate == NULL) {
2007                 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
2008         }
2009         DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2010 }
2011
2012 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2013 {
2014         struct dcesrv_connection *cur, *next;
2015
2016         next = dce_ctx->broken_connections;
2017         while (next != NULL) {
2018                 cur = next;
2019                 next = cur->next;
2020
2021                 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2022                         struct dcesrv_connection_context *context_cur, *context_next;
2023
2024                         context_next = cur->contexts;
2025                         while (context_next != NULL) {
2026                                 context_cur = context_next;
2027                                 context_next = context_cur->next;
2028
2029                                 dcesrv_connection_context_destructor(context_cur);
2030                         }
2031                 }
2032
2033                 dcesrv_terminate_connection(cur, cur->terminate);
2034         }
2035 }
2036
2037 /* We need this include to be able to compile on some plateforms
2038  * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2039  * correctly.
2040  * It has to be that deep because otherwise we have a conflict on
2041  * const struct dcesrv_interface declaration.
2042  * This is mostly due to socket_wrapper defining #define bind swrap_bind
2043  * which conflict with the bind used before.
2044  */
2045 #include "system/network.h"
2046
2047 struct dcesrv_sock_reply_state {
2048         struct dcesrv_connection *dce_conn;
2049         struct dcesrv_call_state *call;
2050         struct iovec iov;
2051 };
2052
2053 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2054 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2055
2056 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2057 {
2058         struct dcesrv_call_state *call;
2059
2060         call = dce_conn->call_list;
2061         if (!call || !call->replies) {
2062                 return;
2063         }
2064
2065         while (call->replies) {
2066                 struct data_blob_list_item *rep = call->replies;
2067                 struct dcesrv_sock_reply_state *substate;
2068                 struct tevent_req *subreq;
2069
2070                 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2071                 if (!substate) {
2072                         dcesrv_terminate_connection(dce_conn, "no memory");
2073                         return;
2074                 }
2075
2076                 substate->dce_conn = dce_conn;
2077                 substate->call = NULL;
2078
2079                 DLIST_REMOVE(call->replies, rep);
2080
2081                 if (call->replies == NULL && call->terminate_reason == NULL) {
2082                         substate->call = call;
2083                 }
2084
2085                 substate->iov.iov_base = (void *) rep->blob.data;
2086                 substate->iov.iov_len = rep->blob.length;
2087
2088                 subreq = tstream_writev_queue_send(substate,
2089                                                    dce_conn->event_ctx,
2090                                                    dce_conn->stream,
2091                                                    dce_conn->send_queue,
2092                                                    &substate->iov, 1);
2093                 if (!subreq) {
2094                         dcesrv_terminate_connection(dce_conn, "no memory");
2095                         return;
2096                 }
2097                 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2098                                         substate);
2099         }
2100
2101         if (call->terminate_reason != NULL) {
2102                 struct tevent_req *subreq;
2103
2104                 subreq = tevent_queue_wait_send(call,
2105                                                 dce_conn->event_ctx,
2106                                                 dce_conn->send_queue);
2107                 if (!subreq) {
2108                         dcesrv_terminate_connection(dce_conn, __location__);
2109                         return;
2110                 }
2111                 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2112                                         call);
2113         }
2114
2115         DLIST_REMOVE(call->conn->call_list, call);
2116         call->list = DCESRV_LIST_NONE;
2117 }
2118
2119 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2120 {
2121         struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2122                                                 struct dcesrv_sock_reply_state);
2123         int ret;
2124         int sys_errno;
2125         NTSTATUS status;
2126         struct dcesrv_call_state *call = substate->call;
2127
2128         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2129         TALLOC_FREE(subreq);
2130         if (ret == -1) {
2131                 status = map_nt_error_from_unix_common(sys_errno);
2132                 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2133                 return;
2134         }
2135
2136         talloc_free(substate);
2137         if (call) {
2138                 talloc_free(call);
2139         }
2140 }
2141
2142 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2143
2144 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2145 {
2146         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2147                                                 struct dcesrv_call_state);
2148         bool ok;
2149         struct timeval tv;
2150
2151         /* make sure we stop send queue before removing subreq */
2152         tevent_queue_stop(call->conn->send_queue);
2153
2154         ok = tevent_queue_wait_recv(subreq);
2155         TALLOC_FREE(subreq);
2156         if (!ok) {
2157                 dcesrv_terminate_connection(call->conn, __location__);
2158                 return;
2159         }
2160
2161         /* disconnect after 200 usecs */
2162         tv = timeval_current_ofs_usec(200);
2163         subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2164         if (subreq == NULL) {
2165                 dcesrv_terminate_connection(call->conn, __location__);
2166                 return;
2167         }
2168         tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2169                                 call);
2170 }
2171
2172 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2173 {
2174         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2175                                                 struct dcesrv_call_state);
2176         bool ok;
2177
2178         ok = tevent_wakeup_recv(subreq);
2179         TALLOC_FREE(subreq);
2180         if (!ok) {
2181                 dcesrv_terminate_connection(call->conn, __location__);
2182                 return;
2183         }
2184
2185         dcesrv_terminate_connection(call->conn, call->terminate_reason);
2186 }
2187
2188 struct dcesrv_socket_context {
2189         const struct dcesrv_endpoint *endpoint;
2190         struct dcesrv_context *dcesrv_ctx;
2191 };
2192
2193
2194 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2195
2196 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2197 {
2198         NTSTATUS status;
2199         struct dcesrv_socket_context *dcesrv_sock = 
2200                 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2201         enum dcerpc_transport_t transport =
2202                 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2203         struct dcesrv_connection *dcesrv_conn = NULL;
2204         int ret;
2205         struct tevent_req *subreq;
2206         struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2207
2208         dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2209
2210         if (!srv_conn->session_info) {
2211                 status = auth_anonymous_session_info(srv_conn,
2212                                                      lp_ctx,
2213                                                      &srv_conn->session_info);
2214                 if (!NT_STATUS_IS_OK(status)) {
2215                         DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2216                                 nt_errstr(status)));
2217                         stream_terminate_connection(srv_conn, nt_errstr(status));
2218                         return;
2219                 }
2220         }
2221
2222         status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2223                                          srv_conn,
2224                                          dcesrv_sock->endpoint,
2225                                          srv_conn->session_info,
2226                                          srv_conn->event.ctx,
2227                                          srv_conn->msg_ctx,
2228                                          srv_conn->server_id,
2229                                          DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2230                                          &dcesrv_conn);
2231         if (!NT_STATUS_IS_OK(status)) {
2232                 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
2233                         nt_errstr(status)));
2234                 stream_terminate_connection(srv_conn, nt_errstr(status));
2235                 return;
2236         }
2237
2238         dcesrv_conn->transport.private_data             = srv_conn;
2239         dcesrv_conn->transport.report_output_data       = dcesrv_sock_report_output_data;
2240
2241         TALLOC_FREE(srv_conn->event.fde);
2242
2243         dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2244         if (!dcesrv_conn->send_queue) {
2245                 status = NT_STATUS_NO_MEMORY;
2246                 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2247                         nt_errstr(status)));
2248                 stream_terminate_connection(srv_conn, nt_errstr(status));
2249                 return;
2250         }
2251
2252         if (transport == NCACN_NP) {
2253                 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2254                 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2255                                                   &srv_conn->tstream);
2256         } else {
2257                 ret = tstream_bsd_existing_socket(dcesrv_conn,
2258                                                   socket_get_fd(srv_conn->socket),
2259                                                   &dcesrv_conn->stream);
2260                 if (ret == -1) {
2261                         status = map_nt_error_from_unix_common(errno);
2262                         DEBUG(0, ("dcesrv_sock_accept: "
2263                                   "failed to setup tstream: %s\n",
2264                                   nt_errstr(status)));
2265                         stream_terminate_connection(srv_conn, nt_errstr(status));
2266                         return;
2267                 }
2268                 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2269         }
2270
2271         dcesrv_conn->local_address = srv_conn->local_address;
2272         dcesrv_conn->remote_address = srv_conn->remote_address;
2273
2274         if (transport == NCALRPC) {
2275                 uid_t uid;
2276                 gid_t gid;
2277                 int sock_fd;
2278
2279                 sock_fd = socket_get_fd(srv_conn->socket);
2280                 if (sock_fd == -1) {
2281                         stream_terminate_connection(
2282                                 srv_conn, "socket_get_fd failed\n");
2283                         return;
2284                 }
2285
2286                 ret = getpeereid(sock_fd, &uid, &gid);
2287                 if (ret == -1) {
2288                         status = map_nt_error_from_unix_common(errno);
2289                         DEBUG(0, ("dcesrv_sock_accept: "
2290                                   "getpeereid() failed for NCALRPC: %s\n",
2291                                   nt_errstr(status)));
2292                         stream_terminate_connection(srv_conn, nt_errstr(status));
2293                         return;
2294                 }
2295                 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2296                         struct tsocket_address *r = NULL;
2297
2298                         ret = tsocket_address_unix_from_path(dcesrv_conn,
2299                                                              "/root/ncalrpc_as_system",
2300                                                              &r);
2301                         if (ret == -1) {
2302                                 status = map_nt_error_from_unix_common(errno);
2303                                 DEBUG(0, ("dcesrv_sock_accept: "
2304                                           "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2305                                           nt_errstr(status)));
2306                                 stream_terminate_connection(srv_conn, nt_errstr(status));
2307                                 return;
2308                         }
2309                         dcesrv_conn->remote_address = r;
2310                 }
2311         }
2312
2313         srv_conn->private_data = dcesrv_conn;
2314
2315         irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2316
2317         subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2318                                                dcesrv_conn->event_ctx,
2319                                                dcesrv_conn->stream);
2320         if (!subreq) {
2321                 status = NT_STATUS_NO_MEMORY;
2322                 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2323                         nt_errstr(status)));
2324                 stream_terminate_connection(srv_conn, nt_errstr(status));
2325                 return;
2326         }
2327         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2328
2329         return;
2330 }
2331
2332 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2333 {
2334         struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2335                                              struct dcesrv_connection);
2336         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2337         struct ncacn_packet *pkt;
2338         DATA_BLOB buffer;
2339         NTSTATUS status;
2340
2341         if (dce_conn->terminate) {
2342                 /*
2343                  * if the current connection is broken
2344                  * we need to clean it up before any other connection
2345                  */
2346                 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2347                 dcesrv_cleanup_broken_connections(dce_ctx);
2348                 return;
2349         }
2350
2351         dcesrv_cleanup_broken_connections(dce_ctx);
2352
2353         status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2354                                                &pkt, &buffer);
2355         TALLOC_FREE(subreq);
2356         if (!NT_STATUS_IS_OK(status)) {
2357                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2358                 return;
2359         }
2360
2361         status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2362         if (!NT_STATUS_IS_OK(status)) {
2363                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2364                 return;
2365         }
2366
2367         subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2368                                                dce_conn->event_ctx,
2369                                                dce_conn->stream);
2370         if (!subreq) {
2371                 status = NT_STATUS_NO_MEMORY;
2372                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2373                 return;
2374         }
2375         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2376 }
2377
2378 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2379 {
2380         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2381                                              struct dcesrv_connection);
2382         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2383 }
2384
2385 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2386 {
2387         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2388                                              struct dcesrv_connection);
2389         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2390 }
2391
2392
2393 static const struct stream_server_ops dcesrv_stream_ops = {
2394         .name                   = "rpc",
2395         .accept_connection      = dcesrv_sock_accept,
2396         .recv_handler           = dcesrv_sock_recv,
2397         .send_handler           = dcesrv_sock_send,
2398 };
2399
2400 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 
2401                                    struct loadparm_context *lp_ctx,
2402                                    struct dcesrv_endpoint *e,
2403                             struct tevent_context *event_ctx, const struct model_ops *model_ops)
2404 {
2405         struct dcesrv_socket_context *dcesrv_sock;
2406         uint16_t port = 1;
2407         NTSTATUS status;
2408         const char *endpoint;
2409
2410         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2411         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2412
2413         /* remember the endpoint of this socket */
2414         dcesrv_sock->endpoint           = e;
2415         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2416
2417         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2418
2419         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2420                                      model_ops, &dcesrv_stream_ops, 
2421                                      "unix", endpoint, &port,
2422                                      lpcfg_socket_options(lp_ctx),
2423                                      dcesrv_sock);
2424         if (!NT_STATUS_IS_OK(status)) {
2425                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2426                          endpoint, nt_errstr(status)));
2427         }
2428
2429         return status;
2430 }
2431
2432 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 
2433                                       struct loadparm_context *lp_ctx,
2434                                       struct dcesrv_endpoint *e,
2435                                       struct tevent_context *event_ctx, const struct model_ops *model_ops)
2436 {
2437         struct dcesrv_socket_context *dcesrv_sock;
2438         uint16_t port = 1;
2439         char *full_path;
2440         NTSTATUS status;
2441         const char *endpoint;
2442
2443         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2444
2445         if (endpoint == NULL) {
2446                 /*
2447                  * No identifier specified: use DEFAULT.
2448                  *
2449                  * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2450                  * no endpoint and let the epmapper worry about it.
2451                  */
2452                 endpoint = "DEFAULT";
2453                 status = dcerpc_binding_set_string_option(e->ep_description,
2454                                                           "endpoint",
2455                                                           endpoint);
2456                 if (!NT_STATUS_IS_OK(status)) {
2457                         DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2458                                   nt_errstr(status)));
2459                         return status;
2460                 }
2461         }
2462
2463         full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2464                                     endpoint);
2465
2466         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2467         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2468
2469         /* remember the endpoint of this socket */
2470         dcesrv_sock->endpoint           = e;
2471         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2472
2473         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2474                                      model_ops, &dcesrv_stream_ops, 
2475                                      "unix", full_path, &port, 
2476                                      lpcfg_socket_options(lp_ctx),
2477                                      dcesrv_sock);
2478         if (!NT_STATUS_IS_OK(status)) {
2479                 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2480                          endpoint, full_path, nt_errstr(status)));
2481         }
2482         return status;
2483 }
2484
2485 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2486                                  struct loadparm_context *lp_ctx,
2487                                  struct dcesrv_endpoint *e,
2488                                  struct tevent_context *event_ctx, const struct model_ops *model_ops)
2489 {
2490         struct dcesrv_socket_context *dcesrv_sock;
2491         NTSTATUS status;
2492         const char *endpoint;
2493
2494         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2495         if (endpoint == NULL) {
2496                 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2497                 return NT_STATUS_INVALID_PARAMETER;
2498         }
2499
2500         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2501         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2502
2503         /* remember the endpoint of this socket */
2504         dcesrv_sock->endpoint           = e;
2505         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2506
2507         status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2508                                           model_ops, &dcesrv_stream_ops,
2509                                           endpoint,
2510                                           dcesrv_sock);
2511         if (!NT_STATUS_IS_OK(status)) {
2512                 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2513                          endpoint, nt_errstr(status)));
2514                 return status;
2515         }
2516
2517         return NT_STATUS_OK;
2518 }
2519
2520 /*
2521   add a socket address to the list of events, one event per dcerpc endpoint
2522 */
2523 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2524                                          struct tevent_context *event_ctx, const struct model_ops *model_ops,
2525                                          const char *address)
2526 {
2527         struct dcesrv_socket_context *dcesrv_sock;
2528         uint16_t port = 0;
2529         NTSTATUS status;
2530         const char *endpoint;
2531         char port_str[6];
2532
2533         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2534         if (endpoint != NULL) {
2535                 port = atoi(endpoint);
2536         }
2537
2538         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2539         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2540
2541         /* remember the endpoint of this socket */
2542         dcesrv_sock->endpoint           = e;
2543         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2544
2545         status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2546                                      model_ops, &dcesrv_stream_ops, 
2547                                      "ip", address, &port,
2548                                      lpcfg_socket_options(dce_ctx->lp_ctx),
2549                                      dcesrv_sock);
2550         if (!NT_STATUS_IS_OK(status)) {
2551                 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n", 
2552                          address, port, nt_errstr(status)));
2553                 return status;
2554         }
2555
2556         snprintf(port_str, sizeof(port_str), "%u", port);
2557
2558         status = dcerpc_binding_set_string_option(e->ep_description,
2559                                                   "endpoint", port_str);
2560         if (!NT_STATUS_IS_OK(status)) {
2561                 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2562                          port_str, nt_errstr(status)));
2563                 return status;
2564         }
2565
2566         return NT_STATUS_OK;
2567 }
2568
2569 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2570
2571 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 
2572                                   struct loadparm_context *lp_ctx,
2573                                   struct dcesrv_endpoint *e,
2574                                   struct tevent_context *event_ctx, const struct model_ops *model_ops)
2575 {
2576         NTSTATUS status;
2577
2578         /* Add TCP/IP sockets */
2579         if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2580                 int num_interfaces;
2581                 int i;
2582                 struct interface *ifaces;
2583
2584                 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2585
2586                 num_interfaces = iface_list_count(ifaces);
2587                 for(i = 0; i < num_interfaces; i++) {
2588                         const char *address = iface_list_n_ip(ifaces, i);
2589                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2590                         NT_STATUS_NOT_OK_RETURN(status);
2591                 }
2592         } else {
2593                 char **wcard;
2594                 int i;
2595                 int num_binds = 0;
2596                 wcard = iface_list_wildcard(dce_ctx);
2597                 NT_STATUS_HAVE_NO_MEMORY(wcard);
2598                 for (i=0; wcard[i]; i++) {
2599                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2600                         if (NT_STATUS_IS_OK(status)) {
2601                                 num_binds++;
2602                         }
2603                 }
2604                 talloc_free(wcard);
2605                 if (num_binds == 0) {
2606                         return NT_STATUS_INVALID_PARAMETER_MIX;
2607                 }
2608         }
2609
2610         return NT_STATUS_OK;
2611 }
2612
2613 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2614                        struct loadparm_context *lp_ctx,
2615                        struct dcesrv_endpoint *e,
2616                        struct tevent_context *event_ctx,
2617                        const struct model_ops *model_ops)
2618 {
2619         enum dcerpc_transport_t transport =
2620                 dcerpc_binding_get_transport(e->ep_description);
2621
2622         switch (transport) {
2623         case NCACN_UNIX_STREAM:
2624                 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2625
2626         case NCALRPC:
2627                 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2628
2629         case NCACN_IP_TCP:
2630                 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2631
2632         case NCACN_NP:
2633                 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2634
2635         default:
2636                 return NT_STATUS_NOT_SUPPORTED;
2637         }
2638 }
2639
2640
2641 /**
2642  * retrieve credentials from a dce_call
2643  */
2644 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2645 {
2646         return dce_call->conn->auth_state.session_info->credentials;
2647 }
2648
2649 /**
2650  * returns true if this is an authenticated call
2651  */
2652 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2653 {
2654         enum security_user_level level;
2655         level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2656         return level >= SECURITY_USER;
2657 }
2658
2659 /**
2660  * retrieve account_name for a dce_call
2661  */
2662 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2663 {
2664         return dce_call->context->conn->auth_state.session_info->info->account_name;
2665 }