s4:rpc_server: ignore CO_CANCEL and ORPHANED PDUs
[metze/samba/wip.git] / source4 / rpc_server / dcerpc_server.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    server side dcerpc core code
5
6    Copyright (C) Andrew Tridgell 2003-2005
7    Copyright (C) Stefan (metze) Metzmacher 2004-2005
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "../lib/util/dlinklist.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/dcerpc_server_proto.h"
29 #include "rpc_server/common/proto.h"
30 #include "librpc/rpc/dcerpc_proto.h"
31 #include "system/filesys.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "../lib/tsocket/tsocket.h"
35 #include "../libcli/named_pipe_auth/npa_tstream.h"
36 #include "smbd/service_stream.h"
37 #include "../lib/tsocket/tsocket.h"
38 #include "lib/socket/socket.h"
39 #include "smbd/process_model.h"
40 #include "lib/messaging/irpc.h"
41 #include "librpc/rpc/rpc_common.h"
42 #include "lib/util/samba_modules.h"
43 #include "librpc/gen_ndr/ndr_dcerpc.h"
44
45 extern const struct dcesrv_interface dcesrv_mgmt_interface;
46
47 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
48                                 const struct dcerpc_bind *b,
49                                 struct dcerpc_ack_ctx *ack_ctx_list);
50
51 /*
52   find an association group given a assoc_group_id
53  */
54 static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context *dce_ctx,
55                                                           uint32_t id)
56 {
57         void *id_ptr;
58
59         id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
60         if (id_ptr == NULL) {
61                 return NULL;
62         }
63         return talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
64 }
65
66 /*
67   take a reference to an existing association group
68  */
69 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
70                                                                struct dcesrv_context *dce_ctx,
71                                                                uint32_t id)
72 {
73         struct dcesrv_assoc_group *assoc_group;
74
75         assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
76         if (assoc_group == NULL) {
77                 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
78                 return NULL;
79         }
80         return talloc_reference(mem_ctx, assoc_group);
81 }
82
83 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
84 {
85         int ret;
86         ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
87         if (ret != 0) {
88                 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
89                          assoc_group->id));
90         }
91         return 0;
92 }
93
94 /*
95   allocate a new association group
96  */
97 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
98                                                          struct dcesrv_context *dce_ctx)
99 {
100         struct dcesrv_assoc_group *assoc_group;
101         int id;
102
103         assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
104         if (assoc_group == NULL) {
105                 return NULL;
106         }
107         
108         id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
109         if (id == -1) {
110                 talloc_free(assoc_group);
111                 DEBUG(0,(__location__ ": Out of association groups!\n"));
112                 return NULL;
113         }
114
115         assoc_group->id = id;
116         assoc_group->dce_ctx = dce_ctx;
117
118         talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
119
120         return assoc_group;
121 }
122
123
124 /*
125   see if two endpoints match
126 */
127 static bool endpoints_match(const struct dcerpc_binding *ep1,
128                             const struct dcerpc_binding *ep2)
129 {
130         enum dcerpc_transport_t t1;
131         enum dcerpc_transport_t t2;
132         const char *e1;
133         const char *e2;
134
135         t1 = dcerpc_binding_get_transport(ep1);
136         t2 = dcerpc_binding_get_transport(ep2);
137
138         e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
139         e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
140
141         if (t1 != t2) {
142                 return false;
143         }
144
145         if (!e1 || !e2) {
146                 return e1 == e2;
147         }
148
149         if (strcasecmp(e1, e2) != 0) {
150                 return false;
151         }
152
153         return true;
154 }
155
156 /*
157   find an endpoint in the dcesrv_context
158 */
159 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
160                                              const struct dcerpc_binding *ep_description)
161 {
162         struct dcesrv_endpoint *ep;
163         for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
164                 if (endpoints_match(ep->ep_description, ep_description)) {
165                         return ep;
166                 }
167         }
168         return NULL;
169 }
170
171 /*
172   find a registered context_id from a bind or alter_context
173 */
174 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn, 
175                                                              uint16_t context_id)
176 {
177         struct dcesrv_connection_context *c;
178         for (c=conn->contexts;c;c=c->next) {
179                 if (c->context_id == context_id) return c;
180         }
181         return NULL;
182 }
183
184 /*
185   see if a uuid and if_version match to an interface
186 */
187 static bool interface_match(const struct dcesrv_interface *if1,
188                                                         const struct dcesrv_interface *if2)
189 {
190         return (if1->syntax_id.if_version == if2->syntax_id.if_version && 
191                         GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
192 }
193
194 /*
195   find the interface operations on an endpoint
196 */
197 static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoint *endpoint,
198                                                      const struct dcesrv_interface *iface)
199 {
200         struct dcesrv_if_list *ifl;
201         for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
202                 if (interface_match(&(ifl->iface), iface)) {
203                         return &(ifl->iface);
204                 }
205         }
206         return NULL;
207 }
208
209 /*
210   see if a uuid and if_version match to an interface
211 */
212 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
213                                     const struct GUID *uuid, uint32_t if_version)
214 {
215         return (iface->syntax_id.if_version == if_version && 
216                         GUID_equal(&iface->syntax_id.uuid, uuid));
217 }
218
219 /*
220   find the interface operations on an endpoint by uuid
221 */
222 static const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
223                                                              const struct GUID *uuid, uint32_t if_version)
224 {
225         struct dcesrv_if_list *ifl;
226         for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
227                 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
228                         return &(ifl->iface);
229                 }
230         }
231         return NULL;
232 }
233
234 /*
235   find the earlier parts of a fragmented call awaiting reassembily
236 */
237 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint16_t call_id)
238 {
239         struct dcesrv_call_state *c;
240         for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
241                 if (c->pkt.call_id == call_id) {
242                         return c;
243                 }
244         }
245         return NULL;
246 }
247
248 /*
249   register an interface on an endpoint
250 */
251 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
252                                    const char *ep_name,
253                                    const struct dcesrv_interface *iface,
254                                    const struct security_descriptor *sd)
255 {
256         struct dcesrv_endpoint *ep;
257         struct dcesrv_if_list *ifl;
258         struct dcerpc_binding *binding;
259         bool add_ep = false;
260         NTSTATUS status;
261         
262         status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
263
264         if (NT_STATUS_IS_ERR(status)) {
265                 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
266                 return status;
267         }
268
269         /* check if this endpoint exists
270          */
271         if ((ep=find_endpoint(dce_ctx, binding))==NULL) {
272                 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
273                 if (!ep) {
274                         return NT_STATUS_NO_MEMORY;
275                 }
276                 ZERO_STRUCTP(ep);
277                 ep->ep_description = talloc_move(ep, &binding);
278                 add_ep = true;
279
280                 /* add mgmt interface */
281                 ifl = talloc_zero(ep, struct dcesrv_if_list);
282                 if (!ifl) {
283                         return NT_STATUS_NO_MEMORY;
284                 }
285
286                 memcpy(&(ifl->iface), &dcesrv_mgmt_interface, 
287                            sizeof(struct dcesrv_interface));
288
289                 DLIST_ADD(ep->interface_list, ifl);
290         }
291
292         /* see if the interface is already registered on te endpoint */
293         if (find_interface(ep, iface)!=NULL) {
294                 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
295                         iface->name, ep_name));
296                 return NT_STATUS_OBJECT_NAME_COLLISION;
297         }
298
299         /* talloc a new interface list element */
300         ifl = talloc_zero(ep, struct dcesrv_if_list);
301         if (!ifl) {
302                 return NT_STATUS_NO_MEMORY;
303         }
304
305         /* copy the given interface struct to the one on the endpoints interface list */
306         memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
307
308         /* if we have a security descriptor given,
309          * we should see if we can set it up on the endpoint
310          */
311         if (sd != NULL) {
312                 /* if there's currently no security descriptor given on the endpoint
313                  * we try to set it
314                  */
315                 if (ep->sd == NULL) {
316                         ep->sd = security_descriptor_copy(ep, sd);
317                 }
318
319                 /* if now there's no security descriptor given on the endpoint
320                  * something goes wrong, either we failed to copy the security descriptor
321                  * or there was already one on the endpoint
322                  */
323                 if (ep->sd != NULL) {
324                         DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
325                                  "                           on endpoint '%s'\n",
326                                 iface->name, ep_name));
327                         if (add_ep) free(ep);
328                         free(ifl);
329                         return NT_STATUS_OBJECT_NAME_COLLISION;
330                 }
331         }
332
333         /* finally add the interface on the endpoint */
334         DLIST_ADD(ep->interface_list, ifl);
335
336         /* if it's a new endpoint add it to the dcesrv_context */
337         if (add_ep) {
338                 DLIST_ADD(dce_ctx->endpoint_list, ep);
339         }
340
341         DEBUG(4,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n",
342                 iface->name, ep_name));
343
344         return NT_STATUS_OK;
345 }
346
347 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
348                                       DATA_BLOB *session_key)
349 {
350         if (p->auth_state.session_info->session_key.length) {
351                 *session_key = p->auth_state.session_info->session_key;
352                 return NT_STATUS_OK;
353         }
354         return NT_STATUS_NO_USER_SESSION_KEY;
355 }
356
357 /*
358   fetch the user session key - may be default (above) or the SMB session key
359
360   The key is always truncated to 16 bytes 
361 */
362 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
363                                   DATA_BLOB *session_key)
364 {
365         NTSTATUS status = p->auth_state.session_key(p, session_key);
366         if (!NT_STATUS_IS_OK(status)) {
367                 return status;
368         }
369
370         session_key->length = MIN(session_key->length, 16);
371
372         return NT_STATUS_OK;
373 }
374
375 /*
376   connect to a dcerpc endpoint
377 */
378 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
379                                  TALLOC_CTX *mem_ctx,
380                                  const struct dcesrv_endpoint *ep,
381                                  struct auth_session_info *session_info,
382                                  struct tevent_context *event_ctx,
383                                  struct imessaging_context *msg_ctx,
384                                  struct server_id server_id,
385                                  uint32_t state_flags,
386                                  struct dcesrv_connection **_p)
387 {
388         struct dcesrv_connection *p;
389
390         if (!session_info) {
391                 return NT_STATUS_ACCESS_DENIED;
392         }
393
394         p = talloc_zero(mem_ctx, struct dcesrv_connection);
395         NT_STATUS_HAVE_NO_MEMORY(p);
396
397         if (!talloc_reference(p, session_info)) {
398                 talloc_free(p);
399                 return NT_STATUS_NO_MEMORY;
400         }
401
402         p->dce_ctx = dce_ctx;
403         p->endpoint = ep;
404         p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
405         p->auth_state.session_info = session_info;
406         p->auth_state.session_key = dcesrv_generic_session_key;
407         p->event_ctx = event_ctx;
408         p->msg_ctx = msg_ctx;
409         p->server_id = server_id;
410         p->state_flags = state_flags;
411         p->allow_bind = true;
412         p->max_recv_frag = 5840;
413         p->max_xmit_frag = 5840;
414         p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
415
416         /*
417          * For now we only support NDR32.
418          */
419         p->preferred_transfer = &ndr_transfer_syntax_ndr;
420
421         *_p = p;
422         return NT_STATUS_OK;
423 }
424
425 /*
426   move a call from an existing linked list to the specified list. This
427   prevents bugs where we forget to remove the call from a previous
428   list when moving it.
429  */
430 static void dcesrv_call_set_list(struct dcesrv_call_state *call, 
431                                  enum dcesrv_call_list list)
432 {
433         switch (call->list) {
434         case DCESRV_LIST_NONE:
435                 break;
436         case DCESRV_LIST_CALL_LIST:
437                 DLIST_REMOVE(call->conn->call_list, call);
438                 break;
439         case DCESRV_LIST_FRAGMENTED_CALL_LIST:
440                 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
441                 break;
442         case DCESRV_LIST_PENDING_CALL_LIST:
443                 DLIST_REMOVE(call->conn->pending_call_list, call);
444                 break;
445         }
446         call->list = list;
447         switch (list) {
448         case DCESRV_LIST_NONE:
449                 break;
450         case DCESRV_LIST_CALL_LIST:
451                 DLIST_ADD_END(call->conn->call_list, call);
452                 break;
453         case DCESRV_LIST_FRAGMENTED_CALL_LIST:
454                 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
455                 break;
456         case DCESRV_LIST_PENDING_CALL_LIST:
457                 DLIST_ADD_END(call->conn->pending_call_list, call);
458                 break;
459         }
460 }
461
462 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
463                                          const char *reason)
464 {
465         if (call->conn->terminate != NULL) {
466                 return;
467         }
468
469         call->conn->allow_bind = false;
470         call->conn->allow_alter = false;
471         call->conn->allow_auth3 = false;
472         call->conn->allow_request = false;
473
474         call->terminate_reason = talloc_strdup(call, reason);
475         if (call->terminate_reason == NULL) {
476                 call->terminate_reason = __location__;
477         }
478 }
479
480 /*
481   return a dcerpc bind_nak
482 */
483 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
484 {
485         struct ncacn_packet pkt;
486         struct dcerpc_bind_nak_version version;
487         struct data_blob_list_item *rep;
488         NTSTATUS status;
489         static const uint8_t _pad[3] = { 0, };
490
491         /*
492          * We add the call to the pending_call_list
493          * in order to defer the termination.
494          */
495         dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
496
497         /* setup a bind_nak */
498         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
499         pkt.auth_length = 0;
500         pkt.call_id = call->pkt.call_id;
501         pkt.ptype = DCERPC_PKT_BIND_NAK;
502         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
503         pkt.u.bind_nak.reject_reason = reason;
504         version.rpc_vers = 5;
505         version.rpc_vers_minor = 0;
506         pkt.u.bind_nak.num_versions = 1;
507         pkt.u.bind_nak.versions = &version;
508         pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
509
510         rep = talloc_zero(call, struct data_blob_list_item);
511         if (!rep) {
512                 return NT_STATUS_NO_MEMORY;
513         }
514
515         status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
516         if (!NT_STATUS_IS_OK(status)) {
517                 return status;
518         }
519
520         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
521
522         DLIST_ADD_END(call->replies, rep);
523         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
524
525         if (call->conn->call_list && call->conn->call_list->replies) {
526                 if (call->conn->transport.report_output_data) {
527                         call->conn->transport.report_output_data(call->conn);
528                 }
529         }
530
531         return NT_STATUS_OK;    
532 }
533
534 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
535                                  uint32_t fault_code)
536 {
537         /*
538          * We add the call to the pending_call_list
539          * in order to defer the termination.
540          */
541         dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
542
543         return dcesrv_fault_with_flags(call, fault_code,
544                                        DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
545 }
546
547 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
548 {
549         DLIST_REMOVE(c->conn->contexts, c);
550
551         if (c->iface && c->iface->unbind) {
552                 c->iface->unbind(c, c->iface);
553                 c->iface = NULL;
554         }
555
556         return 0;
557 }
558
559 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
560 {
561         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
562         const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
563         enum dcerpc_transport_t transport =
564                 dcerpc_binding_get_transport(endpoint->ep_description);
565         struct dcesrv_connection_context *context = dce_call->context;
566         const struct dcesrv_interface *iface = context->iface;
567
568         context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
569
570         if (transport == NCALRPC) {
571                 context->allow_connect = true;
572                 return;
573         }
574
575         /*
576          * allow overwrite per interface
577          * allow dcerpc auth level connect:<interface>
578          */
579         context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
580         context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
581                                         "allow dcerpc auth level connect",
582                                         iface->name,
583                                         context->allow_connect);
584 }
585
586 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
587                                                  const struct dcesrv_interface *iface)
588 {
589         if (dce_call->context == NULL) {
590                 return NT_STATUS_INTERNAL_ERROR;
591         }
592
593         /*
594          * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
595          * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
596          */
597         dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
598         return NT_STATUS_OK;
599 }
600
601 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
602                                                const struct dcesrv_interface *iface)
603 {
604         if (dce_call->context == NULL) {
605                 return NT_STATUS_INTERNAL_ERROR;
606         }
607
608         dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
609         return NT_STATUS_OK;
610 }
611
612 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
613                                                        const struct dcesrv_interface *iface)
614 {
615         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
616         const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
617         enum dcerpc_transport_t transport =
618                 dcerpc_binding_get_transport(endpoint->ep_description);
619         struct dcesrv_connection_context *context = dce_call->context;
620
621         if (context == NULL) {
622                 return NT_STATUS_INTERNAL_ERROR;
623         }
624
625         if (transport == NCALRPC) {
626                 context->allow_connect = true;
627                 return NT_STATUS_OK;
628         }
629
630         /*
631          * allow overwrite per interface
632          * allow dcerpc auth level connect:<interface>
633          */
634         context->allow_connect = false;
635         context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
636                                         "allow dcerpc auth level connect",
637                                         iface->name,
638                                         context->allow_connect);
639         return NT_STATUS_OK;
640 }
641
642 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
643                                                       const struct dcesrv_interface *iface)
644 {
645         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
646         const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
647         enum dcerpc_transport_t transport =
648                 dcerpc_binding_get_transport(endpoint->ep_description);
649         struct dcesrv_connection_context *context = dce_call->context;
650
651         if (context == NULL) {
652                 return NT_STATUS_INTERNAL_ERROR;
653         }
654
655         if (transport == NCALRPC) {
656                 context->allow_connect = true;
657                 return NT_STATUS_OK;
658         }
659
660         /*
661          * allow overwrite per interface
662          * allow dcerpc auth level connect:<interface>
663          */
664         context->allow_connect = true;
665         context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
666                                         "allow dcerpc auth level connect",
667                                         iface->name,
668                                         context->allow_connect);
669         return NT_STATUS_OK;
670 }
671
672 /*
673   handle a bind request
674 */
675 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
676 {
677         struct ncacn_packet pkt;
678         struct data_blob_list_item *rep;
679         NTSTATUS status;
680         uint32_t extra_flags = 0;
681         uint16_t max_req = 0;
682         uint16_t max_rep = 0;
683         const char *ep_prefix = "";
684         const char *endpoint = NULL;
685         struct dcerpc_ack_ctx *ack_ctx_list = NULL;
686         struct dcerpc_ack_ctx *ack_features = NULL;
687         size_t i;
688
689         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
690                         DCERPC_PKT_BIND,
691                         call->pkt.u.bind.auth_info.length,
692                         0, /* required flags */
693                         DCERPC_PFC_FLAG_FIRST |
694                         DCERPC_PFC_FLAG_LAST |
695                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
696                         0x08 | /* this is not defined, but should be ignored */
697                         DCERPC_PFC_FLAG_CONC_MPX |
698                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
699                         DCERPC_PFC_FLAG_MAYBE |
700                         DCERPC_PFC_FLAG_OBJECT_UUID);
701         if (!NT_STATUS_IS_OK(status)) {
702                 return dcesrv_bind_nak(call,
703                         DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
704         }
705
706         /* max_recv_frag and max_xmit_frag result always in the same value! */
707         max_req = MIN(call->pkt.u.bind.max_xmit_frag,
708                       call->pkt.u.bind.max_recv_frag);
709         /*
710          * The values are between 2048 and 5840 tested against Windows 2012R2
711          * via ncacn_ip_tcp on port 135.
712          */
713         max_req = MAX(2048, max_req);
714         max_rep = MIN(max_req, call->conn->max_recv_frag);
715         /* They are truncated to an 8 byte boundary. */
716         max_rep &= 0xFFF8;
717
718         /* max_recv_frag and max_xmit_frag result always in the same value! */
719         call->conn->max_recv_frag = max_rep;
720         call->conn->max_xmit_frag = max_rep;
721
722         /*
723           if provided, check the assoc_group is valid
724          */
725         if (call->pkt.u.bind.assoc_group_id != 0) {
726                 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
727                                                                        call->conn->dce_ctx,
728                                                                        call->pkt.u.bind.assoc_group_id);
729         } else {
730                 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
731                                                                  call->conn->dce_ctx);
732         }
733         if (call->conn->assoc_group == NULL) {
734                 return dcesrv_bind_nak(call, 0);
735         }
736
737         if (call->pkt.u.bind.num_contexts < 1) {
738                 return dcesrv_bind_nak(call, 0);
739         }
740
741         ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
742                                          call->pkt.u.bind.num_contexts);
743         if (ack_ctx_list == NULL) {
744                 return dcesrv_bind_nak(call, 0);
745         }
746
747         /*
748          * Set some sane defaults (required by dcesrv_negotiate_contexts()/
749          * dcesrv_check_or_create_context()) and do some protocol validation
750          * and set sane defaults.
751          */
752         for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
753                 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
754                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
755                 bool is_feature = false;
756                 uint64_t features = 0;
757
758                 if (c->num_transfer_syntaxes == 0) {
759                         return dcesrv_bind_nak(call, 0);
760                 }
761
762                 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
763                 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
764
765                 /*
766                  * It's only treated as bind time feature request, if the first
767                  * transfer_syntax matches, all others are ignored.
768                  */
769                 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
770                                                                &features);
771                 if (!is_feature) {
772                         continue;
773                 }
774
775                 if (ack_features != NULL) {
776                         /*
777                          * Only one bind time feature context is allowed.
778                          */
779                         return dcesrv_bind_nak(call, 0);
780                 }
781                 ack_features = a;
782
783                 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
784                 a->reason.negotiate = 0;
785                 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
786                         /* not supported yet */
787                 }
788                 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
789                         /* not supported yet */
790                 }
791
792                 call->conn->bind_time_features = a->reason.negotiate;
793         }
794
795         /*
796          * Try to negotiate one new presentation context.
797          */
798         status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
799         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
800                 return dcesrv_bind_nak(call, 0);
801         }
802         if (!NT_STATUS_IS_OK(status)) {
803                 return status;
804         }
805
806         if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
807             (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
808                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
809                 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
810         }
811
812         if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
813                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
814         }
815
816         /* handle any authentication that is being requested */
817         if (!dcesrv_auth_bind(call)) {
818                 struct dcesrv_auth *auth = &call->conn->auth_state;
819
820                 TALLOC_FREE(call->context);
821
822                 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
823                         /*
824                          * With DCERPC_AUTH_LEVEL_NONE, we get the
825                          * reject_reason in auth->auth_context_id.
826                          */
827                         return dcesrv_bind_nak(call, auth->auth_context_id);
828                 }
829
830                 /*
831                  * This must a be a temporary failure e.g. talloc or invalid
832                  * configuration, e.g. no machine account.
833                  */
834                 return dcesrv_bind_nak(call,
835                                 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
836         }
837
838         /* setup a bind_ack */
839         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
840         pkt.auth_length = 0;
841         pkt.call_id = call->pkt.call_id;
842         pkt.ptype = DCERPC_PKT_BIND_ACK;
843         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
844         pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
845         pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
846         pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
847
848         endpoint = dcerpc_binding_get_string_option(
849                                 call->conn->endpoint->ep_description,
850                                 "endpoint");
851         if (endpoint == NULL) {
852                 endpoint = "";
853         }
854
855         if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
856                 /*
857                  * TODO: check if this is really needed
858                  *
859                  * Or if we should fix this in our idl files.
860                  */
861                 ep_prefix = "\\PIPE\\";
862                 endpoint += 6;
863         }
864
865         pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
866                                                            ep_prefix,
867                                                            endpoint);
868         if (pkt.u.bind_ack.secondary_address == NULL) {
869                 TALLOC_FREE(call->context);
870                 return NT_STATUS_NO_MEMORY;
871         }
872         pkt.u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
873         pkt.u.bind_ack.ctx_list = ack_ctx_list;
874         pkt.u.bind_ack.auth_info = data_blob_null;
875
876         status = dcesrv_auth_bind_ack(call, &pkt);
877         if (!NT_STATUS_IS_OK(status)) {
878                 TALLOC_FREE(call->context);
879                 return dcesrv_bind_nak(call, 0);
880         }
881
882         rep = talloc_zero(call, struct data_blob_list_item);
883         if (!rep) {
884                 TALLOC_FREE(call->context);
885                 return NT_STATUS_NO_MEMORY;
886         }
887
888         status = ncacn_push_auth(&rep->blob, call, &pkt,
889                                  call->out_auth_info);
890         if (!NT_STATUS_IS_OK(status)) {
891                 TALLOC_FREE(call->context);
892                 return status;
893         }
894
895         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
896
897         DLIST_ADD_END(call->replies, rep);
898         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
899
900         if (call->conn->call_list && call->conn->call_list->replies) {
901                 if (call->conn->transport.report_output_data) {
902                         call->conn->transport.report_output_data(call->conn);
903                 }
904         }
905
906         return NT_STATUS_OK;
907 }
908
909
910 /*
911   handle a auth3 request
912 */
913 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
914 {
915         NTSTATUS status;
916
917         if (!call->conn->allow_auth3) {
918                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
919         }
920
921         if (call->conn->auth_state.auth_finished) {
922                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
923         }
924
925         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
926                         DCERPC_PKT_AUTH3,
927                         call->pkt.u.auth3.auth_info.length,
928                         0, /* required flags */
929                         DCERPC_PFC_FLAG_FIRST |
930                         DCERPC_PFC_FLAG_LAST |
931                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
932                         0x08 | /* this is not defined, but should be ignored */
933                         DCERPC_PFC_FLAG_CONC_MPX |
934                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
935                         DCERPC_PFC_FLAG_MAYBE |
936                         DCERPC_PFC_FLAG_OBJECT_UUID);
937         if (!NT_STATUS_IS_OK(status)) {
938                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
939         }
940
941         /* handle the auth3 in the auth code */
942         if (!dcesrv_auth_auth3(call)) {
943                 call->conn->auth_state.auth_invalid = true;
944                 if (call->fault_code != 0) {
945                         return dcesrv_fault_disconnect(call, call->fault_code);
946                 }
947         }
948
949         talloc_free(call);
950
951         /* we don't send a reply to a auth3 request, except by a
952            fault */
953         return NT_STATUS_OK;
954 }
955
956
957 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
958                                 const struct dcerpc_bind *b,
959                                 const struct dcerpc_ctx_list *ctx,
960                                 struct dcerpc_ack_ctx *ack,
961                                 bool validate_only,
962                                 const struct ndr_syntax_id *supported_transfer)
963 {
964         uint32_t if_version;
965         struct dcesrv_connection_context *context;
966         const struct dcesrv_interface *iface;
967         struct GUID uuid;
968         NTSTATUS status;
969         const struct ndr_syntax_id *selected_transfer = NULL;
970         size_t i;
971         bool ok;
972
973         if (b == NULL) {
974                 return NT_STATUS_INTERNAL_ERROR;
975         }
976         if (ctx == NULL) {
977                 return NT_STATUS_INTERNAL_ERROR;
978         }
979         if (ctx->num_transfer_syntaxes < 1) {
980                 return NT_STATUS_INTERNAL_ERROR;
981         }
982         if (ack == NULL) {
983                 return NT_STATUS_INTERNAL_ERROR;
984         }
985         if (supported_transfer == NULL) {
986                 return NT_STATUS_INTERNAL_ERROR;
987         }
988
989         switch (ack->result) {
990         case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
991         case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
992                 /*
993                  * We is already completed.
994                  */
995                 return NT_STATUS_OK;
996         default:
997                 break;
998         }
999
1000         ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1001         ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1002
1003         if_version = ctx->abstract_syntax.if_version;
1004         uuid = ctx->abstract_syntax.uuid;
1005
1006         iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1007         if (iface == NULL) {
1008                 char *uuid_str = GUID_string(call, &uuid);
1009                 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1010                 talloc_free(uuid_str);
1011                 /*
1012                  * We report this only via ack->result
1013                  */
1014                 return NT_STATUS_OK;
1015         }
1016
1017         ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1018         ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1019
1020         if (validate_only) {
1021                 /*
1022                  * We report this only via ack->result
1023                  */
1024                 return NT_STATUS_OK;
1025         }
1026
1027         for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1028                 /*
1029                  * we only do NDR encoded dcerpc for now.
1030                  */
1031                 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1032                                          supported_transfer);
1033                 if (ok) {
1034                         selected_transfer = supported_transfer;
1035                         break;
1036                 }
1037         }
1038
1039         context = dcesrv_find_context(call->conn, ctx->context_id);
1040         if (context != NULL) {
1041                 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1042                                          &ctx->abstract_syntax);
1043                 if (!ok) {
1044                         return NT_STATUS_RPC_PROTOCOL_ERROR;
1045                 }
1046
1047                 if (selected_transfer != NULL) {
1048                         ok = ndr_syntax_id_equal(&context->transfer_syntax,
1049                                                  selected_transfer);
1050                         if (!ok) {
1051                                 return NT_STATUS_RPC_PROTOCOL_ERROR;
1052                         }
1053
1054                         ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1055                         ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1056                         ack->syntax = context->transfer_syntax;
1057                 }
1058
1059                 /*
1060                  * We report this only via ack->result
1061                  */
1062                 return NT_STATUS_OK;
1063         }
1064
1065         if (selected_transfer == NULL) {
1066                 /*
1067                  * We report this only via ack->result
1068                  */
1069                 return NT_STATUS_OK;
1070         }
1071
1072         ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1073         ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1074
1075         /* add this context to the list of available context_ids */
1076         context = talloc_zero(call->conn, struct dcesrv_connection_context);
1077         if (context == NULL) {
1078                 return NT_STATUS_NO_MEMORY;
1079         }
1080         context->conn = call->conn;
1081         context->context_id = ctx->context_id;
1082         context->iface = iface;
1083         context->transfer_syntax = *selected_transfer;
1084         context->private_data = NULL;
1085         DLIST_ADD(call->conn->contexts, context);
1086         call->context = context;
1087         talloc_set_destructor(context, dcesrv_connection_context_destructor);
1088
1089         dcesrv_prepare_context_auth(call);
1090
1091         status = iface->bind(call, iface, if_version);
1092         call->context = NULL;
1093         if (!NT_STATUS_IS_OK(status)) {
1094                 /* we don't want to trigger the iface->unbind() hook */
1095                 context->iface = NULL;
1096                 talloc_free(context);
1097                 /*
1098                  * We report this only via ack->result
1099                  */
1100                 return NT_STATUS_OK;
1101         }
1102
1103         ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1104         ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1105         ack->syntax = context->transfer_syntax;
1106         return NT_STATUS_OK;
1107 }
1108
1109 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1110                                 const struct dcerpc_bind *b,
1111                                 struct dcerpc_ack_ctx *ack_ctx_list)
1112 {
1113         NTSTATUS status;
1114         size_t i;
1115         bool validate_only = false;
1116         bool preferred_ndr32;
1117
1118         /*
1119          * Try to negotiate one new presentation context,
1120          * using our preferred transfer syntax.
1121          */
1122         for (i = 0; i < b->num_contexts; i++) {
1123                 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1124                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1125
1126                 status = dcesrv_check_or_create_context(call, b, c, a,
1127                                                 validate_only,
1128                                                 call->conn->preferred_transfer);
1129                 if (!NT_STATUS_IS_OK(status)) {
1130                         return status;
1131                 }
1132
1133                 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1134                         /*
1135                          * We managed to negotiate one context.
1136                          *
1137                          * => we're done.
1138                          */
1139                         validate_only = true;
1140                 }
1141         }
1142
1143         preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1144                                         call->conn->preferred_transfer);
1145         if (preferred_ndr32) {
1146                 /*
1147                  * We're done.
1148                  */
1149                 return NT_STATUS_OK;
1150         }
1151
1152         /*
1153          * Try to negotiate one new presentation context,
1154          * using NDR 32 as fallback.
1155          */
1156         for (i = 0; i < b->num_contexts; i++) {
1157                 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1158                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1159
1160                 status = dcesrv_check_or_create_context(call, b, c, a,
1161                                                 validate_only,
1162                                                 &ndr_transfer_syntax_ndr);
1163                 if (!NT_STATUS_IS_OK(status)) {
1164                         return status;
1165                 }
1166
1167                 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1168                         /*
1169                          * We managed to negotiate one context.
1170                          *
1171                          * => we're done.
1172                          */
1173                         validate_only = true;
1174                 }
1175         }
1176
1177         return NT_STATUS_OK;
1178 }
1179
1180 /*
1181   handle a alter context request
1182 */
1183 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1184 {
1185         NTSTATUS status;
1186         bool auth_ok = false;
1187         struct ncacn_packet pkt;
1188         uint32_t extra_flags = 0;
1189         struct data_blob_list_item *rep = NULL;
1190         struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1191         size_t i;
1192
1193         if (!call->conn->allow_alter) {
1194                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1195         }
1196
1197         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1198                         DCERPC_PKT_ALTER,
1199                         call->pkt.u.alter.auth_info.length,
1200                         0, /* required flags */
1201                         DCERPC_PFC_FLAG_FIRST |
1202                         DCERPC_PFC_FLAG_LAST |
1203                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1204                         0x08 | /* this is not defined, but should be ignored */
1205                         DCERPC_PFC_FLAG_CONC_MPX |
1206                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1207                         DCERPC_PFC_FLAG_MAYBE |
1208                         DCERPC_PFC_FLAG_OBJECT_UUID);
1209         if (!NT_STATUS_IS_OK(status)) {
1210                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1211         }
1212
1213         auth_ok = dcesrv_auth_alter(call);
1214         if (!auth_ok) {
1215                 if (call->fault_code != 0) {
1216                         return dcesrv_fault_disconnect(call, call->fault_code);
1217                 }
1218         }
1219
1220         if (call->pkt.u.alter.num_contexts < 1) {
1221                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1222         }
1223
1224         ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1225                                          call->pkt.u.alter.num_contexts);
1226         if (ack_ctx_list == NULL) {
1227                 return NT_STATUS_NO_MEMORY;
1228         }
1229
1230         /*
1231          * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1232          * dcesrv_check_or_create_context()) and do some protocol validation
1233          * and set sane defaults.
1234          */
1235         for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1236                 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1237                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1238
1239                 if (c->num_transfer_syntaxes == 0) {
1240                         return dcesrv_fault_disconnect(call,
1241                                         DCERPC_NCA_S_PROTO_ERROR);
1242                 }
1243
1244                 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1245                 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1246         }
1247
1248         /*
1249          * Try to negotiate one new presentation context.
1250          */
1251         status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1252         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1253                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1254         }
1255         if (!NT_STATUS_IS_OK(status)) {
1256                 return status;
1257         }
1258
1259         if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1260             (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1261                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1262                 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1263         }
1264
1265         if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1266                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1267         }
1268
1269         /* handle any authentication that is being requested */
1270         if (!auth_ok) {
1271                 if (call->in_auth_info.auth_type !=
1272                     call->conn->auth_state.auth_type)
1273                 {
1274                         return dcesrv_fault_disconnect(call,
1275                                         DCERPC_FAULT_SEC_PKG_ERROR);
1276                 }
1277                 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1278         }
1279
1280         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1281         pkt.auth_length = 0;
1282         pkt.call_id = call->pkt.call_id;
1283         pkt.ptype = DCERPC_PKT_ALTER_RESP;
1284         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1285         pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1286         pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1287         pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1288         pkt.u.alter_resp.secondary_address = "";
1289         pkt.u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1290         pkt.u.alter_resp.ctx_list = ack_ctx_list;
1291         pkt.u.alter_resp.auth_info = data_blob_null;
1292
1293         status = dcesrv_auth_alter_ack(call, &pkt);
1294         if (!NT_STATUS_IS_OK(status)) {
1295                 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1296         }
1297
1298         rep = talloc_zero(call, struct data_blob_list_item);
1299         if (!rep) {
1300                 return NT_STATUS_NO_MEMORY;
1301         }
1302
1303         status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1304         if (!NT_STATUS_IS_OK(status)) {
1305                 return status;
1306         }
1307
1308         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1309
1310         DLIST_ADD_END(call->replies, rep);
1311         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1312
1313         if (call->conn->call_list && call->conn->call_list->replies) {
1314                 if (call->conn->transport.report_output_data) {
1315                         call->conn->transport.report_output_data(call->conn);
1316                 }
1317         }
1318
1319         return NT_STATUS_OK;
1320 }
1321
1322 /*
1323   possibly save the call for inspection with ndrdump
1324  */
1325 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1326 {
1327 #ifdef DEVELOPER
1328         char *fname;
1329         const char *dump_dir;
1330         dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1331         if (!dump_dir) {
1332                 return;
1333         }
1334         fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1335                                 dump_dir,
1336                                 call->context->iface->name,
1337                                 call->pkt.u.request.opnum,
1338                                 why);
1339         if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1340                 DEBUG(0,("RPC SAVED %s\n", fname));
1341         }
1342         talloc_free(fname);
1343 #endif
1344 }
1345
1346 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1347 {
1348         TALLOC_CTX *frame = talloc_stackframe();
1349         const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1350                 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1351         const struct dcerpc_sec_vt_pcontext pcontext = {
1352                 .abstract_syntax = call->context->iface->syntax_id,
1353                 .transfer_syntax = call->context->transfer_syntax,
1354         };
1355         const struct dcerpc_sec_vt_header2 header2 =
1356                 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1357         enum ndr_err_code ndr_err;
1358         struct dcerpc_sec_verification_trailer *vt = NULL;
1359         NTSTATUS status = NT_STATUS_OK;
1360         bool ok;
1361
1362         SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1363
1364         ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1365                                                           frame, &vt);
1366         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1367                 status = ndr_map_error2ntstatus(ndr_err);
1368                 goto done;
1369         }
1370
1371         ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1372                                                    &pcontext, &header2);
1373         if (!ok) {
1374                 status = NT_STATUS_ACCESS_DENIED;
1375                 goto done;
1376         }
1377 done:
1378         TALLOC_FREE(frame);
1379         return status;
1380 }
1381
1382 /*
1383   handle a dcerpc request packet
1384 */
1385 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1386 {
1387         const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1388         enum dcerpc_transport_t transport =
1389                 dcerpc_binding_get_transport(endpoint->ep_description);
1390         struct ndr_pull *pull;
1391         NTSTATUS status;
1392         struct dcesrv_connection_context *context;
1393
1394         if (!call->conn->allow_request) {
1395                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1396         }
1397
1398         /* if authenticated, and the mech we use can't do async replies, don't use them... */
1399         if (call->conn->auth_state.gensec_security && 
1400             !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1401                 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1402         }
1403
1404         context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id);
1405         if (context == NULL) {
1406                 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1407                                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1408         }
1409
1410         switch (call->conn->auth_state.auth_level) {
1411         case DCERPC_AUTH_LEVEL_NONE:
1412         case DCERPC_AUTH_LEVEL_PACKET:
1413         case DCERPC_AUTH_LEVEL_INTEGRITY:
1414         case DCERPC_AUTH_LEVEL_PRIVACY:
1415                 break;
1416         default:
1417                 if (!context->allow_connect) {
1418                         char *addr;
1419
1420                         addr = tsocket_address_string(call->conn->remote_address,
1421                                                       call);
1422
1423                         DEBUG(2, ("%s: restrict auth_level_connect access "
1424                                   "to [%s] with auth[type=0x%x,level=0x%x] "
1425                                   "on [%s] from [%s]\n",
1426                                   __func__, context->iface->name,
1427                                   call->conn->auth_state.auth_type,
1428                                   call->conn->auth_state.auth_level,
1429                                   derpc_transport_string_by_transport(transport),
1430                                   addr));
1431                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1432                 }
1433                 break;
1434         }
1435
1436         if (call->conn->auth_state.auth_level < context->min_auth_level) {
1437                 char *addr;
1438
1439                 addr = tsocket_address_string(call->conn->remote_address, call);
1440
1441                 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1442                           "to [%s] with auth[type=0x%x,level=0x%x] "
1443                           "on [%s] from [%s]\n",
1444                           __func__,
1445                           context->min_auth_level,
1446                           context->iface->name,
1447                           call->conn->auth_state.auth_type,
1448                           call->conn->auth_state.auth_level,
1449                           derpc_transport_string_by_transport(transport),
1450                           addr));
1451                 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1452         }
1453
1454         pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1455         NT_STATUS_HAVE_NO_MEMORY(pull);
1456
1457         pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1458
1459         call->context   = context;
1460         call->ndr_pull  = pull;
1461
1462         if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1463                 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1464         }
1465
1466         status = dcesrv_check_verification_trailer(call);
1467         if (!NT_STATUS_IS_OK(status)) {
1468                 uint32_t faultcode = DCERPC_FAULT_OTHER;
1469                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1470                         faultcode = DCERPC_FAULT_ACCESS_DENIED;
1471                 }
1472                 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1473                            nt_errstr(status)));
1474                 return dcesrv_fault(call, faultcode);
1475         }
1476
1477         /* unravel the NDR for the packet */
1478         status = context->iface->ndr_pull(call, call, pull, &call->r);
1479         if (!NT_STATUS_IS_OK(status)) {
1480                 uint8_t extra_flags = 0;
1481                 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1482                         /* we got an unknown call */
1483                         DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1484                                  call->pkt.u.request.opnum, context->iface->name));
1485                         dcesrv_save_call(call, "unknown");
1486                         extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1487                 } else {
1488                         dcesrv_save_call(call, "pullfail");
1489                 }
1490                 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1491         }
1492
1493         if (pull->offset != pull->data_size) {
1494                 dcesrv_save_call(call, "extrabytes");
1495                 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n", 
1496                          pull->data_size - pull->offset));
1497         }
1498
1499         /* call the dispatch function */
1500         status = context->iface->dispatch(call, call, call->r);
1501         if (!NT_STATUS_IS_OK(status)) {
1502                 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1503                          context->iface->name, 
1504                          call->pkt.u.request.opnum,
1505                          dcerpc_errstr(pull, call->fault_code)));
1506                 return dcesrv_fault(call, call->fault_code);
1507         }
1508
1509         /* add the call to the pending list */
1510         dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1511
1512         if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1513                 return NT_STATUS_OK;
1514         }
1515
1516         return dcesrv_reply(call);
1517 }
1518
1519
1520 /*
1521   remove the call from the right list when freed
1522  */
1523 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1524 {
1525         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1526         return 0;
1527 }
1528
1529 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1530 {
1531         return conn->local_address;
1532 }
1533
1534 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1535 {
1536         return conn->remote_address;
1537 }
1538
1539 /*
1540   process some input to a dcerpc endpoint server.
1541 */
1542 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1543                                             struct ncacn_packet *pkt,
1544                                             DATA_BLOB blob)
1545 {
1546         NTSTATUS status;
1547         struct dcesrv_call_state *call;
1548         struct dcesrv_call_state *existing = NULL;
1549
1550         call = talloc_zero(dce_conn, struct dcesrv_call_state);
1551         if (!call) {
1552                 data_blob_free(&blob);
1553                 talloc_free(pkt);
1554                 return NT_STATUS_NO_MEMORY;
1555         }
1556         call->conn              = dce_conn;
1557         call->event_ctx         = dce_conn->event_ctx;
1558         call->msg_ctx           = dce_conn->msg_ctx;
1559         call->state_flags       = call->conn->state_flags;
1560         call->time              = timeval_current();
1561         call->list              = DCESRV_LIST_NONE;
1562
1563         talloc_steal(call, pkt);
1564         talloc_steal(call, blob.data);
1565         call->pkt = *pkt;
1566
1567         talloc_set_destructor(call, dcesrv_call_dequeue);
1568
1569         if (call->conn->allow_bind) {
1570                 /*
1571                  * Only one bind is possible per connection
1572                  */
1573                 call->conn->allow_bind = false;
1574                 return dcesrv_bind(call);
1575         }
1576
1577         /* we have to check the signing here, before combining the
1578            pdus */
1579         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1580                 if (!call->conn->allow_request) {
1581                         return dcesrv_fault_disconnect(call,
1582                                         DCERPC_NCA_S_PROTO_ERROR);
1583                 }
1584
1585                 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1586                                 DCERPC_PKT_REQUEST,
1587                                 call->pkt.u.request.stub_and_verifier.length,
1588                                 0, /* required_flags */
1589                                 DCERPC_PFC_FLAG_FIRST |
1590                                 DCERPC_PFC_FLAG_LAST |
1591                                 DCERPC_PFC_FLAG_PENDING_CANCEL |
1592                                 0x08 | /* this is not defined, but should be ignored */
1593                                 DCERPC_PFC_FLAG_CONC_MPX |
1594                                 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1595                                 DCERPC_PFC_FLAG_MAYBE |
1596                                 DCERPC_PFC_FLAG_OBJECT_UUID);
1597                 if (!NT_STATUS_IS_OK(status)) {
1598                         return dcesrv_fault_disconnect(call,
1599                                         DCERPC_NCA_S_PROTO_ERROR);
1600                 }
1601
1602                 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1603                         /*
1604                          * We don't use dcesrv_fault_disconnect()
1605                          * here, because we don't want to set
1606                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1607                          *
1608                          * Note that we don't check against the negotiated
1609                          * max_recv_frag, but a hard coded value.
1610                          */
1611                         dcesrv_call_disconnect_after(call,
1612                                 "dcesrv_auth_request - frag_length too large");
1613                         return dcesrv_fault(call,
1614                                         DCERPC_NCA_S_PROTO_ERROR);
1615                 }
1616
1617                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1618                         /* only one request is possible in the fragmented list */
1619                         if (dce_conn->incoming_fragmented_call_list != NULL) {
1620                                 TALLOC_FREE(call);
1621                                 call = dce_conn->incoming_fragmented_call_list;
1622                                 dcesrv_call_disconnect_after(call,
1623                                         "dcesrv_auth_request - "
1624                                         "existing fragmented call");
1625                                 return dcesrv_fault(call,
1626                                                 DCERPC_NCA_S_PROTO_ERROR);
1627                         }
1628                         if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1629                                 return dcesrv_fault_disconnect(call,
1630                                                 DCERPC_FAULT_NO_CALL_ACTIVE);
1631                         }
1632                 } else {
1633                         const struct dcerpc_request *nr = &call->pkt.u.request;
1634                         const struct dcerpc_request *er = NULL;
1635                         int cmp;
1636
1637                         existing = dcesrv_find_fragmented_call(dce_conn,
1638                                                         call->pkt.call_id);
1639                         if (existing == NULL) {
1640                                 dcesrv_call_disconnect_after(call,
1641                                         "dcesrv_auth_request - "
1642                                         "no existing fragmented call");
1643                                 return dcesrv_fault(call,
1644                                                 DCERPC_NCA_S_PROTO_ERROR);
1645                         }
1646                         er = &existing->pkt.u.request;
1647
1648                         if (call->pkt.ptype != existing->pkt.ptype) {
1649                                 /* trying to play silly buggers are we? */
1650                                 return dcesrv_fault_disconnect(existing,
1651                                                 DCERPC_NCA_S_PROTO_ERROR);
1652                         }
1653                         cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1654                                      sizeof(pkt->drep));
1655                         if (cmp != 0) {
1656                                 return dcesrv_fault_disconnect(existing,
1657                                                 DCERPC_NCA_S_PROTO_ERROR);
1658                         }
1659                         if (nr->context_id != er->context_id)  {
1660                                 return dcesrv_fault_disconnect(existing,
1661                                                 DCERPC_NCA_S_PROTO_ERROR);
1662                         }
1663                         if (nr->opnum != er->opnum)  {
1664                                 return dcesrv_fault_disconnect(existing,
1665                                                 DCERPC_NCA_S_PROTO_ERROR);
1666                         }
1667                 }
1668         }
1669
1670         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1671                 bool ok;
1672                 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1673
1674                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1675                         payload_offset += 16;
1676                 }
1677
1678                 ok = dcesrv_auth_pkt_pull(call, &blob,
1679                                           0, /* required_flags */
1680                                           DCERPC_PFC_FLAG_FIRST |
1681                                           DCERPC_PFC_FLAG_LAST |
1682                                           DCERPC_PFC_FLAG_PENDING_CANCEL |
1683                                           0x08 | /* this is not defined, but should be ignored */
1684                                           DCERPC_PFC_FLAG_CONC_MPX |
1685                                           DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1686                                           DCERPC_PFC_FLAG_MAYBE |
1687                                           DCERPC_PFC_FLAG_OBJECT_UUID,
1688                                           payload_offset,
1689                                           &call->pkt.u.request.stub_and_verifier);
1690                 if (!ok) {
1691                         /*
1692                          * We don't use dcesrv_fault_disconnect()
1693                          * here, because we don't want to set
1694                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1695                          */
1696                         dcesrv_call_disconnect_after(call,
1697                                                 "dcesrv_auth_request - failed");
1698                         if (call->fault_code == 0) {
1699                                 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1700                         }
1701                         return dcesrv_fault(call, call->fault_code);
1702                 }
1703         }
1704
1705         /* see if this is a continued packet */
1706         if (existing != NULL) {
1707                 struct dcerpc_request *er = &existing->pkt.u.request;
1708                 const struct dcerpc_request *nr = &call->pkt.u.request;
1709                 size_t available;
1710                 size_t alloc_size;
1711                 size_t alloc_hint;
1712
1713                 /*
1714                  * Up to 4 MByte are allowed by all fragments
1715                  */
1716                 available = dce_conn->max_total_request_size;
1717                 if (er->stub_and_verifier.length > available) {
1718                         dcesrv_call_disconnect_after(existing,
1719                                 "dcesrv_auth_request - existing payload too large");
1720                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1721                 }
1722                 available -= er->stub_and_verifier.length;
1723                 if (nr->alloc_hint > available) {
1724                         dcesrv_call_disconnect_after(existing,
1725                                 "dcesrv_auth_request - alloc hint too large");
1726                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1727                 }
1728                 if (nr->stub_and_verifier.length > available) {
1729                         dcesrv_call_disconnect_after(existing,
1730                                 "dcesrv_auth_request - new payload too large");
1731                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1732                 }
1733                 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1734                 /* allocate at least 1 byte */
1735                 alloc_hint = MAX(alloc_hint, 1);
1736                 alloc_size = er->stub_and_verifier.length +
1737                              nr->stub_and_verifier.length;
1738                 alloc_size = MAX(alloc_size, alloc_hint);
1739
1740                 er->stub_and_verifier.data =
1741                         talloc_realloc(existing,
1742                                        er->stub_and_verifier.data,
1743                                        uint8_t, alloc_size);
1744                 if (er->stub_and_verifier.data == NULL) {
1745                         TALLOC_FREE(call);
1746                         return dcesrv_fault_with_flags(existing,
1747                                                        DCERPC_FAULT_OUT_OF_RESOURCES,
1748                                                        DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1749                 }
1750                 memcpy(er->stub_and_verifier.data +
1751                        er->stub_and_verifier.length,
1752                        nr->stub_and_verifier.data,
1753                        nr->stub_and_verifier.length);
1754                 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1755
1756                 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1757
1758                 TALLOC_FREE(call);
1759                 call = existing;
1760         }
1761
1762         /* this may not be the last pdu in the chain - if its isn't then
1763            just put it on the incoming_fragmented_call_list and wait for the rest */
1764         if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1765             !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1766                 /*
1767                  * Up to 4 MByte are allowed by all fragments
1768                  */
1769                 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1770                         dcesrv_call_disconnect_after(call,
1771                                 "dcesrv_auth_request - initial alloc hint too large");
1772                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1773                 }
1774                 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1775                 return NT_STATUS_OK;
1776         } 
1777         
1778         /* This removes any fragments we may have had stashed away */
1779         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1780
1781         switch (call->pkt.ptype) {
1782         case DCERPC_PKT_BIND:
1783                 status = dcesrv_bind_nak(call,
1784                         DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1785                 break;
1786         case DCERPC_PKT_AUTH3:
1787                 status = dcesrv_auth3(call);
1788                 break;
1789         case DCERPC_PKT_ALTER:
1790                 status = dcesrv_alter(call);
1791                 break;
1792         case DCERPC_PKT_REQUEST:
1793                 status = dcesrv_request(call);
1794                 break;
1795         case DCERPC_PKT_CO_CANCEL:
1796         case DCERPC_PKT_ORPHANED:
1797                 /*
1798                  * Window just ignores CO_CANCEL and ORPHANED,
1799                  * so we do...
1800                  */
1801                 status = NT_STATUS_OK;
1802                 TALLOC_FREE(call);
1803                 break;
1804         case DCERPC_PKT_BIND_ACK:
1805         case DCERPC_PKT_BIND_NAK:
1806         case DCERPC_PKT_ALTER_RESP:
1807         case DCERPC_PKT_RESPONSE:
1808         case DCERPC_PKT_FAULT:
1809         case DCERPC_PKT_SHUTDOWN:
1810         default:
1811                 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1812                 break;
1813         }
1814
1815         /* if we are going to be sending a reply then add
1816            it to the list of pending calls. We add it to the end to keep the call
1817            list in the order we will answer */
1818         if (!NT_STATUS_IS_OK(status)) {
1819                 talloc_free(call);
1820         }
1821
1822         return status;
1823 }
1824
1825 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, 
1826                                       struct loadparm_context *lp_ctx,
1827                                       const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1828 {
1829         NTSTATUS status;
1830         struct dcesrv_context *dce_ctx;
1831         int i;
1832
1833         if (!endpoint_servers) {
1834                 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1835                 return NT_STATUS_INTERNAL_ERROR;
1836         }
1837
1838         dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
1839         NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
1840
1841         if (uid_wrapper_enabled()) {
1842                 setenv("UID_WRAPPER_MYUID", "1", 1);
1843         }
1844         dce_ctx->initial_euid = geteuid();
1845         if (uid_wrapper_enabled()) {
1846                 unsetenv("UID_WRAPPER_MYUID");
1847         }
1848
1849         dce_ctx->endpoint_list  = NULL;
1850         dce_ctx->lp_ctx = lp_ctx;
1851         dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
1852         NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
1853         dce_ctx->broken_connections = NULL;
1854
1855         for (i=0;endpoint_servers[i];i++) {
1856                 const struct dcesrv_endpoint_server *ep_server;
1857
1858                 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
1859                 if (!ep_server) {
1860                         DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
1861                         return NT_STATUS_INTERNAL_ERROR;
1862                 }
1863
1864                 status = ep_server->init_server(dce_ctx, ep_server);
1865                 if (!NT_STATUS_IS_OK(status)) {
1866                         DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
1867                                 nt_errstr(status)));
1868                         return status;
1869                 }
1870         }
1871
1872         *_dce_ctx = dce_ctx;
1873         return NT_STATUS_OK;
1874 }
1875
1876 /* the list of currently registered DCERPC endpoint servers.
1877  */
1878 static struct ep_server {
1879         struct dcesrv_endpoint_server *ep_server;
1880 } *ep_servers = NULL;
1881 static int num_ep_servers;
1882
1883 /*
1884   register a DCERPC endpoint server. 
1885
1886   The 'name' can be later used by other backends to find the operations
1887   structure for this backend.  
1888
1889   The 'type' is used to specify whether this is for a disk, printer or IPC$ share
1890 */
1891 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const void *_ep_server)
1892 {
1893         const struct dcesrv_endpoint_server *ep_server = _ep_server;
1894         
1895         if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1896                 /* its already registered! */
1897                 DEBUG(0,("DCERPC endpoint server '%s' already registered\n", 
1898                          ep_server->name));
1899                 return NT_STATUS_OBJECT_NAME_COLLISION;
1900         }
1901
1902         ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1903         if (!ep_servers) {
1904                 smb_panic("out of memory in dcerpc_register");
1905         }
1906
1907         ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1908         ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1909
1910         num_ep_servers++;
1911
1912         DEBUG(3,("DCERPC endpoint server '%s' registered\n", 
1913                  ep_server->name));
1914
1915         return NT_STATUS_OK;
1916 }
1917
1918 /*
1919   return the operations structure for a named backend of the specified type
1920 */
1921 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1922 {
1923         int i;
1924
1925         for (i=0;i<num_ep_servers;i++) {
1926                 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1927                         return ep_servers[i].ep_server;
1928                 }
1929         }
1930
1931         return NULL;
1932 }
1933
1934 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1935 {
1936         static bool initialized;
1937 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1938         STATIC_dcerpc_server_MODULES_PROTO;
1939         init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1940         init_module_fn *shared_init;
1941
1942         if (initialized) {
1943                 return;
1944         }
1945         initialized = true;
1946
1947         shared_init = load_samba_modules(NULL, "dcerpc_server");
1948
1949         run_init_functions(static_init);
1950         run_init_functions(shared_init);
1951
1952         talloc_free(shared_init);
1953 }
1954
1955 /*
1956   return the DCERPC module version, and the size of some critical types
1957   This can be used by endpoint server modules to either detect compilation errors, or provide
1958   multiple implementations for different smbd compilation options in one module
1959 */
1960 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1961 {
1962         static const struct dcesrv_critical_sizes critical_sizes = {
1963                 DCERPC_MODULE_VERSION,
1964                 sizeof(struct dcesrv_context),
1965                 sizeof(struct dcesrv_endpoint),
1966                 sizeof(struct dcesrv_endpoint_server),
1967                 sizeof(struct dcesrv_interface),
1968                 sizeof(struct dcesrv_if_list),
1969                 sizeof(struct dcesrv_connection),
1970                 sizeof(struct dcesrv_call_state),
1971                 sizeof(struct dcesrv_auth),
1972                 sizeof(struct dcesrv_handle)
1973         };
1974
1975         return &critical_sizes;
1976 }
1977
1978 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
1979 {
1980         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
1981         struct stream_connection *srv_conn;
1982         srv_conn = talloc_get_type(dce_conn->transport.private_data,
1983                                    struct stream_connection);
1984
1985         dce_conn->allow_bind = false;
1986         dce_conn->allow_auth3 = false;
1987         dce_conn->allow_alter = false;
1988         dce_conn->allow_request = false;
1989
1990         if (dce_conn->pending_call_list == NULL) {
1991                 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
1992
1993                 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
1994                 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
1995                 return;
1996         }
1997
1998         if (dce_conn->terminate != NULL) {
1999                 return;
2000         }
2001
2002         DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
2003                  reason));
2004         dce_conn->terminate = talloc_strdup(dce_conn, reason);
2005         if (dce_conn->terminate == NULL) {
2006                 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
2007         }
2008         DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2009 }
2010
2011 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2012 {
2013         struct dcesrv_connection *cur, *next;
2014
2015         next = dce_ctx->broken_connections;
2016         while (next != NULL) {
2017                 cur = next;
2018                 next = cur->next;
2019
2020                 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2021                         struct dcesrv_connection_context *context_cur, *context_next;
2022
2023                         context_next = cur->contexts;
2024                         while (context_next != NULL) {
2025                                 context_cur = context_next;
2026                                 context_next = context_cur->next;
2027
2028                                 dcesrv_connection_context_destructor(context_cur);
2029                         }
2030                 }
2031
2032                 dcesrv_terminate_connection(cur, cur->terminate);
2033         }
2034 }
2035
2036 /* We need this include to be able to compile on some plateforms
2037  * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2038  * correctly.
2039  * It has to be that deep because otherwise we have a conflict on
2040  * const struct dcesrv_interface declaration.
2041  * This is mostly due to socket_wrapper defining #define bind swrap_bind
2042  * which conflict with the bind used before.
2043  */
2044 #include "system/network.h"
2045
2046 struct dcesrv_sock_reply_state {
2047         struct dcesrv_connection *dce_conn;
2048         struct dcesrv_call_state *call;
2049         struct iovec iov;
2050 };
2051
2052 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2053 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2054
2055 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2056 {
2057         struct dcesrv_call_state *call;
2058
2059         call = dce_conn->call_list;
2060         if (!call || !call->replies) {
2061                 return;
2062         }
2063
2064         while (call->replies) {
2065                 struct data_blob_list_item *rep = call->replies;
2066                 struct dcesrv_sock_reply_state *substate;
2067                 struct tevent_req *subreq;
2068
2069                 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2070                 if (!substate) {
2071                         dcesrv_terminate_connection(dce_conn, "no memory");
2072                         return;
2073                 }
2074
2075                 substate->dce_conn = dce_conn;
2076                 substate->call = NULL;
2077
2078                 DLIST_REMOVE(call->replies, rep);
2079
2080                 if (call->replies == NULL && call->terminate_reason == NULL) {
2081                         substate->call = call;
2082                 }
2083
2084                 substate->iov.iov_base = (void *) rep->blob.data;
2085                 substate->iov.iov_len = rep->blob.length;
2086
2087                 subreq = tstream_writev_queue_send(substate,
2088                                                    dce_conn->event_ctx,
2089                                                    dce_conn->stream,
2090                                                    dce_conn->send_queue,
2091                                                    &substate->iov, 1);
2092                 if (!subreq) {
2093                         dcesrv_terminate_connection(dce_conn, "no memory");
2094                         return;
2095                 }
2096                 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2097                                         substate);
2098         }
2099
2100         if (call->terminate_reason != NULL) {
2101                 struct tevent_req *subreq;
2102
2103                 subreq = tevent_queue_wait_send(call,
2104                                                 dce_conn->event_ctx,
2105                                                 dce_conn->send_queue);
2106                 if (!subreq) {
2107                         dcesrv_terminate_connection(dce_conn, __location__);
2108                         return;
2109                 }
2110                 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2111                                         call);
2112         }
2113
2114         DLIST_REMOVE(call->conn->call_list, call);
2115         call->list = DCESRV_LIST_NONE;
2116 }
2117
2118 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2119 {
2120         struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2121                                                 struct dcesrv_sock_reply_state);
2122         int ret;
2123         int sys_errno;
2124         NTSTATUS status;
2125         struct dcesrv_call_state *call = substate->call;
2126
2127         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2128         TALLOC_FREE(subreq);
2129         if (ret == -1) {
2130                 status = map_nt_error_from_unix_common(sys_errno);
2131                 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2132                 return;
2133         }
2134
2135         talloc_free(substate);
2136         if (call) {
2137                 talloc_free(call);
2138         }
2139 }
2140
2141 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2142
2143 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2144 {
2145         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2146                                                 struct dcesrv_call_state);
2147         bool ok;
2148         struct timeval tv;
2149
2150         /* make sure we stop send queue before removing subreq */
2151         tevent_queue_stop(call->conn->send_queue);
2152
2153         ok = tevent_queue_wait_recv(subreq);
2154         TALLOC_FREE(subreq);
2155         if (!ok) {
2156                 dcesrv_terminate_connection(call->conn, __location__);
2157                 return;
2158         }
2159
2160         /* disconnect after 200 usecs */
2161         tv = timeval_current_ofs_usec(200);
2162         subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2163         if (subreq == NULL) {
2164                 dcesrv_terminate_connection(call->conn, __location__);
2165                 return;
2166         }
2167         tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2168                                 call);
2169 }
2170
2171 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2172 {
2173         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2174                                                 struct dcesrv_call_state);
2175         bool ok;
2176
2177         ok = tevent_wakeup_recv(subreq);
2178         TALLOC_FREE(subreq);
2179         if (!ok) {
2180                 dcesrv_terminate_connection(call->conn, __location__);
2181                 return;
2182         }
2183
2184         dcesrv_terminate_connection(call->conn, call->terminate_reason);
2185 }
2186
2187 struct dcesrv_socket_context {
2188         const struct dcesrv_endpoint *endpoint;
2189         struct dcesrv_context *dcesrv_ctx;
2190 };
2191
2192
2193 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2194
2195 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2196 {
2197         NTSTATUS status;
2198         struct dcesrv_socket_context *dcesrv_sock = 
2199                 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2200         enum dcerpc_transport_t transport =
2201                 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2202         struct dcesrv_connection *dcesrv_conn = NULL;
2203         int ret;
2204         struct tevent_req *subreq;
2205         struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2206
2207         dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2208
2209         if (!srv_conn->session_info) {
2210                 status = auth_anonymous_session_info(srv_conn,
2211                                                      lp_ctx,
2212                                                      &srv_conn->session_info);
2213                 if (!NT_STATUS_IS_OK(status)) {
2214                         DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2215                                 nt_errstr(status)));
2216                         stream_terminate_connection(srv_conn, nt_errstr(status));
2217                         return;
2218                 }
2219         }
2220
2221         status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2222                                          srv_conn,
2223                                          dcesrv_sock->endpoint,
2224                                          srv_conn->session_info,
2225                                          srv_conn->event.ctx,
2226                                          srv_conn->msg_ctx,
2227                                          srv_conn->server_id,
2228                                          DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2229                                          &dcesrv_conn);
2230         if (!NT_STATUS_IS_OK(status)) {
2231                 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
2232                         nt_errstr(status)));
2233                 stream_terminate_connection(srv_conn, nt_errstr(status));
2234                 return;
2235         }
2236
2237         dcesrv_conn->transport.private_data             = srv_conn;
2238         dcesrv_conn->transport.report_output_data       = dcesrv_sock_report_output_data;
2239
2240         TALLOC_FREE(srv_conn->event.fde);
2241
2242         dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2243         if (!dcesrv_conn->send_queue) {
2244                 status = NT_STATUS_NO_MEMORY;
2245                 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2246                         nt_errstr(status)));
2247                 stream_terminate_connection(srv_conn, nt_errstr(status));
2248                 return;
2249         }
2250
2251         if (transport == NCACN_NP) {
2252                 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2253                 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2254                                                   &srv_conn->tstream);
2255         } else {
2256                 ret = tstream_bsd_existing_socket(dcesrv_conn,
2257                                                   socket_get_fd(srv_conn->socket),
2258                                                   &dcesrv_conn->stream);
2259                 if (ret == -1) {
2260                         status = map_nt_error_from_unix_common(errno);
2261                         DEBUG(0, ("dcesrv_sock_accept: "
2262                                   "failed to setup tstream: %s\n",
2263                                   nt_errstr(status)));
2264                         stream_terminate_connection(srv_conn, nt_errstr(status));
2265                         return;
2266                 }
2267                 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2268         }
2269
2270         dcesrv_conn->local_address = srv_conn->local_address;
2271         dcesrv_conn->remote_address = srv_conn->remote_address;
2272
2273         if (transport == NCALRPC) {
2274                 uid_t uid;
2275                 gid_t gid;
2276                 int sock_fd;
2277
2278                 sock_fd = socket_get_fd(srv_conn->socket);
2279                 if (sock_fd == -1) {
2280                         stream_terminate_connection(
2281                                 srv_conn, "socket_get_fd failed\n");
2282                         return;
2283                 }
2284
2285                 ret = getpeereid(sock_fd, &uid, &gid);
2286                 if (ret == -1) {
2287                         status = map_nt_error_from_unix_common(errno);
2288                         DEBUG(0, ("dcesrv_sock_accept: "
2289                                   "getpeereid() failed for NCALRPC: %s\n",
2290                                   nt_errstr(status)));
2291                         stream_terminate_connection(srv_conn, nt_errstr(status));
2292                         return;
2293                 }
2294                 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2295                         struct tsocket_address *r = NULL;
2296
2297                         ret = tsocket_address_unix_from_path(dcesrv_conn,
2298                                                              "/root/ncalrpc_as_system",
2299                                                              &r);
2300                         if (ret == -1) {
2301                                 status = map_nt_error_from_unix_common(errno);
2302                                 DEBUG(0, ("dcesrv_sock_accept: "
2303                                           "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2304                                           nt_errstr(status)));
2305                                 stream_terminate_connection(srv_conn, nt_errstr(status));
2306                                 return;
2307                         }
2308                         dcesrv_conn->remote_address = r;
2309                 }
2310         }
2311
2312         srv_conn->private_data = dcesrv_conn;
2313
2314         irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2315
2316         subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2317                                                dcesrv_conn->event_ctx,
2318                                                dcesrv_conn->stream);
2319         if (!subreq) {
2320                 status = NT_STATUS_NO_MEMORY;
2321                 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2322                         nt_errstr(status)));
2323                 stream_terminate_connection(srv_conn, nt_errstr(status));
2324                 return;
2325         }
2326         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2327
2328         return;
2329 }
2330
2331 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2332 {
2333         struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2334                                              struct dcesrv_connection);
2335         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2336         struct ncacn_packet *pkt;
2337         DATA_BLOB buffer;
2338         NTSTATUS status;
2339
2340         if (dce_conn->terminate) {
2341                 /*
2342                  * if the current connection is broken
2343                  * we need to clean it up before any other connection
2344                  */
2345                 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2346                 dcesrv_cleanup_broken_connections(dce_ctx);
2347                 return;
2348         }
2349
2350         dcesrv_cleanup_broken_connections(dce_ctx);
2351
2352         status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2353                                                &pkt, &buffer);
2354         TALLOC_FREE(subreq);
2355         if (!NT_STATUS_IS_OK(status)) {
2356                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2357                 return;
2358         }
2359
2360         status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2361         if (!NT_STATUS_IS_OK(status)) {
2362                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2363                 return;
2364         }
2365
2366         subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2367                                                dce_conn->event_ctx,
2368                                                dce_conn->stream);
2369         if (!subreq) {
2370                 status = NT_STATUS_NO_MEMORY;
2371                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2372                 return;
2373         }
2374         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2375 }
2376
2377 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2378 {
2379         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2380                                              struct dcesrv_connection);
2381         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2382 }
2383
2384 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2385 {
2386         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2387                                              struct dcesrv_connection);
2388         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2389 }
2390
2391
2392 static const struct stream_server_ops dcesrv_stream_ops = {
2393         .name                   = "rpc",
2394         .accept_connection      = dcesrv_sock_accept,
2395         .recv_handler           = dcesrv_sock_recv,
2396         .send_handler           = dcesrv_sock_send,
2397 };
2398
2399 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 
2400                                    struct loadparm_context *lp_ctx,
2401                                    struct dcesrv_endpoint *e,
2402                             struct tevent_context *event_ctx, const struct model_ops *model_ops)
2403 {
2404         struct dcesrv_socket_context *dcesrv_sock;
2405         uint16_t port = 1;
2406         NTSTATUS status;
2407         const char *endpoint;
2408
2409         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2410         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2411
2412         /* remember the endpoint of this socket */
2413         dcesrv_sock->endpoint           = e;
2414         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2415
2416         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2417
2418         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2419                                      model_ops, &dcesrv_stream_ops, 
2420                                      "unix", endpoint, &port,
2421                                      lpcfg_socket_options(lp_ctx),
2422                                      dcesrv_sock);
2423         if (!NT_STATUS_IS_OK(status)) {
2424                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2425                          endpoint, nt_errstr(status)));
2426         }
2427
2428         return status;
2429 }
2430
2431 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 
2432                                       struct loadparm_context *lp_ctx,
2433                                       struct dcesrv_endpoint *e,
2434                                       struct tevent_context *event_ctx, const struct model_ops *model_ops)
2435 {
2436         struct dcesrv_socket_context *dcesrv_sock;
2437         uint16_t port = 1;
2438         char *full_path;
2439         NTSTATUS status;
2440         const char *endpoint;
2441
2442         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2443
2444         if (endpoint == NULL) {
2445                 /*
2446                  * No identifier specified: use DEFAULT.
2447                  *
2448                  * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2449                  * no endpoint and let the epmapper worry about it.
2450                  */
2451                 endpoint = "DEFAULT";
2452                 status = dcerpc_binding_set_string_option(e->ep_description,
2453                                                           "endpoint",
2454                                                           endpoint);
2455                 if (!NT_STATUS_IS_OK(status)) {
2456                         DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2457                                   nt_errstr(status)));
2458                         return status;
2459                 }
2460         }
2461
2462         full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2463                                     endpoint);
2464
2465         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2466         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2467
2468         /* remember the endpoint of this socket */
2469         dcesrv_sock->endpoint           = e;
2470         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2471
2472         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2473                                      model_ops, &dcesrv_stream_ops, 
2474                                      "unix", full_path, &port, 
2475                                      lpcfg_socket_options(lp_ctx),
2476                                      dcesrv_sock);
2477         if (!NT_STATUS_IS_OK(status)) {
2478                 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2479                          endpoint, full_path, nt_errstr(status)));
2480         }
2481         return status;
2482 }
2483
2484 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2485                                  struct loadparm_context *lp_ctx,
2486                                  struct dcesrv_endpoint *e,
2487                                  struct tevent_context *event_ctx, const struct model_ops *model_ops)
2488 {
2489         struct dcesrv_socket_context *dcesrv_sock;
2490         NTSTATUS status;
2491         const char *endpoint;
2492
2493         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2494         if (endpoint == NULL) {
2495                 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2496                 return NT_STATUS_INVALID_PARAMETER;
2497         }
2498
2499         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2500         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2501
2502         /* remember the endpoint of this socket */
2503         dcesrv_sock->endpoint           = e;
2504         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2505
2506         status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2507                                           model_ops, &dcesrv_stream_ops,
2508                                           endpoint,
2509                                           dcesrv_sock);
2510         if (!NT_STATUS_IS_OK(status)) {
2511                 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2512                          endpoint, nt_errstr(status)));
2513                 return status;
2514         }
2515
2516         return NT_STATUS_OK;
2517 }
2518
2519 /*
2520   add a socket address to the list of events, one event per dcerpc endpoint
2521 */
2522 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2523                                          struct tevent_context *event_ctx, const struct model_ops *model_ops,
2524                                          const char *address)
2525 {
2526         struct dcesrv_socket_context *dcesrv_sock;
2527         uint16_t port = 0;
2528         NTSTATUS status;
2529         const char *endpoint;
2530         char port_str[6];
2531
2532         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2533         if (endpoint != NULL) {
2534                 port = atoi(endpoint);
2535         }
2536
2537         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2538         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2539
2540         /* remember the endpoint of this socket */
2541         dcesrv_sock->endpoint           = e;
2542         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2543
2544         status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2545                                      model_ops, &dcesrv_stream_ops, 
2546                                      "ip", address, &port,
2547                                      lpcfg_socket_options(dce_ctx->lp_ctx),
2548                                      dcesrv_sock);
2549         if (!NT_STATUS_IS_OK(status)) {
2550                 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n", 
2551                          address, port, nt_errstr(status)));
2552                 return status;
2553         }
2554
2555         snprintf(port_str, sizeof(port_str), "%u", port);
2556
2557         status = dcerpc_binding_set_string_option(e->ep_description,
2558                                                   "endpoint", port_str);
2559         if (!NT_STATUS_IS_OK(status)) {
2560                 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2561                          port_str, nt_errstr(status)));
2562                 return status;
2563         }
2564
2565         return NT_STATUS_OK;
2566 }
2567
2568 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2569
2570 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 
2571                                   struct loadparm_context *lp_ctx,
2572                                   struct dcesrv_endpoint *e,
2573                                   struct tevent_context *event_ctx, const struct model_ops *model_ops)
2574 {
2575         NTSTATUS status;
2576
2577         /* Add TCP/IP sockets */
2578         if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2579                 int num_interfaces;
2580                 int i;
2581                 struct interface *ifaces;
2582
2583                 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2584
2585                 num_interfaces = iface_list_count(ifaces);
2586                 for(i = 0; i < num_interfaces; i++) {
2587                         const char *address = iface_list_n_ip(ifaces, i);
2588                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2589                         NT_STATUS_NOT_OK_RETURN(status);
2590                 }
2591         } else {
2592                 char **wcard;
2593                 int i;
2594                 int num_binds = 0;
2595                 wcard = iface_list_wildcard(dce_ctx);
2596                 NT_STATUS_HAVE_NO_MEMORY(wcard);
2597                 for (i=0; wcard[i]; i++) {
2598                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2599                         if (NT_STATUS_IS_OK(status)) {
2600                                 num_binds++;
2601                         }
2602                 }
2603                 talloc_free(wcard);
2604                 if (num_binds == 0) {
2605                         return NT_STATUS_INVALID_PARAMETER_MIX;
2606                 }
2607         }
2608
2609         return NT_STATUS_OK;
2610 }
2611
2612 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2613                        struct loadparm_context *lp_ctx,
2614                        struct dcesrv_endpoint *e,
2615                        struct tevent_context *event_ctx,
2616                        const struct model_ops *model_ops)
2617 {
2618         enum dcerpc_transport_t transport =
2619                 dcerpc_binding_get_transport(e->ep_description);
2620
2621         switch (transport) {
2622         case NCACN_UNIX_STREAM:
2623                 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2624
2625         case NCALRPC:
2626                 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2627
2628         case NCACN_IP_TCP:
2629                 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2630
2631         case NCACN_NP:
2632                 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2633
2634         default:
2635                 return NT_STATUS_NOT_SUPPORTED;
2636         }
2637 }
2638
2639
2640 /**
2641  * retrieve credentials from a dce_call
2642  */
2643 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2644 {
2645         return dce_call->conn->auth_state.session_info->credentials;
2646 }
2647
2648 /**
2649  * returns true if this is an authenticated call
2650  */
2651 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2652 {
2653         enum security_user_level level;
2654         level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2655         return level >= SECURITY_USER;
2656 }
2657
2658 /**
2659  * retrieve account_name for a dce_call
2660  */
2661 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2662 {
2663         return dce_call->context->conn->auth_state.session_info->info->account_name;
2664 }