CVE-2015-5370: s4:rpc_server: verify the protocol headers before processing pdus
[gd/samba-autobuild/.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 /* this is only used when the client asks for an unknown interface */
46 #define DUMMY_ASSOC_GROUP 0x0FFFFFFF
47
48 extern const struct dcesrv_interface dcesrv_mgmt_interface;
49
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(0,(__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                                                                    uint32_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->max_recv_frag = 5840;
412         p->max_xmit_frag = 5840;
413
414         *_p = p;
415         return NT_STATUS_OK;
416 }
417
418 /*
419   move a call from an existing linked list to the specified list. This
420   prevents bugs where we forget to remove the call from a previous
421   list when moving it.
422  */
423 static void dcesrv_call_set_list(struct dcesrv_call_state *call, 
424                                  enum dcesrv_call_list list)
425 {
426         switch (call->list) {
427         case DCESRV_LIST_NONE:
428                 break;
429         case DCESRV_LIST_CALL_LIST:
430                 DLIST_REMOVE(call->conn->call_list, call);
431                 break;
432         case DCESRV_LIST_FRAGMENTED_CALL_LIST:
433                 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
434                 break;
435         case DCESRV_LIST_PENDING_CALL_LIST:
436                 DLIST_REMOVE(call->conn->pending_call_list, call);
437                 break;
438         }
439         call->list = list;
440         switch (list) {
441         case DCESRV_LIST_NONE:
442                 break;
443         case DCESRV_LIST_CALL_LIST:
444                 DLIST_ADD_END(call->conn->call_list, call);
445                 break;
446         case DCESRV_LIST_FRAGMENTED_CALL_LIST:
447                 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
448                 break;
449         case DCESRV_LIST_PENDING_CALL_LIST:
450                 DLIST_ADD_END(call->conn->pending_call_list, call);
451                 break;
452         }
453 }
454
455 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
456                                          const char *reason)
457 {
458         if (call->conn->terminate != NULL) {
459                 return;
460         }
461
462         call->terminate_reason = talloc_strdup(call, reason);
463         if (call->terminate_reason == NULL) {
464                 call->terminate_reason = __location__;
465         }
466 }
467
468 /*
469   return a dcerpc bind_nak
470 */
471 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
472 {
473         struct ncacn_packet pkt;
474         struct dcerpc_bind_nak_version version;
475         struct data_blob_list_item *rep;
476         NTSTATUS status;
477         static const uint8_t _pad[3] = { 0, };
478
479         /*
480          * We add the call to the pending_call_list
481          * in order to defer the termination.
482          */
483         dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
484
485         /* setup a bind_nak */
486         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
487         pkt.auth_length = 0;
488         pkt.call_id = call->pkt.call_id;
489         pkt.ptype = DCERPC_PKT_BIND_NAK;
490         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
491         pkt.u.bind_nak.reject_reason = reason;
492         version.rpc_vers = 5;
493         version.rpc_vers_minor = 0;
494         pkt.u.bind_nak.num_versions = 1;
495         pkt.u.bind_nak.versions = &version;
496         pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
497
498         rep = talloc_zero(call, struct data_blob_list_item);
499         if (!rep) {
500                 return NT_STATUS_NO_MEMORY;
501         }
502
503         status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
504         if (!NT_STATUS_IS_OK(status)) {
505                 return status;
506         }
507
508         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
509
510         DLIST_ADD_END(call->replies, rep);
511         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
512
513         if (call->conn->call_list && call->conn->call_list->replies) {
514                 if (call->conn->transport.report_output_data) {
515                         call->conn->transport.report_output_data(call->conn);
516                 }
517         }
518
519         return NT_STATUS_OK;    
520 }
521
522 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
523                                  uint32_t fault_code)
524 {
525         /*
526          * We add the call to the pending_call_list
527          * in order to defer the termination.
528          */
529         dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
530
531         return dcesrv_fault_with_flags(call, fault_code,
532                                        DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
533 }
534
535 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
536 {
537         DLIST_REMOVE(c->conn->contexts, c);
538
539         if (c->iface && c->iface->unbind) {
540                 c->iface->unbind(c, c->iface);
541                 c->iface = NULL;
542         }
543
544         return 0;
545 }
546
547 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
548 {
549         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
550         const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
551         enum dcerpc_transport_t transport =
552                 dcerpc_binding_get_transport(endpoint->ep_description);
553         struct dcesrv_connection_context *context = dce_call->context;
554         const struct dcesrv_interface *iface = context->iface;
555
556         context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
557
558         if (transport == NCALRPC) {
559                 context->allow_connect = true;
560                 return;
561         }
562
563         /*
564          * allow overwrite per interface
565          * allow dcerpc auth level connect:<interface>
566          */
567         context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
568         context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
569                                         "allow dcerpc auth level connect",
570                                         iface->name,
571                                         context->allow_connect);
572 }
573
574 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
575                                                  const struct dcesrv_interface *iface)
576 {
577         if (dce_call->context == NULL) {
578                 return NT_STATUS_INTERNAL_ERROR;
579         }
580
581         dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
582         return NT_STATUS_OK;
583 }
584
585 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
586                                                const struct dcesrv_interface *iface)
587 {
588         if (dce_call->context == NULL) {
589                 return NT_STATUS_INTERNAL_ERROR;
590         }
591
592         dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
593         return NT_STATUS_OK;
594 }
595
596 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
597                                                        const struct dcesrv_interface *iface)
598 {
599         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
600         const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
601         enum dcerpc_transport_t transport =
602                 dcerpc_binding_get_transport(endpoint->ep_description);
603         struct dcesrv_connection_context *context = dce_call->context;
604
605         if (context == NULL) {
606                 return NT_STATUS_INTERNAL_ERROR;
607         }
608
609         if (transport == NCALRPC) {
610                 context->allow_connect = true;
611                 return NT_STATUS_OK;
612         }
613
614         /*
615          * allow overwrite per interface
616          * allow dcerpc auth level connect:<interface>
617          */
618         context->allow_connect = false;
619         context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
620                                         "allow dcerpc auth level connect",
621                                         iface->name,
622                                         context->allow_connect);
623         return NT_STATUS_OK;
624 }
625
626 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
627                                                       const struct dcesrv_interface *iface)
628 {
629         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
630         const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
631         enum dcerpc_transport_t transport =
632                 dcerpc_binding_get_transport(endpoint->ep_description);
633         struct dcesrv_connection_context *context = dce_call->context;
634
635         if (context == NULL) {
636                 return NT_STATUS_INTERNAL_ERROR;
637         }
638
639         if (transport == NCALRPC) {
640                 context->allow_connect = true;
641                 return NT_STATUS_OK;
642         }
643
644         /*
645          * allow overwrite per interface
646          * allow dcerpc auth level connect:<interface>
647          */
648         context->allow_connect = true;
649         context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
650                                         "allow dcerpc auth level connect",
651                                         iface->name,
652                                         context->allow_connect);
653         return NT_STATUS_OK;
654 }
655
656 /*
657   handle a bind request
658 */
659 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
660 {
661         uint32_t if_version, transfer_syntax_version;
662         struct GUID uuid, *transfer_syntax_uuid;
663         struct ncacn_packet pkt;
664         struct data_blob_list_item *rep;
665         NTSTATUS status;
666         uint32_t result=0, reason=0;
667         uint32_t context_id;
668         const struct dcesrv_interface *iface;
669         uint32_t extra_flags = 0;
670         uint16_t max_req = 0;
671         uint16_t max_rep = 0;
672         const char *ep_prefix = "";
673         const char *endpoint = NULL;
674
675         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
676                         DCERPC_PKT_BIND,
677                         call->pkt.u.bind.auth_info.length,
678                         0, /* required flags */
679                         DCERPC_PFC_FLAG_FIRST |
680                         DCERPC_PFC_FLAG_LAST |
681                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
682                         0x08 | /* this is not defined, but should be ignored */
683                         DCERPC_PFC_FLAG_CONC_MPX |
684                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
685                         DCERPC_PFC_FLAG_MAYBE |
686                         DCERPC_PFC_FLAG_OBJECT_UUID);
687         if (!NT_STATUS_IS_OK(status)) {
688                 return dcesrv_bind_nak(call,
689                         DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
690         }
691
692         /* max_recv_frag and max_xmit_frag result always in the same value! */
693         max_req = MIN(call->pkt.u.bind.max_xmit_frag,
694                       call->pkt.u.bind.max_recv_frag);
695         /*
696          * The values are between 2048 and 5840 tested against Windows 2012R2
697          * via ncacn_ip_tcp on port 135.
698          */
699         max_req = MAX(2048, max_req);
700         max_rep = MIN(max_req, call->conn->max_recv_frag);
701         /* They are truncated to an 8 byte boundary. */
702         max_rep &= 0xFFF8;
703
704         /* max_recv_frag and max_xmit_frag result always in the same value! */
705         call->conn->max_recv_frag = max_rep;
706         call->conn->max_xmit_frag = max_rep;
707
708         /*
709           if provided, check the assoc_group is valid
710          */
711         if (call->pkt.u.bind.assoc_group_id != 0 &&
712             lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","assoc group checking", true) &&
713             dcesrv_assoc_group_find(call->conn->dce_ctx, call->pkt.u.bind.assoc_group_id) == NULL) {
714                 return dcesrv_bind_nak(call, 0);        
715         }
716
717         if (call->pkt.u.bind.num_contexts < 1 ||
718             call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) {
719                 return dcesrv_bind_nak(call, 0);
720         }
721
722         context_id = call->pkt.u.bind.ctx_list[0].context_id;
723
724         /* you can't bind twice on one context */
725         if (dcesrv_find_context(call->conn, context_id) != NULL) {
726                 return dcesrv_bind_nak(call, 0);
727         }
728
729         if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version;
730         uuid = call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid;
731
732         transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].if_version;
733         transfer_syntax_uuid = &call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].uuid;
734         if (!GUID_equal(&ndr_transfer_syntax_ndr.uuid, transfer_syntax_uuid) != 0 ||
735             ndr_transfer_syntax_ndr.if_version != transfer_syntax_version) {
736                 char *uuid_str = GUID_string(call, transfer_syntax_uuid);
737                 /* we only do NDR encoded dcerpc */
738                 DEBUG(0,("Non NDR transfer syntax requested - %s\n", uuid_str));
739                 talloc_free(uuid_str);
740                 return dcesrv_bind_nak(call, 0);
741         }
742
743         iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
744         if (iface == NULL) {
745                 char *uuid_str = GUID_string(call, &uuid);
746                 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
747                 talloc_free(uuid_str);
748
749                 /* we don't know about that interface */
750                 result = DCERPC_BIND_PROVIDER_REJECT;
751                 reason = DCERPC_BIND_REASON_ASYNTAX;            
752         }
753
754         if (iface) {
755                 /* add this context to the list of available context_ids */
756                 struct dcesrv_connection_context *context = talloc_zero(call->conn,
757                                                                    struct dcesrv_connection_context);
758                 if (context == NULL) {
759                         return dcesrv_bind_nak(call, 0);
760                 }
761                 context->conn = call->conn;
762                 context->iface = iface;
763                 context->context_id = context_id;
764                 if (call->pkt.u.bind.assoc_group_id != 0) {
765                         context->assoc_group = dcesrv_assoc_group_reference(context,
766                                                                             call->conn->dce_ctx, 
767                                                                             call->pkt.u.bind.assoc_group_id);
768                 } else {
769                         context->assoc_group = dcesrv_assoc_group_new(context, call->conn->dce_ctx);
770                 }
771                 if (context->assoc_group == NULL) {
772                         talloc_free(context);
773                         return dcesrv_bind_nak(call, 0);
774                 }
775                 context->private_data = NULL;
776                 DLIST_ADD(call->conn->contexts, context);
777                 call->context = context;
778                 talloc_set_destructor(context, dcesrv_connection_context_destructor);
779
780                 dcesrv_prepare_context_auth(call);
781
782                 status = iface->bind(call, iface, if_version);
783                 if (!NT_STATUS_IS_OK(status)) {
784                         char *uuid_str = GUID_string(call, &uuid);
785                         DEBUG(2,("Request for dcerpc interface %s/%d rejected: %s\n",
786                                  uuid_str, if_version, nt_errstr(status)));
787                         talloc_free(uuid_str);
788                         /* we don't want to trigger the iface->unbind() hook */
789                         context->iface = NULL;
790                         talloc_free(call->context);
791                         call->context = NULL;
792                         return dcesrv_bind_nak(call, 0);
793                 }
794         }
795
796         if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
797             (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
798                 call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
799                 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
800         }
801
802         if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
803                 call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
804         }
805
806         /* handle any authentication that is being requested */
807         if (!dcesrv_auth_bind(call)) {
808                 talloc_free(call->context);
809                 call->context = NULL;
810                 return dcesrv_bind_nak(call, DCERPC_BIND_REASON_INVALID_AUTH_TYPE);
811         }
812
813         /* setup a bind_ack */
814         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
815         pkt.auth_length = 0;
816         pkt.call_id = call->pkt.call_id;
817         pkt.ptype = DCERPC_PKT_BIND_ACK;
818         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
819         pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
820         pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
821
822         /*
823           make it possible for iface->bind() to specify the assoc_group_id
824           This helps the openchange mapiproxy plugin to work correctly.
825           
826           metze
827         */
828         if (call->context) {
829                 pkt.u.bind_ack.assoc_group_id = call->context->assoc_group->id;
830         } else {
831                 pkt.u.bind_ack.assoc_group_id = DUMMY_ASSOC_GROUP;
832         }
833
834         if (iface) {
835                 endpoint = dcerpc_binding_get_string_option(
836                                 call->conn->endpoint->ep_description,
837                                 "endpoint");
838         }
839
840         if (endpoint == NULL) {
841                 endpoint = "";
842         }
843
844         if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
845                 /*
846                  * TODO: check if this is really needed
847                  *
848                  * Or if we should fix this in our idl files.
849                  */
850                 ep_prefix = "\\PIPE\\";
851                 endpoint += 6;
852         }
853
854         pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
855                                                            ep_prefix,
856                                                            endpoint);
857         if (pkt.u.bind_ack.secondary_address == NULL) {
858                 TALLOC_FREE(call->context);
859                 return NT_STATUS_NO_MEMORY;
860         }
861         pkt.u.bind_ack.num_results = 1;
862         pkt.u.bind_ack.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx);
863         if (!pkt.u.bind_ack.ctx_list) {
864                 talloc_free(call->context);
865                 call->context = NULL;
866                 return NT_STATUS_NO_MEMORY;
867         }
868         pkt.u.bind_ack.ctx_list[0].result = result;
869         pkt.u.bind_ack.ctx_list[0].reason.value = reason;
870         pkt.u.bind_ack.ctx_list[0].syntax = ndr_transfer_syntax_ndr;
871         pkt.u.bind_ack.auth_info = data_blob(NULL, 0);
872
873         status = dcesrv_auth_bind_ack(call, &pkt);
874         if (!NT_STATUS_IS_OK(status)) {
875                 talloc_free(call->context);
876                 call->context = NULL;
877                 return dcesrv_bind_nak(call, 0);
878         }
879
880         rep = talloc_zero(call, struct data_blob_list_item);
881         if (!rep) {
882                 talloc_free(call->context);
883                 call->context = NULL;
884                 return NT_STATUS_NO_MEMORY;
885         }
886
887         status = ncacn_push_auth(&rep->blob, call, &pkt,
888                                                          call->conn->auth_state.auth_info);
889         if (!NT_STATUS_IS_OK(status)) {
890                 talloc_free(call->context);
891                 call->context = NULL;
892                 return status;
893         }
894
895         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
896
897         DLIST_ADD_END(call->replies, rep);
898         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
899
900         if (call->conn->call_list && call->conn->call_list->replies) {
901                 if (call->conn->transport.report_output_data) {
902                         call->conn->transport.report_output_data(call->conn);
903                 }
904         }
905
906         return NT_STATUS_OK;
907 }
908
909
910 /*
911   handle a auth3 request
912 */
913 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
914 {
915         NTSTATUS status;
916
917         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
918                         DCERPC_PKT_AUTH3,
919                         call->pkt.u.auth3.auth_info.length,
920                         0, /* required flags */
921                         DCERPC_PFC_FLAG_FIRST |
922                         DCERPC_PFC_FLAG_LAST |
923                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
924                         0x08 | /* this is not defined, but should be ignored */
925                         DCERPC_PFC_FLAG_CONC_MPX |
926                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
927                         DCERPC_PFC_FLAG_MAYBE |
928                         DCERPC_PFC_FLAG_OBJECT_UUID);
929         if (!NT_STATUS_IS_OK(status)) {
930                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
931         }
932
933         /* handle the auth3 in the auth code */
934         if (!dcesrv_auth_auth3(call)) {
935                 return dcesrv_fault(call, DCERPC_FAULT_OTHER);
936         }
937
938         talloc_free(call);
939
940         /* we don't send a reply to a auth3 request, except by a
941            fault */
942         return NT_STATUS_OK;
943 }
944
945
946 /*
947   handle a bind request
948 */
949 static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_t context_id)
950 {
951         uint32_t if_version, transfer_syntax_version;
952         struct dcesrv_connection_context *context;
953         const struct dcesrv_interface *iface;
954         struct GUID uuid, *transfer_syntax_uuid;
955         NTSTATUS status;
956
957         if_version = call->pkt.u.alter.ctx_list[0].abstract_syntax.if_version;
958         uuid = call->pkt.u.alter.ctx_list[0].abstract_syntax.uuid;
959
960         transfer_syntax_version = call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].if_version;
961         transfer_syntax_uuid = &call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].uuid;
962         if (!GUID_equal(transfer_syntax_uuid, &ndr_transfer_syntax_ndr.uuid) ||
963             ndr_transfer_syntax_ndr.if_version != transfer_syntax_version) {
964                 /* we only do NDR encoded dcerpc */
965                 return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED;
966         }
967
968         iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
969         if (iface == NULL) {
970                 char *uuid_str = GUID_string(call, &uuid);
971                 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
972                 talloc_free(uuid_str);
973                 return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED;
974         }
975
976         /* add this context to the list of available context_ids */
977         context = talloc_zero(call->conn, struct dcesrv_connection_context);
978         if (context == NULL) {
979                 return NT_STATUS_NO_MEMORY;
980         }
981         context->conn = call->conn;
982         context->iface = iface;
983         context->context_id = context_id;
984         if (call->pkt.u.alter.assoc_group_id != 0) {
985                 context->assoc_group = dcesrv_assoc_group_reference(context,
986                                                                     call->conn->dce_ctx, 
987                                                                     call->pkt.u.alter.assoc_group_id);
988         } else {
989                 context->assoc_group = dcesrv_assoc_group_new(context, call->conn->dce_ctx);
990         }
991         if (context->assoc_group == NULL) {
992                 talloc_free(context);
993                 call->context = NULL;
994                 return NT_STATUS_NO_MEMORY;
995         }
996         context->private_data = NULL;
997         DLIST_ADD(call->conn->contexts, context);
998         call->context = context;
999         talloc_set_destructor(context, dcesrv_connection_context_destructor);
1000
1001         dcesrv_prepare_context_auth(call);
1002
1003         status = iface->bind(call, iface, if_version);
1004         if (!NT_STATUS_IS_OK(status)) {
1005                 /* we don't want to trigger the iface->unbind() hook */
1006                 context->iface = NULL;
1007                 talloc_free(context);
1008                 call->context = NULL;
1009                 return status;
1010         }
1011
1012         return NT_STATUS_OK;
1013 }
1014
1015 /* setup and send an alter_resp */
1016 static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call,
1017                                 uint32_t result,
1018                                 uint32_t reason)
1019 {
1020         struct ncacn_packet pkt;
1021         uint32_t extra_flags = 0;
1022         struct data_blob_list_item *rep = NULL;
1023         NTSTATUS status;
1024
1025         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1026         pkt.auth_length = 0;
1027         pkt.call_id = call->pkt.call_id;
1028         pkt.ptype = DCERPC_PKT_ALTER_RESP;
1029         if (result == 0) {
1030                 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1031                                 call->context->conn->state_flags &
1032                                         DCESRV_CALL_STATE_FLAG_MULTIPLEXED) {
1033                         extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1034                 }
1035                 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1036                         call->context->conn->state_flags |=
1037                                 DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1038                 }
1039         }
1040         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1041         pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1042         pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1043         if (result == 0) {
1044                 pkt.u.alter_resp.assoc_group_id = call->context->assoc_group->id;
1045         } else {
1046                 pkt.u.alter_resp.assoc_group_id = 0;
1047         }
1048         pkt.u.alter_resp.num_results = 1;
1049         pkt.u.alter_resp.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx);
1050         if (!pkt.u.alter_resp.ctx_list) {
1051                 return NT_STATUS_NO_MEMORY;
1052         }
1053         pkt.u.alter_resp.ctx_list[0].result = result;
1054         pkt.u.alter_resp.ctx_list[0].reason.value = reason;
1055         pkt.u.alter_resp.ctx_list[0].syntax = ndr_transfer_syntax_ndr;
1056         pkt.u.alter_resp.auth_info = data_blob(NULL, 0);
1057         pkt.u.alter_resp.secondary_address = "";
1058
1059         status = dcesrv_auth_alter_ack(call, &pkt);
1060         if (!NT_STATUS_IS_OK(status)) {
1061                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)
1062                     || NT_STATUS_EQUAL(status, NT_STATUS_LOGON_FAILURE)
1063                     || NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)
1064                     || NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1065                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1066                 }
1067                 return dcesrv_fault(call, 0);
1068         }
1069
1070         rep = talloc_zero(call, struct data_blob_list_item);
1071         if (!rep) {
1072                 return NT_STATUS_NO_MEMORY;
1073         }
1074
1075         status = ncacn_push_auth(&rep->blob, call, &pkt, call->conn->auth_state.auth_info);
1076         if (!NT_STATUS_IS_OK(status)) {
1077                 return status;
1078         }
1079
1080         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1081
1082         DLIST_ADD_END(call->replies, rep);
1083         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1084
1085         if (call->conn->call_list && call->conn->call_list->replies) {
1086                 if (call->conn->transport.report_output_data) {
1087                         call->conn->transport.report_output_data(call->conn);
1088                 }
1089         }
1090
1091         return NT_STATUS_OK;
1092 }
1093
1094 /*
1095   handle a alter context request
1096 */
1097 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1098 {
1099         NTSTATUS status;
1100         uint32_t context_id;
1101
1102         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1103                         DCERPC_PKT_ALTER,
1104                         call->pkt.u.alter.auth_info.length,
1105                         0, /* required flags */
1106                         DCERPC_PFC_FLAG_FIRST |
1107                         DCERPC_PFC_FLAG_LAST |
1108                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1109                         0x08 | /* this is not defined, but should be ignored */
1110                         DCERPC_PFC_FLAG_CONC_MPX |
1111                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1112                         DCERPC_PFC_FLAG_MAYBE |
1113                         DCERPC_PFC_FLAG_OBJECT_UUID);
1114         if (!NT_STATUS_IS_OK(status)) {
1115                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1116         }
1117
1118         /* handle any authentication that is being requested */
1119         if (!dcesrv_auth_alter(call)) {
1120                 /* TODO: work out the right reject code */
1121                 return dcesrv_alter_resp(call,
1122                                 DCERPC_BIND_PROVIDER_REJECT,
1123                                 DCERPC_BIND_REASON_ASYNTAX);
1124         }
1125
1126         context_id = call->pkt.u.alter.ctx_list[0].context_id;
1127
1128         /* see if they are asking for a new interface */
1129         call->context = dcesrv_find_context(call->conn, context_id);
1130         if (!call->context) {
1131                 status = dcesrv_alter_new_context(call, context_id);
1132                 if (!NT_STATUS_IS_OK(status)) {
1133                         return dcesrv_alter_resp(call,
1134                                 DCERPC_BIND_PROVIDER_REJECT,
1135                                 DCERPC_BIND_REASON_ASYNTAX);
1136                 }
1137         }
1138
1139         if (call->pkt.u.alter.assoc_group_id != 0 &&
1140             lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","assoc group checking", true) &&
1141             call->pkt.u.alter.assoc_group_id != call->context->assoc_group->id) {
1142                 DEBUG(0,(__location__ ": Failed attempt to use new assoc_group in alter context (0x%08x 0x%08x)\n",
1143                          call->context->assoc_group->id, call->pkt.u.alter.assoc_group_id));
1144                 /* TODO: can they ask for a new association group? */
1145                 return dcesrv_alter_resp(call,
1146                                 DCERPC_BIND_PROVIDER_REJECT,
1147                                 DCERPC_BIND_REASON_ASYNTAX);
1148         }
1149
1150         return dcesrv_alter_resp(call,
1151                                 DCERPC_BIND_ACK_RESULT_ACCEPTANCE,
1152                                 DCERPC_BIND_ACK_REASON_NOT_SPECIFIED);
1153 }
1154
1155 /*
1156   possibly save the call for inspection with ndrdump
1157  */
1158 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1159 {
1160 #ifdef DEVELOPER
1161         char *fname;
1162         const char *dump_dir;
1163         dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1164         if (!dump_dir) {
1165                 return;
1166         }
1167         fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1168                                 dump_dir,
1169                                 call->context->iface->name,
1170                                 call->pkt.u.request.opnum,
1171                                 why);
1172         if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1173                 DEBUG(0,("RPC SAVED %s\n", fname));
1174         }
1175         talloc_free(fname);
1176 #endif
1177 }
1178
1179 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1180 {
1181         TALLOC_CTX *frame = talloc_stackframe();
1182         const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1183                 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1184         const struct dcerpc_sec_vt_pcontext pcontext = {
1185                 .abstract_syntax = call->context->iface->syntax_id,
1186                 .transfer_syntax = ndr_transfer_syntax_ndr,
1187         };
1188         const struct dcerpc_sec_vt_header2 header2 =
1189                 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1190         enum ndr_err_code ndr_err;
1191         struct dcerpc_sec_verification_trailer *vt = NULL;
1192         NTSTATUS status = NT_STATUS_OK;
1193         bool ok;
1194
1195         SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1196
1197         ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1198                                                           frame, &vt);
1199         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1200                 status = ndr_map_error2ntstatus(ndr_err);
1201                 goto done;
1202         }
1203
1204         ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1205                                                    &pcontext, &header2);
1206         if (!ok) {
1207                 status = NT_STATUS_ACCESS_DENIED;
1208                 goto done;
1209         }
1210 done:
1211         TALLOC_FREE(frame);
1212         return status;
1213 }
1214
1215 /*
1216   handle a dcerpc request packet
1217 */
1218 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1219 {
1220         const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1221         enum dcerpc_transport_t transport =
1222                 dcerpc_binding_get_transport(endpoint->ep_description);
1223         struct ndr_pull *pull;
1224         NTSTATUS status;
1225         struct dcesrv_connection_context *context;
1226
1227         /* if authenticated, and the mech we use can't do async replies, don't use them... */
1228         if (call->conn->auth_state.gensec_security && 
1229             !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1230                 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1231         }
1232
1233         context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id);
1234         if (context == NULL) {
1235                 return dcesrv_fault(call, DCERPC_FAULT_UNK_IF);
1236         }
1237
1238         switch (call->conn->auth_state.auth_level) {
1239         case DCERPC_AUTH_LEVEL_NONE:
1240         case DCERPC_AUTH_LEVEL_INTEGRITY:
1241         case DCERPC_AUTH_LEVEL_PRIVACY:
1242                 break;
1243         default:
1244                 if (!context->allow_connect) {
1245                         char *addr;
1246
1247                         addr = tsocket_address_string(call->conn->remote_address,
1248                                                       call);
1249
1250                         DEBUG(2, ("%s: restrict auth_level_connect access "
1251                                   "to [%s] with auth[type=0x%x,level=0x%x] "
1252                                   "on [%s] from [%s]\n",
1253                                   __func__, context->iface->name,
1254                                   call->conn->auth_state.auth_type,
1255                                   call->conn->auth_state.auth_level,
1256                                   derpc_transport_string_by_transport(transport),
1257                                   addr));
1258                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1259                 }
1260                 break;
1261         }
1262
1263         if (call->conn->auth_state.auth_level < context->min_auth_level) {
1264                 char *addr;
1265
1266                 addr = tsocket_address_string(call->conn->remote_address, call);
1267
1268                 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1269                           "to [%s] with auth[type=0x%x,level=0x%x] "
1270                           "on [%s] from [%s]\n",
1271                           __func__,
1272                           context->min_auth_level,
1273                           context->iface->name,
1274                           call->conn->auth_state.auth_type,
1275                           call->conn->auth_state.auth_level,
1276                           derpc_transport_string_by_transport(transport),
1277                           addr));
1278                 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1279         }
1280
1281         pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1282         NT_STATUS_HAVE_NO_MEMORY(pull);
1283
1284         pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1285
1286         call->context   = context;
1287         call->ndr_pull  = pull;
1288
1289         if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1290                 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1291         }
1292
1293         status = dcesrv_check_verification_trailer(call);
1294         if (!NT_STATUS_IS_OK(status)) {
1295                 uint32_t faultcode = DCERPC_FAULT_OTHER;
1296                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1297                         faultcode = DCERPC_FAULT_ACCESS_DENIED;
1298                 }
1299                 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1300                            nt_errstr(status)));
1301                 return dcesrv_fault(call, faultcode);
1302         }
1303
1304         /* unravel the NDR for the packet */
1305         status = context->iface->ndr_pull(call, call, pull, &call->r);
1306         if (!NT_STATUS_IS_OK(status)) {
1307                 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1308                         /* we got an unknown call */
1309                         DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1310                                  call->pkt.u.request.opnum, context->iface->name));
1311                         dcesrv_save_call(call, "unknown");
1312                 } else {
1313                         dcesrv_save_call(call, "pullfail");
1314                 }
1315                 return dcesrv_fault(call, call->fault_code);
1316         }
1317
1318         if (pull->offset != pull->data_size) {
1319                 dcesrv_save_call(call, "extrabytes");
1320                 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n", 
1321                          pull->data_size - pull->offset));
1322         }
1323
1324         /* call the dispatch function */
1325         status = context->iface->dispatch(call, call, call->r);
1326         if (!NT_STATUS_IS_OK(status)) {
1327                 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1328                          context->iface->name, 
1329                          call->pkt.u.request.opnum,
1330                          dcerpc_errstr(pull, call->fault_code)));
1331                 return dcesrv_fault(call, call->fault_code);
1332         }
1333
1334         /* add the call to the pending list */
1335         dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1336
1337         if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1338                 return NT_STATUS_OK;
1339         }
1340
1341         return dcesrv_reply(call);
1342 }
1343
1344
1345 /*
1346   remove the call from the right list when freed
1347  */
1348 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1349 {
1350         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1351         return 0;
1352 }
1353
1354 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1355 {
1356         return conn->local_address;
1357 }
1358
1359 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1360 {
1361         return conn->remote_address;
1362 }
1363
1364 /*
1365   process some input to a dcerpc endpoint server.
1366 */
1367 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1368                                             struct ncacn_packet *pkt,
1369                                             DATA_BLOB blob)
1370 {
1371         NTSTATUS status;
1372         struct dcesrv_call_state *call;
1373
1374         call = talloc_zero(dce_conn, struct dcesrv_call_state);
1375         if (!call) {
1376                 data_blob_free(&blob);
1377                 talloc_free(pkt);
1378                 return NT_STATUS_NO_MEMORY;
1379         }
1380         call->conn              = dce_conn;
1381         call->event_ctx         = dce_conn->event_ctx;
1382         call->msg_ctx           = dce_conn->msg_ctx;
1383         call->state_flags       = call->conn->state_flags;
1384         call->time              = timeval_current();
1385         call->list              = DCESRV_LIST_NONE;
1386
1387         talloc_steal(call, pkt);
1388         talloc_steal(call, blob.data);
1389         call->pkt = *pkt;
1390
1391         talloc_set_destructor(call, dcesrv_call_dequeue);
1392
1393         /* we have to check the signing here, before combining the
1394            pdus */
1395         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1396                 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1397                                 DCERPC_PKT_REQUEST,
1398                                 call->pkt.u.request.stub_and_verifier.length,
1399                                 0, /* required_flags */
1400                                 DCERPC_PFC_FLAG_FIRST |
1401                                 DCERPC_PFC_FLAG_LAST |
1402                                 DCERPC_PFC_FLAG_PENDING_CANCEL |
1403                                 0x08 | /* this is not defined, but should be ignored */
1404                                 DCERPC_PFC_FLAG_CONC_MPX |
1405                                 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1406                                 DCERPC_PFC_FLAG_MAYBE |
1407                                 DCERPC_PFC_FLAG_OBJECT_UUID);
1408                 if (!NT_STATUS_IS_OK(status)) {
1409                         return dcesrv_fault_disconnect(call,
1410                                         DCERPC_NCA_S_PROTO_ERROR);
1411                 }
1412
1413                 if (!dcesrv_auth_request(call, &blob)) {
1414                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1415                 }
1416         }
1417
1418         /* see if this is a continued packet */
1419         if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1420             !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) {
1421                 struct dcesrv_call_state *call2 = call;
1422                 uint32_t alloc_size;
1423
1424                 /* we only allow fragmented requests, no other packet types */
1425                 if (call->pkt.ptype != DCERPC_PKT_REQUEST) {
1426                         return dcesrv_fault(call2, DCERPC_FAULT_OTHER);
1427                 }
1428
1429                 /* this is a continuation of an existing call - find the call
1430                    then tack it on the end */
1431                 call = dcesrv_find_fragmented_call(dce_conn, call2->pkt.call_id);
1432                 if (!call) {
1433                         return dcesrv_fault(call2, DCERPC_FAULT_OTHER);
1434                 }
1435
1436                 if (call->pkt.ptype != call2->pkt.ptype) {
1437                         /* trying to play silly buggers are we? */
1438                         return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR);
1439                 }
1440                 if (memcmp(call->pkt.drep, call2->pkt.drep, sizeof(pkt->drep)) != 0) {
1441                         return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR);
1442                 }
1443                 if (call->pkt.call_id != call2->pkt.call_id) {
1444                         return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR);
1445                 }
1446                 if (call->pkt.u.request.context_id != call2->pkt.u.request.context_id)  {
1447                         return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR);
1448                 }
1449                 if (call->pkt.u.request.opnum != call2->pkt.u.request.opnum)  {
1450                         return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR);
1451                 }
1452
1453                 alloc_size = call->pkt.u.request.stub_and_verifier.length +
1454                         call2->pkt.u.request.stub_and_verifier.length;
1455                 if (call->pkt.u.request.alloc_hint > alloc_size) {
1456                         alloc_size = call->pkt.u.request.alloc_hint;
1457                 }
1458
1459                 call->pkt.u.request.stub_and_verifier.data = 
1460                         talloc_realloc(call, 
1461                                        call->pkt.u.request.stub_and_verifier.data, 
1462                                        uint8_t, alloc_size);
1463                 if (!call->pkt.u.request.stub_and_verifier.data) {
1464                         return dcesrv_fault(call2, DCERPC_FAULT_OTHER);
1465                 }
1466                 memcpy(call->pkt.u.request.stub_and_verifier.data +
1467                        call->pkt.u.request.stub_and_verifier.length,
1468                        call2->pkt.u.request.stub_and_verifier.data,
1469                        call2->pkt.u.request.stub_and_verifier.length);
1470                 call->pkt.u.request.stub_and_verifier.length += 
1471                         call2->pkt.u.request.stub_and_verifier.length;
1472
1473                 call->pkt.pfc_flags |= (call2->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1474
1475                 talloc_free(call2);
1476         }
1477
1478         /* this may not be the last pdu in the chain - if its isn't then
1479            just put it on the incoming_fragmented_call_list and wait for the rest */
1480         if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1481             !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1482                 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1483                 return NT_STATUS_OK;
1484         } 
1485         
1486         /* This removes any fragments we may have had stashed away */
1487         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1488
1489         switch (call->pkt.ptype) {
1490         case DCERPC_PKT_BIND:
1491                 status = dcesrv_bind(call);
1492                 break;
1493         case DCERPC_PKT_AUTH3:
1494                 status = dcesrv_auth3(call);
1495                 break;
1496         case DCERPC_PKT_ALTER:
1497                 status = dcesrv_alter(call);
1498                 break;
1499         case DCERPC_PKT_REQUEST:
1500                 status = dcesrv_request(call);
1501                 break;
1502         default:
1503                 status = NT_STATUS_INVALID_PARAMETER;
1504                 break;
1505         }
1506
1507         /* if we are going to be sending a reply then add
1508            it to the list of pending calls. We add it to the end to keep the call
1509            list in the order we will answer */
1510         if (!NT_STATUS_IS_OK(status)) {
1511                 talloc_free(call);
1512         }
1513
1514         return status;
1515 }
1516
1517 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, 
1518                                       struct loadparm_context *lp_ctx,
1519                                       const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1520 {
1521         NTSTATUS status;
1522         struct dcesrv_context *dce_ctx;
1523         int i;
1524
1525         if (!endpoint_servers) {
1526                 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1527                 return NT_STATUS_INTERNAL_ERROR;
1528         }
1529
1530         dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
1531         NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
1532
1533         if (uid_wrapper_enabled()) {
1534                 setenv("UID_WRAPPER_MYUID", "1", 1);
1535         }
1536         dce_ctx->initial_euid = geteuid();
1537         if (uid_wrapper_enabled()) {
1538                 unsetenv("UID_WRAPPER_MYUID");
1539         }
1540
1541         dce_ctx->endpoint_list  = NULL;
1542         dce_ctx->lp_ctx = lp_ctx;
1543         dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
1544         NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
1545         dce_ctx->broken_connections = NULL;
1546
1547         for (i=0;endpoint_servers[i];i++) {
1548                 const struct dcesrv_endpoint_server *ep_server;
1549
1550                 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
1551                 if (!ep_server) {
1552                         DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
1553                         return NT_STATUS_INTERNAL_ERROR;
1554                 }
1555
1556                 status = ep_server->init_server(dce_ctx, ep_server);
1557                 if (!NT_STATUS_IS_OK(status)) {
1558                         DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
1559                                 nt_errstr(status)));
1560                         return status;
1561                 }
1562         }
1563
1564         *_dce_ctx = dce_ctx;
1565         return NT_STATUS_OK;
1566 }
1567
1568 /* the list of currently registered DCERPC endpoint servers.
1569  */
1570 static struct ep_server {
1571         struct dcesrv_endpoint_server *ep_server;
1572 } *ep_servers = NULL;
1573 static int num_ep_servers;
1574
1575 /*
1576   register a DCERPC endpoint server. 
1577
1578   The 'name' can be later used by other backends to find the operations
1579   structure for this backend.  
1580
1581   The 'type' is used to specify whether this is for a disk, printer or IPC$ share
1582 */
1583 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const void *_ep_server)
1584 {
1585         const struct dcesrv_endpoint_server *ep_server = _ep_server;
1586         
1587         if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1588                 /* its already registered! */
1589                 DEBUG(0,("DCERPC endpoint server '%s' already registered\n", 
1590                          ep_server->name));
1591                 return NT_STATUS_OBJECT_NAME_COLLISION;
1592         }
1593
1594         ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1595         if (!ep_servers) {
1596                 smb_panic("out of memory in dcerpc_register");
1597         }
1598
1599         ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1600         ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1601
1602         num_ep_servers++;
1603
1604         DEBUG(3,("DCERPC endpoint server '%s' registered\n", 
1605                  ep_server->name));
1606
1607         return NT_STATUS_OK;
1608 }
1609
1610 /*
1611   return the operations structure for a named backend of the specified type
1612 */
1613 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1614 {
1615         int i;
1616
1617         for (i=0;i<num_ep_servers;i++) {
1618                 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1619                         return ep_servers[i].ep_server;
1620                 }
1621         }
1622
1623         return NULL;
1624 }
1625
1626 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1627 {
1628         static bool initialized;
1629 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1630         STATIC_dcerpc_server_MODULES_PROTO;
1631         init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1632         init_module_fn *shared_init;
1633
1634         if (initialized) {
1635                 return;
1636         }
1637         initialized = true;
1638
1639         shared_init = load_samba_modules(NULL, "dcerpc_server");
1640
1641         run_init_functions(static_init);
1642         run_init_functions(shared_init);
1643
1644         talloc_free(shared_init);
1645 }
1646
1647 /*
1648   return the DCERPC module version, and the size of some critical types
1649   This can be used by endpoint server modules to either detect compilation errors, or provide
1650   multiple implementations for different smbd compilation options in one module
1651 */
1652 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1653 {
1654         static const struct dcesrv_critical_sizes critical_sizes = {
1655                 DCERPC_MODULE_VERSION,
1656                 sizeof(struct dcesrv_context),
1657                 sizeof(struct dcesrv_endpoint),
1658                 sizeof(struct dcesrv_endpoint_server),
1659                 sizeof(struct dcesrv_interface),
1660                 sizeof(struct dcesrv_if_list),
1661                 sizeof(struct dcesrv_connection),
1662                 sizeof(struct dcesrv_call_state),
1663                 sizeof(struct dcesrv_auth),
1664                 sizeof(struct dcesrv_handle)
1665         };
1666
1667         return &critical_sizes;
1668 }
1669
1670 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
1671 {
1672         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
1673         struct stream_connection *srv_conn;
1674         srv_conn = talloc_get_type(dce_conn->transport.private_data,
1675                                    struct stream_connection);
1676
1677         if (dce_conn->pending_call_list == NULL) {
1678                 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
1679
1680                 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
1681                 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
1682                 return;
1683         }
1684
1685         if (dce_conn->terminate != NULL) {
1686                 return;
1687         }
1688
1689         DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
1690                  reason));
1691         dce_conn->terminate = talloc_strdup(dce_conn, reason);
1692         if (dce_conn->terminate == NULL) {
1693                 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
1694         }
1695         DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
1696 }
1697
1698 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
1699 {
1700         struct dcesrv_connection *cur, *next;
1701
1702         next = dce_ctx->broken_connections;
1703         while (next != NULL) {
1704                 cur = next;
1705                 next = cur->next;
1706
1707                 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1708                         struct dcesrv_connection_context *context_cur, *context_next;
1709
1710                         context_next = cur->contexts;
1711                         while (context_next != NULL) {
1712                                 context_cur = context_next;
1713                                 context_next = context_cur->next;
1714
1715                                 dcesrv_connection_context_destructor(context_cur);
1716                         }
1717                 }
1718
1719                 dcesrv_terminate_connection(cur, cur->terminate);
1720         }
1721 }
1722
1723 /* We need this include to be able to compile on some plateforms
1724  * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
1725  * correctly.
1726  * It has to be that deep because otherwise we have a conflict on
1727  * const struct dcesrv_interface declaration.
1728  * This is mostly due to socket_wrapper defining #define bind swrap_bind
1729  * which conflict with the bind used before.
1730  */
1731 #include "system/network.h"
1732
1733 struct dcesrv_sock_reply_state {
1734         struct dcesrv_connection *dce_conn;
1735         struct dcesrv_call_state *call;
1736         struct iovec iov;
1737 };
1738
1739 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
1740 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
1741
1742 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
1743 {
1744         struct dcesrv_call_state *call;
1745
1746         call = dce_conn->call_list;
1747         if (!call || !call->replies) {
1748                 return;
1749         }
1750
1751         while (call->replies) {
1752                 struct data_blob_list_item *rep = call->replies;
1753                 struct dcesrv_sock_reply_state *substate;
1754                 struct tevent_req *subreq;
1755
1756                 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
1757                 if (!substate) {
1758                         dcesrv_terminate_connection(dce_conn, "no memory");
1759                         return;
1760                 }
1761
1762                 substate->dce_conn = dce_conn;
1763                 substate->call = NULL;
1764
1765                 DLIST_REMOVE(call->replies, rep);
1766
1767                 if (call->replies == NULL && call->terminate_reason == NULL) {
1768                         substate->call = call;
1769                 }
1770
1771                 substate->iov.iov_base = (void *) rep->blob.data;
1772                 substate->iov.iov_len = rep->blob.length;
1773
1774                 subreq = tstream_writev_queue_send(substate,
1775                                                    dce_conn->event_ctx,
1776                                                    dce_conn->stream,
1777                                                    dce_conn->send_queue,
1778                                                    &substate->iov, 1);
1779                 if (!subreq) {
1780                         dcesrv_terminate_connection(dce_conn, "no memory");
1781                         return;
1782                 }
1783                 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
1784                                         substate);
1785         }
1786
1787         if (call->terminate_reason != NULL) {
1788                 struct tevent_req *subreq;
1789
1790                 subreq = tevent_queue_wait_send(call,
1791                                                 dce_conn->event_ctx,
1792                                                 dce_conn->send_queue);
1793                 if (!subreq) {
1794                         dcesrv_terminate_connection(dce_conn, __location__);
1795                         return;
1796                 }
1797                 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
1798                                         call);
1799         }
1800
1801         DLIST_REMOVE(call->conn->call_list, call);
1802         call->list = DCESRV_LIST_NONE;
1803 }
1804
1805 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
1806 {
1807         struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
1808                                                 struct dcesrv_sock_reply_state);
1809         int ret;
1810         int sys_errno;
1811         NTSTATUS status;
1812         struct dcesrv_call_state *call = substate->call;
1813
1814         ret = tstream_writev_queue_recv(subreq, &sys_errno);
1815         TALLOC_FREE(subreq);
1816         if (ret == -1) {
1817                 status = map_nt_error_from_unix_common(sys_errno);
1818                 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
1819                 return;
1820         }
1821
1822         talloc_free(substate);
1823         if (call) {
1824                 talloc_free(call);
1825         }
1826 }
1827
1828 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
1829
1830 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
1831 {
1832         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
1833                                                 struct dcesrv_call_state);
1834         bool ok;
1835         struct timeval tv;
1836
1837         /* make sure we stop send queue before removing subreq */
1838         tevent_queue_stop(call->conn->send_queue);
1839
1840         ok = tevent_queue_wait_recv(subreq);
1841         TALLOC_FREE(subreq);
1842         if (!ok) {
1843                 dcesrv_terminate_connection(call->conn, __location__);
1844                 return;
1845         }
1846
1847         /* disconnect after 200 usecs */
1848         tv = timeval_current_ofs_usec(200);
1849         subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
1850         if (subreq == NULL) {
1851                 dcesrv_terminate_connection(call->conn, __location__);
1852                 return;
1853         }
1854         tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
1855                                 call);
1856 }
1857
1858 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
1859 {
1860         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
1861                                                 struct dcesrv_call_state);
1862         bool ok;
1863
1864         ok = tevent_wakeup_recv(subreq);
1865         TALLOC_FREE(subreq);
1866         if (!ok) {
1867                 dcesrv_terminate_connection(call->conn, __location__);
1868                 return;
1869         }
1870
1871         dcesrv_terminate_connection(call->conn, call->terminate_reason);
1872 }
1873
1874 struct dcesrv_socket_context {
1875         const struct dcesrv_endpoint *endpoint;
1876         struct dcesrv_context *dcesrv_ctx;
1877 };
1878
1879
1880 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
1881
1882 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
1883 {
1884         NTSTATUS status;
1885         struct dcesrv_socket_context *dcesrv_sock = 
1886                 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
1887         enum dcerpc_transport_t transport =
1888                 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
1889         struct dcesrv_connection *dcesrv_conn = NULL;
1890         int ret;
1891         struct tevent_req *subreq;
1892         struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
1893
1894         dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
1895
1896         if (!srv_conn->session_info) {
1897                 status = auth_anonymous_session_info(srv_conn,
1898                                                      lp_ctx,
1899                                                      &srv_conn->session_info);
1900                 if (!NT_STATUS_IS_OK(status)) {
1901                         DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
1902                                 nt_errstr(status)));
1903                         stream_terminate_connection(srv_conn, nt_errstr(status));
1904                         return;
1905                 }
1906         }
1907
1908         status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
1909                                          srv_conn,
1910                                          dcesrv_sock->endpoint,
1911                                          srv_conn->session_info,
1912                                          srv_conn->event.ctx,
1913                                          srv_conn->msg_ctx,
1914                                          srv_conn->server_id,
1915                                          DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
1916                                          &dcesrv_conn);
1917         if (!NT_STATUS_IS_OK(status)) {
1918                 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
1919                         nt_errstr(status)));
1920                 stream_terminate_connection(srv_conn, nt_errstr(status));
1921                 return;
1922         }
1923
1924         dcesrv_conn->transport.private_data             = srv_conn;
1925         dcesrv_conn->transport.report_output_data       = dcesrv_sock_report_output_data;
1926
1927         TALLOC_FREE(srv_conn->event.fde);
1928
1929         dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
1930         if (!dcesrv_conn->send_queue) {
1931                 status = NT_STATUS_NO_MEMORY;
1932                 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
1933                         nt_errstr(status)));
1934                 stream_terminate_connection(srv_conn, nt_errstr(status));
1935                 return;
1936         }
1937
1938         if (transport == NCACN_NP) {
1939                 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
1940                 dcesrv_conn->stream = talloc_move(dcesrv_conn,
1941                                                   &srv_conn->tstream);
1942         } else {
1943                 ret = tstream_bsd_existing_socket(dcesrv_conn,
1944                                                   socket_get_fd(srv_conn->socket),
1945                                                   &dcesrv_conn->stream);
1946                 if (ret == -1) {
1947                         status = map_nt_error_from_unix_common(errno);
1948                         DEBUG(0, ("dcesrv_sock_accept: "
1949                                   "failed to setup tstream: %s\n",
1950                                   nt_errstr(status)));
1951                         stream_terminate_connection(srv_conn, nt_errstr(status));
1952                         return;
1953                 }
1954                 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
1955         }
1956
1957         dcesrv_conn->local_address = srv_conn->local_address;
1958         dcesrv_conn->remote_address = srv_conn->remote_address;
1959
1960         if (transport == NCALRPC) {
1961                 uid_t uid;
1962                 gid_t gid;
1963
1964                 ret = getpeereid(socket_get_fd(srv_conn->socket), &uid, &gid);
1965                 if (ret == -1) {
1966                         status = map_nt_error_from_unix_common(errno);
1967                         DEBUG(0, ("dcesrv_sock_accept: "
1968                                   "getpeereid() failed for NCALRPC: %s\n",
1969                                   nt_errstr(status)));
1970                         stream_terminate_connection(srv_conn, nt_errstr(status));
1971                         return;
1972                 }
1973                 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
1974                         struct tsocket_address *r = NULL;
1975
1976                         ret = tsocket_address_unix_from_path(dcesrv_conn,
1977                                                              "/root/ncalrpc_as_system",
1978                                                              &r);
1979                         if (ret == -1) {
1980                                 status = map_nt_error_from_unix_common(errno);
1981                                 DEBUG(0, ("dcesrv_sock_accept: "
1982                                           "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
1983                                           nt_errstr(status)));
1984                                 stream_terminate_connection(srv_conn, nt_errstr(status));
1985                                 return;
1986                         }
1987                         dcesrv_conn->remote_address = r;
1988                 }
1989         }
1990
1991         srv_conn->private_data = dcesrv_conn;
1992
1993         irpc_add_name(srv_conn->msg_ctx, "rpc_server");
1994
1995         subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
1996                                                dcesrv_conn->event_ctx,
1997                                                dcesrv_conn->stream);
1998         if (!subreq) {
1999                 status = NT_STATUS_NO_MEMORY;
2000                 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2001                         nt_errstr(status)));
2002                 stream_terminate_connection(srv_conn, nt_errstr(status));
2003                 return;
2004         }
2005         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2006
2007         return;
2008 }
2009
2010 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2011 {
2012         struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2013                                              struct dcesrv_connection);
2014         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2015         struct ncacn_packet *pkt;
2016         DATA_BLOB buffer;
2017         NTSTATUS status;
2018
2019         if (dce_conn->terminate) {
2020                 /*
2021                  * if the current connection is broken
2022                  * we need to clean it up before any other connection
2023                  */
2024                 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2025                 dcesrv_cleanup_broken_connections(dce_ctx);
2026                 return;
2027         }
2028
2029         dcesrv_cleanup_broken_connections(dce_ctx);
2030
2031         status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2032                                                &pkt, &buffer);
2033         TALLOC_FREE(subreq);
2034         if (!NT_STATUS_IS_OK(status)) {
2035                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2036                 return;
2037         }
2038
2039         status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2040         if (!NT_STATUS_IS_OK(status)) {
2041                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2042                 return;
2043         }
2044
2045         subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2046                                                dce_conn->event_ctx,
2047                                                dce_conn->stream);
2048         if (!subreq) {
2049                 status = NT_STATUS_NO_MEMORY;
2050                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2051                 return;
2052         }
2053         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2054 }
2055
2056 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2057 {
2058         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2059                                              struct dcesrv_connection);
2060         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2061 }
2062
2063 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2064 {
2065         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2066                                              struct dcesrv_connection);
2067         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2068 }
2069
2070
2071 static const struct stream_server_ops dcesrv_stream_ops = {
2072         .name                   = "rpc",
2073         .accept_connection      = dcesrv_sock_accept,
2074         .recv_handler           = dcesrv_sock_recv,
2075         .send_handler           = dcesrv_sock_send,
2076 };
2077
2078 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 
2079                                    struct loadparm_context *lp_ctx,
2080                                    struct dcesrv_endpoint *e,
2081                             struct tevent_context *event_ctx, const struct model_ops *model_ops)
2082 {
2083         struct dcesrv_socket_context *dcesrv_sock;
2084         uint16_t port = 1;
2085         NTSTATUS status;
2086         const char *endpoint;
2087
2088         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2089         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2090
2091         /* remember the endpoint of this socket */
2092         dcesrv_sock->endpoint           = e;
2093         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2094
2095         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2096
2097         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2098                                      model_ops, &dcesrv_stream_ops, 
2099                                      "unix", endpoint, &port,
2100                                      lpcfg_socket_options(lp_ctx),
2101                                      dcesrv_sock);
2102         if (!NT_STATUS_IS_OK(status)) {
2103                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2104                          endpoint, nt_errstr(status)));
2105         }
2106
2107         return status;
2108 }
2109
2110 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 
2111                                       struct loadparm_context *lp_ctx,
2112                                       struct dcesrv_endpoint *e,
2113                                       struct tevent_context *event_ctx, const struct model_ops *model_ops)
2114 {
2115         struct dcesrv_socket_context *dcesrv_sock;
2116         uint16_t port = 1;
2117         char *full_path;
2118         NTSTATUS status;
2119         const char *endpoint;
2120
2121         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2122
2123         if (endpoint == NULL) {
2124                 /*
2125                  * No identifier specified: use DEFAULT.
2126                  *
2127                  * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2128                  * no endpoint and let the epmapper worry about it.
2129                  */
2130                 endpoint = "DEFAULT";
2131                 status = dcerpc_binding_set_string_option(e->ep_description,
2132                                                           "endpoint",
2133                                                           endpoint);
2134                 if (!NT_STATUS_IS_OK(status)) {
2135                         DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2136                                   nt_errstr(status)));
2137                         return status;
2138                 }
2139         }
2140
2141         full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2142                                     endpoint);
2143
2144         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2145         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2146
2147         /* remember the endpoint of this socket */
2148         dcesrv_sock->endpoint           = e;
2149         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2150
2151         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2152                                      model_ops, &dcesrv_stream_ops, 
2153                                      "unix", full_path, &port, 
2154                                      lpcfg_socket_options(lp_ctx),
2155                                      dcesrv_sock);
2156         if (!NT_STATUS_IS_OK(status)) {
2157                 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2158                          endpoint, full_path, nt_errstr(status)));
2159         }
2160         return status;
2161 }
2162
2163 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2164                                  struct loadparm_context *lp_ctx,
2165                                  struct dcesrv_endpoint *e,
2166                                  struct tevent_context *event_ctx, const struct model_ops *model_ops)
2167 {
2168         struct dcesrv_socket_context *dcesrv_sock;
2169         NTSTATUS status;
2170         const char *endpoint;
2171
2172         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2173         if (endpoint == NULL) {
2174                 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2175                 return NT_STATUS_INVALID_PARAMETER;
2176         }
2177
2178         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2179         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2180
2181         /* remember the endpoint of this socket */
2182         dcesrv_sock->endpoint           = e;
2183         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2184
2185         status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2186                                           model_ops, &dcesrv_stream_ops,
2187                                           endpoint,
2188                                           dcesrv_sock);
2189         if (!NT_STATUS_IS_OK(status)) {
2190                 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2191                          endpoint, nt_errstr(status)));
2192                 return status;
2193         }
2194
2195         return NT_STATUS_OK;
2196 }
2197
2198 /*
2199   add a socket address to the list of events, one event per dcerpc endpoint
2200 */
2201 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2202                                          struct tevent_context *event_ctx, const struct model_ops *model_ops,
2203                                          const char *address)
2204 {
2205         struct dcesrv_socket_context *dcesrv_sock;
2206         uint16_t port = 0;
2207         NTSTATUS status;
2208         const char *endpoint;
2209         char port_str[6];
2210
2211         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2212         if (endpoint != NULL) {
2213                 port = atoi(endpoint);
2214         }
2215
2216         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2217         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2218
2219         /* remember the endpoint of this socket */
2220         dcesrv_sock->endpoint           = e;
2221         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2222
2223         status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2224                                      model_ops, &dcesrv_stream_ops, 
2225                                      "ip", address, &port,
2226                                      lpcfg_socket_options(dce_ctx->lp_ctx),
2227                                      dcesrv_sock);
2228         if (!NT_STATUS_IS_OK(status)) {
2229                 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n", 
2230                          address, port, nt_errstr(status)));
2231                 return status;
2232         }
2233
2234         snprintf(port_str, sizeof(port_str), "%u", port);
2235
2236         status = dcerpc_binding_set_string_option(e->ep_description,
2237                                                   "endpoint", port_str);
2238         if (!NT_STATUS_IS_OK(status)) {
2239                 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2240                          port_str, nt_errstr(status)));
2241                 return status;
2242         }
2243
2244         return NT_STATUS_OK;
2245 }
2246
2247 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2248
2249 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 
2250                                   struct loadparm_context *lp_ctx,
2251                                   struct dcesrv_endpoint *e,
2252                                   struct tevent_context *event_ctx, const struct model_ops *model_ops)
2253 {
2254         NTSTATUS status;
2255
2256         /* Add TCP/IP sockets */
2257         if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2258                 int num_interfaces;
2259                 int i;
2260                 struct interface *ifaces;
2261
2262                 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2263
2264                 num_interfaces = iface_list_count(ifaces);
2265                 for(i = 0; i < num_interfaces; i++) {
2266                         const char *address = iface_list_n_ip(ifaces, i);
2267                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2268                         NT_STATUS_NOT_OK_RETURN(status);
2269                 }
2270         } else {
2271                 char **wcard;
2272                 int i;
2273                 int num_binds = 0;
2274                 wcard = iface_list_wildcard(dce_ctx);
2275                 NT_STATUS_HAVE_NO_MEMORY(wcard);
2276                 for (i=0; wcard[i]; i++) {
2277                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2278                         if (NT_STATUS_IS_OK(status)) {
2279                                 num_binds++;
2280                         }
2281                 }
2282                 talloc_free(wcard);
2283                 if (num_binds == 0) {
2284                         return NT_STATUS_INVALID_PARAMETER_MIX;
2285                 }
2286         }
2287
2288         return NT_STATUS_OK;
2289 }
2290
2291 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2292                        struct loadparm_context *lp_ctx,
2293                        struct dcesrv_endpoint *e,
2294                        struct tevent_context *event_ctx,
2295                        const struct model_ops *model_ops)
2296 {
2297         enum dcerpc_transport_t transport =
2298                 dcerpc_binding_get_transport(e->ep_description);
2299
2300         switch (transport) {
2301         case NCACN_UNIX_STREAM:
2302                 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2303
2304         case NCALRPC:
2305                 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2306
2307         case NCACN_IP_TCP:
2308                 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2309
2310         case NCACN_NP:
2311                 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2312
2313         default:
2314                 return NT_STATUS_NOT_SUPPORTED;
2315         }
2316 }
2317
2318
2319 /**
2320  * retrieve credentials from a dce_call
2321  */
2322 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2323 {
2324         return dce_call->conn->auth_state.session_info->credentials;
2325 }
2326
2327 /**
2328  * returns true if this is an authenticated call
2329  */
2330 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2331 {
2332         enum security_user_level level;
2333         level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2334         return level >= SECURITY_USER;
2335 }
2336
2337 /**
2338  * retrieve account_name for a dce_call
2339  */
2340 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2341 {
2342         return dce_call->context->conn->auth_state.session_info->info->account_name;
2343 }