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