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