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