s4/rpc_server: Show what RPC interfaces are listening on which TCP port
[samba.git] / source4 / rpc_server / dcerpc_server.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    server side dcerpc core code
5
6    Copyright (C) Andrew Tridgell 2003-2005
7    Copyright (C) Stefan (metze) Metzmacher 2004-2005
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "../lib/util/dlinklist.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/dcerpc_server_proto.h"
29 #include "rpc_server/common/proto.h"
30 #include "librpc/rpc/dcerpc_proto.h"
31 #include "system/filesys.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "../lib/tsocket/tsocket.h"
35 #include "../libcli/named_pipe_auth/npa_tstream.h"
36 #include "smbd/service_stream.h"
37 #include "../lib/tsocket/tsocket.h"
38 #include "lib/socket/socket.h"
39 #include "smbd/process_model.h"
40 #include "lib/messaging/irpc.h"
41 #include "librpc/rpc/rpc_common.h"
42 #include "lib/util/samba_modules.h"
43 #include "librpc/gen_ndr/ndr_dcerpc.h"
44
45 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                         a->reason.negotiate |=
790                                 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
791                 }
792
793                 call->conn->bind_time_features = a->reason.negotiate;
794         }
795
796         /*
797          * Try to negotiate one new presentation context.
798          */
799         status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
800         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
801                 return dcesrv_bind_nak(call, 0);
802         }
803         if (!NT_STATUS_IS_OK(status)) {
804                 return status;
805         }
806
807         if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
808             (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
809                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
810                 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
811         }
812
813         if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
814                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
815         }
816
817         /* handle any authentication that is being requested */
818         if (!dcesrv_auth_bind(call)) {
819                 struct dcesrv_auth *auth = &call->conn->auth_state;
820
821                 TALLOC_FREE(call->context);
822
823                 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
824                         /*
825                          * With DCERPC_AUTH_LEVEL_NONE, we get the
826                          * reject_reason in auth->auth_context_id.
827                          */
828                         return dcesrv_bind_nak(call, auth->auth_context_id);
829                 }
830
831                 /*
832                  * This must a be a temporary failure e.g. talloc or invalid
833                  * configuration, e.g. no machine account.
834                  */
835                 return dcesrv_bind_nak(call,
836                                 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
837         }
838
839         /* setup a bind_ack */
840         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
841         pkt.auth_length = 0;
842         pkt.call_id = call->pkt.call_id;
843         pkt.ptype = DCERPC_PKT_BIND_ACK;
844         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
845         pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
846         pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
847         pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
848
849         endpoint = dcerpc_binding_get_string_option(
850                                 call->conn->endpoint->ep_description,
851                                 "endpoint");
852         if (endpoint == NULL) {
853                 endpoint = "";
854         }
855
856         if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
857                 /*
858                  * TODO: check if this is really needed
859                  *
860                  * Or if we should fix this in our idl files.
861                  */
862                 ep_prefix = "\\PIPE\\";
863                 endpoint += 6;
864         }
865
866         pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
867                                                            ep_prefix,
868                                                            endpoint);
869         if (pkt.u.bind_ack.secondary_address == NULL) {
870                 TALLOC_FREE(call->context);
871                 return NT_STATUS_NO_MEMORY;
872         }
873         pkt.u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
874         pkt.u.bind_ack.ctx_list = ack_ctx_list;
875         pkt.u.bind_ack.auth_info = data_blob_null;
876
877         status = dcesrv_auth_bind_ack(call, &pkt);
878         if (!NT_STATUS_IS_OK(status)) {
879                 TALLOC_FREE(call->context);
880                 return dcesrv_bind_nak(call, 0);
881         }
882
883         rep = talloc_zero(call, struct data_blob_list_item);
884         if (!rep) {
885                 TALLOC_FREE(call->context);
886                 return NT_STATUS_NO_MEMORY;
887         }
888
889         status = ncacn_push_auth(&rep->blob, call, &pkt,
890                                  call->out_auth_info);
891         if (!NT_STATUS_IS_OK(status)) {
892                 TALLOC_FREE(call->context);
893                 return status;
894         }
895
896         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
897
898         DLIST_ADD_END(call->replies, rep);
899         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
900
901         if (call->conn->call_list && call->conn->call_list->replies) {
902                 if (call->conn->transport.report_output_data) {
903                         call->conn->transport.report_output_data(call->conn);
904                 }
905         }
906
907         return NT_STATUS_OK;
908 }
909
910
911 /*
912   handle a auth3 request
913 */
914 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
915 {
916         NTSTATUS status;
917
918         if (!call->conn->allow_auth3) {
919                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
920         }
921
922         if (call->conn->auth_state.auth_finished) {
923                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
924         }
925
926         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
927                         DCERPC_PKT_AUTH3,
928                         call->pkt.u.auth3.auth_info.length,
929                         0, /* required flags */
930                         DCERPC_PFC_FLAG_FIRST |
931                         DCERPC_PFC_FLAG_LAST |
932                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
933                         0x08 | /* this is not defined, but should be ignored */
934                         DCERPC_PFC_FLAG_CONC_MPX |
935                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
936                         DCERPC_PFC_FLAG_MAYBE |
937                         DCERPC_PFC_FLAG_OBJECT_UUID);
938         if (!NT_STATUS_IS_OK(status)) {
939                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
940         }
941
942         /* handle the auth3 in the auth code */
943         if (!dcesrv_auth_auth3(call)) {
944                 call->conn->auth_state.auth_invalid = true;
945                 if (call->fault_code != 0) {
946                         return dcesrv_fault_disconnect(call, call->fault_code);
947                 }
948         }
949
950         talloc_free(call);
951
952         /* we don't send a reply to a auth3 request, except by a
953            fault */
954         return NT_STATUS_OK;
955 }
956
957
958 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
959                                 const struct dcerpc_bind *b,
960                                 const struct dcerpc_ctx_list *ctx,
961                                 struct dcerpc_ack_ctx *ack,
962                                 bool validate_only,
963                                 const struct ndr_syntax_id *supported_transfer)
964 {
965         uint32_t if_version;
966         struct dcesrv_connection_context *context;
967         const struct dcesrv_interface *iface;
968         struct GUID uuid;
969         NTSTATUS status;
970         const struct ndr_syntax_id *selected_transfer = NULL;
971         size_t i;
972         bool ok;
973
974         if (b == NULL) {
975                 return NT_STATUS_INTERNAL_ERROR;
976         }
977         if (ctx == NULL) {
978                 return NT_STATUS_INTERNAL_ERROR;
979         }
980         if (ctx->num_transfer_syntaxes < 1) {
981                 return NT_STATUS_INTERNAL_ERROR;
982         }
983         if (ack == NULL) {
984                 return NT_STATUS_INTERNAL_ERROR;
985         }
986         if (supported_transfer == NULL) {
987                 return NT_STATUS_INTERNAL_ERROR;
988         }
989
990         switch (ack->result) {
991         case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
992         case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
993                 /*
994                  * We is already completed.
995                  */
996                 return NT_STATUS_OK;
997         default:
998                 break;
999         }
1000
1001         ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1002         ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1003
1004         if_version = ctx->abstract_syntax.if_version;
1005         uuid = ctx->abstract_syntax.uuid;
1006
1007         iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1008         if (iface == NULL) {
1009                 char *uuid_str = GUID_string(call, &uuid);
1010                 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1011                 talloc_free(uuid_str);
1012                 /*
1013                  * We report this only via ack->result
1014                  */
1015                 return NT_STATUS_OK;
1016         }
1017
1018         ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1019         ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1020
1021         if (validate_only) {
1022                 /*
1023                  * We report this only via ack->result
1024                  */
1025                 return NT_STATUS_OK;
1026         }
1027
1028         for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1029                 /*
1030                  * we only do NDR encoded dcerpc for now.
1031                  */
1032                 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1033                                          supported_transfer);
1034                 if (ok) {
1035                         selected_transfer = supported_transfer;
1036                         break;
1037                 }
1038         }
1039
1040         context = dcesrv_find_context(call->conn, ctx->context_id);
1041         if (context != NULL) {
1042                 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1043                                          &ctx->abstract_syntax);
1044                 if (!ok) {
1045                         return NT_STATUS_RPC_PROTOCOL_ERROR;
1046                 }
1047
1048                 if (selected_transfer != NULL) {
1049                         ok = ndr_syntax_id_equal(&context->transfer_syntax,
1050                                                  selected_transfer);
1051                         if (!ok) {
1052                                 return NT_STATUS_RPC_PROTOCOL_ERROR;
1053                         }
1054
1055                         ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1056                         ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1057                         ack->syntax = context->transfer_syntax;
1058                 }
1059
1060                 /*
1061                  * We report this only via ack->result
1062                  */
1063                 return NT_STATUS_OK;
1064         }
1065
1066         if (selected_transfer == NULL) {
1067                 /*
1068                  * We report this only via ack->result
1069                  */
1070                 return NT_STATUS_OK;
1071         }
1072
1073         ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1074         ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1075
1076         /* add this context to the list of available context_ids */
1077         context = talloc_zero(call->conn, struct dcesrv_connection_context);
1078         if (context == NULL) {
1079                 return NT_STATUS_NO_MEMORY;
1080         }
1081         context->conn = call->conn;
1082         context->context_id = ctx->context_id;
1083         context->iface = iface;
1084         context->transfer_syntax = *selected_transfer;
1085         context->private_data = NULL;
1086         DLIST_ADD(call->conn->contexts, context);
1087         call->context = context;
1088         talloc_set_destructor(context, dcesrv_connection_context_destructor);
1089
1090         dcesrv_prepare_context_auth(call);
1091
1092         /*
1093          * Multiplex is supported by default
1094          */
1095         call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1096
1097         status = iface->bind(call, iface, if_version);
1098         call->context = NULL;
1099         if (!NT_STATUS_IS_OK(status)) {
1100                 /* we don't want to trigger the iface->unbind() hook */
1101                 context->iface = NULL;
1102                 talloc_free(context);
1103                 /*
1104                  * We report this only via ack->result
1105                  */
1106                 return NT_STATUS_OK;
1107         }
1108
1109         ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1110         ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1111         ack->syntax = context->transfer_syntax;
1112         return NT_STATUS_OK;
1113 }
1114
1115 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1116                                 const struct dcerpc_bind *b,
1117                                 struct dcerpc_ack_ctx *ack_ctx_list)
1118 {
1119         NTSTATUS status;
1120         size_t i;
1121         bool validate_only = false;
1122         bool preferred_ndr32;
1123
1124         /*
1125          * Try to negotiate one new presentation context,
1126          * using our preferred transfer syntax.
1127          */
1128         for (i = 0; i < b->num_contexts; i++) {
1129                 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1130                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1131
1132                 status = dcesrv_check_or_create_context(call, b, c, a,
1133                                                 validate_only,
1134                                                 call->conn->preferred_transfer);
1135                 if (!NT_STATUS_IS_OK(status)) {
1136                         return status;
1137                 }
1138
1139                 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1140                         /*
1141                          * We managed to negotiate one context.
1142                          *
1143                          * => we're done.
1144                          */
1145                         validate_only = true;
1146                 }
1147         }
1148
1149         preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1150                                         call->conn->preferred_transfer);
1151         if (preferred_ndr32) {
1152                 /*
1153                  * We're done.
1154                  */
1155                 return NT_STATUS_OK;
1156         }
1157
1158         /*
1159          * Try to negotiate one new presentation context,
1160          * using NDR 32 as fallback.
1161          */
1162         for (i = 0; i < b->num_contexts; i++) {
1163                 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1164                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1165
1166                 status = dcesrv_check_or_create_context(call, b, c, a,
1167                                                 validate_only,
1168                                                 &ndr_transfer_syntax_ndr);
1169                 if (!NT_STATUS_IS_OK(status)) {
1170                         return status;
1171                 }
1172
1173                 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1174                         /*
1175                          * We managed to negotiate one context.
1176                          *
1177                          * => we're done.
1178                          */
1179                         validate_only = true;
1180                 }
1181         }
1182
1183         return NT_STATUS_OK;
1184 }
1185
1186 /*
1187   handle a alter context request
1188 */
1189 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1190 {
1191         NTSTATUS status;
1192         bool auth_ok = false;
1193         struct ncacn_packet pkt;
1194         uint32_t extra_flags = 0;
1195         struct data_blob_list_item *rep = NULL;
1196         struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1197         size_t i;
1198
1199         if (!call->conn->allow_alter) {
1200                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1201         }
1202
1203         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1204                         DCERPC_PKT_ALTER,
1205                         call->pkt.u.alter.auth_info.length,
1206                         0, /* required flags */
1207                         DCERPC_PFC_FLAG_FIRST |
1208                         DCERPC_PFC_FLAG_LAST |
1209                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1210                         0x08 | /* this is not defined, but should be ignored */
1211                         DCERPC_PFC_FLAG_CONC_MPX |
1212                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1213                         DCERPC_PFC_FLAG_MAYBE |
1214                         DCERPC_PFC_FLAG_OBJECT_UUID);
1215         if (!NT_STATUS_IS_OK(status)) {
1216                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1217         }
1218
1219         auth_ok = dcesrv_auth_alter(call);
1220         if (!auth_ok) {
1221                 if (call->fault_code != 0) {
1222                         return dcesrv_fault_disconnect(call, call->fault_code);
1223                 }
1224         }
1225
1226         if (call->pkt.u.alter.num_contexts < 1) {
1227                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1228         }
1229
1230         ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1231                                          call->pkt.u.alter.num_contexts);
1232         if (ack_ctx_list == NULL) {
1233                 return NT_STATUS_NO_MEMORY;
1234         }
1235
1236         /*
1237          * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1238          * dcesrv_check_or_create_context()) and do some protocol validation
1239          * and set sane defaults.
1240          */
1241         for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1242                 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1243                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1244
1245                 if (c->num_transfer_syntaxes == 0) {
1246                         return dcesrv_fault_disconnect(call,
1247                                         DCERPC_NCA_S_PROTO_ERROR);
1248                 }
1249
1250                 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1251                 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1252         }
1253
1254         /*
1255          * Try to negotiate one new presentation context.
1256          */
1257         status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1258         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1259                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1260         }
1261         if (!NT_STATUS_IS_OK(status)) {
1262                 return status;
1263         }
1264
1265         if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1266             (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1267                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1268                 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1269         }
1270
1271         if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1272                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1273         }
1274
1275         /* handle any authentication that is being requested */
1276         if (!auth_ok) {
1277                 if (call->in_auth_info.auth_type !=
1278                     call->conn->auth_state.auth_type)
1279                 {
1280                         return dcesrv_fault_disconnect(call,
1281                                         DCERPC_FAULT_SEC_PKG_ERROR);
1282                 }
1283                 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1284         }
1285
1286         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1287         pkt.auth_length = 0;
1288         pkt.call_id = call->pkt.call_id;
1289         pkt.ptype = DCERPC_PKT_ALTER_RESP;
1290         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1291         pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1292         pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1293         pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1294         pkt.u.alter_resp.secondary_address = "";
1295         pkt.u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1296         pkt.u.alter_resp.ctx_list = ack_ctx_list;
1297         pkt.u.alter_resp.auth_info = data_blob_null;
1298
1299         status = dcesrv_auth_alter_ack(call, &pkt);
1300         if (!NT_STATUS_IS_OK(status)) {
1301                 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1302         }
1303
1304         rep = talloc_zero(call, struct data_blob_list_item);
1305         if (!rep) {
1306                 return NT_STATUS_NO_MEMORY;
1307         }
1308
1309         status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1310         if (!NT_STATUS_IS_OK(status)) {
1311                 return status;
1312         }
1313
1314         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1315
1316         DLIST_ADD_END(call->replies, rep);
1317         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1318
1319         if (call->conn->call_list && call->conn->call_list->replies) {
1320                 if (call->conn->transport.report_output_data) {
1321                         call->conn->transport.report_output_data(call->conn);
1322                 }
1323         }
1324
1325         return NT_STATUS_OK;
1326 }
1327
1328 /*
1329   possibly save the call for inspection with ndrdump
1330  */
1331 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1332 {
1333 #ifdef DEVELOPER
1334         char *fname;
1335         const char *dump_dir;
1336         dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1337         if (!dump_dir) {
1338                 return;
1339         }
1340         fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1341                                 dump_dir,
1342                                 call->context->iface->name,
1343                                 call->pkt.u.request.opnum,
1344                                 why);
1345         if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1346                 DEBUG(0,("RPC SAVED %s\n", fname));
1347         }
1348         talloc_free(fname);
1349 #endif
1350 }
1351
1352 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1353 {
1354         TALLOC_CTX *frame = talloc_stackframe();
1355         const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1356                 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1357         const struct dcerpc_sec_vt_pcontext pcontext = {
1358                 .abstract_syntax = call->context->iface->syntax_id,
1359                 .transfer_syntax = call->context->transfer_syntax,
1360         };
1361         const struct dcerpc_sec_vt_header2 header2 =
1362                 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1363         enum ndr_err_code ndr_err;
1364         struct dcerpc_sec_verification_trailer *vt = NULL;
1365         NTSTATUS status = NT_STATUS_OK;
1366         bool ok;
1367
1368         SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1369
1370         ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1371                                                           frame, &vt);
1372         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1373                 status = ndr_map_error2ntstatus(ndr_err);
1374                 goto done;
1375         }
1376
1377         ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1378                                                    &pcontext, &header2);
1379         if (!ok) {
1380                 status = NT_STATUS_ACCESS_DENIED;
1381                 goto done;
1382         }
1383 done:
1384         TALLOC_FREE(frame);
1385         return status;
1386 }
1387
1388 /*
1389   handle a dcerpc request packet
1390 */
1391 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1392 {
1393         const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1394         enum dcerpc_transport_t transport =
1395                 dcerpc_binding_get_transport(endpoint->ep_description);
1396         struct ndr_pull *pull;
1397         NTSTATUS status;
1398
1399         if (!call->conn->allow_request) {
1400                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1401         }
1402
1403         /* if authenticated, and the mech we use can't do async replies, don't use them... */
1404         if (call->conn->auth_state.gensec_security && 
1405             !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1406                 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1407         }
1408
1409         if (call->context == NULL) {
1410                 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1411                                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1412         }
1413
1414         switch (call->conn->auth_state.auth_level) {
1415         case DCERPC_AUTH_LEVEL_NONE:
1416         case DCERPC_AUTH_LEVEL_PACKET:
1417         case DCERPC_AUTH_LEVEL_INTEGRITY:
1418         case DCERPC_AUTH_LEVEL_PRIVACY:
1419                 break;
1420         default:
1421                 if (!call->context->allow_connect) {
1422                         char *addr;
1423
1424                         addr = tsocket_address_string(call->conn->remote_address,
1425                                                       call);
1426
1427                         DEBUG(2, ("%s: restrict auth_level_connect access "
1428                                   "to [%s] with auth[type=0x%x,level=0x%x] "
1429                                   "on [%s] from [%s]\n",
1430                                   __func__, call->context->iface->name,
1431                                   call->conn->auth_state.auth_type,
1432                                   call->conn->auth_state.auth_level,
1433                                   derpc_transport_string_by_transport(transport),
1434                                   addr));
1435                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1436                 }
1437                 break;
1438         }
1439
1440         if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1441                 char *addr;
1442
1443                 addr = tsocket_address_string(call->conn->remote_address, call);
1444
1445                 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1446                           "to [%s] with auth[type=0x%x,level=0x%x] "
1447                           "on [%s] from [%s]\n",
1448                           __func__,
1449                           call->context->min_auth_level,
1450                           call->context->iface->name,
1451                           call->conn->auth_state.auth_type,
1452                           call->conn->auth_state.auth_level,
1453                           derpc_transport_string_by_transport(transport),
1454                           addr));
1455                 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1456         }
1457
1458         pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1459         NT_STATUS_HAVE_NO_MEMORY(pull);
1460
1461         pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1462
1463         call->ndr_pull  = pull;
1464
1465         if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1466                 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1467         }
1468
1469         status = dcesrv_check_verification_trailer(call);
1470         if (!NT_STATUS_IS_OK(status)) {
1471                 uint32_t faultcode = DCERPC_FAULT_OTHER;
1472                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1473                         faultcode = DCERPC_FAULT_ACCESS_DENIED;
1474                 }
1475                 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1476                            nt_errstr(status)));
1477                 return dcesrv_fault(call, faultcode);
1478         }
1479
1480         /* unravel the NDR for the packet */
1481         status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1482         if (!NT_STATUS_IS_OK(status)) {
1483                 uint8_t extra_flags = 0;
1484                 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1485                         /* we got an unknown call */
1486                         DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1487                                  call->pkt.u.request.opnum,
1488                                  call->context->iface->name));
1489                         dcesrv_save_call(call, "unknown");
1490                         extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1491                 } else {
1492                         dcesrv_save_call(call, "pullfail");
1493                 }
1494                 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1495         }
1496
1497         if (pull->offset != pull->data_size) {
1498                 dcesrv_save_call(call, "extrabytes");
1499                 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n", 
1500                          pull->data_size - pull->offset));
1501         }
1502
1503         /* call the dispatch function */
1504         status = call->context->iface->dispatch(call, call, call->r);
1505         if (!NT_STATUS_IS_OK(status)) {
1506                 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1507                          call->context->iface->name,
1508                          call->pkt.u.request.opnum,
1509                          dcerpc_errstr(pull, call->fault_code)));
1510                 return dcesrv_fault(call, call->fault_code);
1511         }
1512
1513         /* add the call to the pending list */
1514         dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1515
1516         if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1517                 return NT_STATUS_OK;
1518         }
1519
1520         return dcesrv_reply(call);
1521 }
1522
1523
1524 /*
1525   remove the call from the right list when freed
1526  */
1527 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1528 {
1529         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1530         return 0;
1531 }
1532
1533 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1534 {
1535         return conn->local_address;
1536 }
1537
1538 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1539 {
1540         return conn->remote_address;
1541 }
1542
1543 /*
1544   process some input to a dcerpc endpoint server.
1545 */
1546 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1547                                             struct ncacn_packet *pkt,
1548                                             DATA_BLOB blob)
1549 {
1550         NTSTATUS status;
1551         struct dcesrv_call_state *call;
1552         struct dcesrv_call_state *existing = NULL;
1553
1554         call = talloc_zero(dce_conn, struct dcesrv_call_state);
1555         if (!call) {
1556                 data_blob_free(&blob);
1557                 talloc_free(pkt);
1558                 return NT_STATUS_NO_MEMORY;
1559         }
1560         call->conn              = dce_conn;
1561         call->event_ctx         = dce_conn->event_ctx;
1562         call->msg_ctx           = dce_conn->msg_ctx;
1563         call->state_flags       = call->conn->state_flags;
1564         call->time              = timeval_current();
1565         call->list              = DCESRV_LIST_NONE;
1566
1567         talloc_steal(call, pkt);
1568         talloc_steal(call, blob.data);
1569         call->pkt = *pkt;
1570
1571         talloc_set_destructor(call, dcesrv_call_dequeue);
1572
1573         if (call->conn->allow_bind) {
1574                 /*
1575                  * Only one bind is possible per connection
1576                  */
1577                 call->conn->allow_bind = false;
1578                 return dcesrv_bind(call);
1579         }
1580
1581         /* we have to check the signing here, before combining the
1582            pdus */
1583         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1584                 if (!call->conn->allow_request) {
1585                         return dcesrv_fault_disconnect(call,
1586                                         DCERPC_NCA_S_PROTO_ERROR);
1587                 }
1588
1589                 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1590                                 DCERPC_PKT_REQUEST,
1591                                 call->pkt.u.request.stub_and_verifier.length,
1592                                 0, /* required_flags */
1593                                 DCERPC_PFC_FLAG_FIRST |
1594                                 DCERPC_PFC_FLAG_LAST |
1595                                 DCERPC_PFC_FLAG_PENDING_CANCEL |
1596                                 0x08 | /* this is not defined, but should be ignored */
1597                                 DCERPC_PFC_FLAG_CONC_MPX |
1598                                 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1599                                 DCERPC_PFC_FLAG_MAYBE |
1600                                 DCERPC_PFC_FLAG_OBJECT_UUID);
1601                 if (!NT_STATUS_IS_OK(status)) {
1602                         return dcesrv_fault_disconnect(call,
1603                                         DCERPC_NCA_S_PROTO_ERROR);
1604                 }
1605
1606                 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1607                         /*
1608                          * We don't use dcesrv_fault_disconnect()
1609                          * here, because we don't want to set
1610                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1611                          *
1612                          * Note that we don't check against the negotiated
1613                          * max_recv_frag, but a hard coded value.
1614                          */
1615                         dcesrv_call_disconnect_after(call,
1616                                 "dcesrv_auth_request - frag_length too large");
1617                         return dcesrv_fault(call,
1618                                         DCERPC_NCA_S_PROTO_ERROR);
1619                 }
1620
1621                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1622                         if (dce_conn->pending_call_list != NULL) {
1623                                 /*
1624                                  * concurrent requests are only allowed
1625                                  * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1626                                  */
1627                                 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1628                                         dcesrv_call_disconnect_after(call,
1629                                                 "dcesrv_auth_request - "
1630                                                 "existing pending call without CONN_MPX");
1631                                         return dcesrv_fault(call,
1632                                                 DCERPC_NCA_S_PROTO_ERROR);
1633                                 }
1634                         }
1635                         /* only one request is possible in the fragmented list */
1636                         if (dce_conn->incoming_fragmented_call_list != NULL) {
1637                                 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1638                                         /*
1639                                          * Without DCERPC_PFC_FLAG_CONC_MPX
1640                                          * we need to return the FAULT on the
1641                                          * already existing call.
1642                                          *
1643                                          * This is important to get the
1644                                          * call_id and context_id right.
1645                                          */
1646                                         TALLOC_FREE(call);
1647                                         call = dce_conn->incoming_fragmented_call_list;
1648                                 }
1649                                 dcesrv_call_disconnect_after(call,
1650                                         "dcesrv_auth_request - "
1651                                         "existing fragmented call");
1652                                 return dcesrv_fault(call,
1653                                                 DCERPC_NCA_S_PROTO_ERROR);
1654                         }
1655                         if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1656                                 return dcesrv_fault_disconnect(call,
1657                                                 DCERPC_FAULT_NO_CALL_ACTIVE);
1658                         }
1659                         call->context = dcesrv_find_context(call->conn,
1660                                                 call->pkt.u.request.context_id);
1661                         if (call->context == NULL) {
1662                                 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1663                                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1664                         }
1665                 } else {
1666                         const struct dcerpc_request *nr = &call->pkt.u.request;
1667                         const struct dcerpc_request *er = NULL;
1668                         int cmp;
1669
1670                         existing = dcesrv_find_fragmented_call(dce_conn,
1671                                                         call->pkt.call_id);
1672                         if (existing == NULL) {
1673                                 dcesrv_call_disconnect_after(call,
1674                                         "dcesrv_auth_request - "
1675                                         "no existing fragmented call");
1676                                 return dcesrv_fault(call,
1677                                                 DCERPC_NCA_S_PROTO_ERROR);
1678                         }
1679                         er = &existing->pkt.u.request;
1680
1681                         if (call->pkt.ptype != existing->pkt.ptype) {
1682                                 /* trying to play silly buggers are we? */
1683                                 return dcesrv_fault_disconnect(existing,
1684                                                 DCERPC_NCA_S_PROTO_ERROR);
1685                         }
1686                         cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1687                                      sizeof(pkt->drep));
1688                         if (cmp != 0) {
1689                                 return dcesrv_fault_disconnect(existing,
1690                                                 DCERPC_NCA_S_PROTO_ERROR);
1691                         }
1692                         if (nr->context_id != er->context_id)  {
1693                                 return dcesrv_fault_disconnect(existing,
1694                                                 DCERPC_NCA_S_PROTO_ERROR);
1695                         }
1696                         if (nr->opnum != er->opnum)  {
1697                                 return dcesrv_fault_disconnect(existing,
1698                                                 DCERPC_NCA_S_PROTO_ERROR);
1699                         }
1700                 }
1701         }
1702
1703         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1704                 bool ok;
1705                 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1706
1707                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1708                         payload_offset += 16;
1709                 }
1710
1711                 ok = dcesrv_auth_pkt_pull(call, &blob,
1712                                           0, /* required_flags */
1713                                           DCERPC_PFC_FLAG_FIRST |
1714                                           DCERPC_PFC_FLAG_LAST |
1715                                           DCERPC_PFC_FLAG_PENDING_CANCEL |
1716                                           0x08 | /* this is not defined, but should be ignored */
1717                                           DCERPC_PFC_FLAG_CONC_MPX |
1718                                           DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1719                                           DCERPC_PFC_FLAG_MAYBE |
1720                                           DCERPC_PFC_FLAG_OBJECT_UUID,
1721                                           payload_offset,
1722                                           &call->pkt.u.request.stub_and_verifier);
1723                 if (!ok) {
1724                         /*
1725                          * We don't use dcesrv_fault_disconnect()
1726                          * here, because we don't want to set
1727                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1728                          */
1729                         dcesrv_call_disconnect_after(call,
1730                                                 "dcesrv_auth_request - failed");
1731                         if (call->fault_code == 0) {
1732                                 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1733                         }
1734                         return dcesrv_fault(call, call->fault_code);
1735                 }
1736         }
1737
1738         /* see if this is a continued packet */
1739         if (existing != NULL) {
1740                 struct dcerpc_request *er = &existing->pkt.u.request;
1741                 const struct dcerpc_request *nr = &call->pkt.u.request;
1742                 size_t available;
1743                 size_t alloc_size;
1744                 size_t alloc_hint;
1745
1746                 /*
1747                  * Up to 4 MByte are allowed by all fragments
1748                  */
1749                 available = dce_conn->max_total_request_size;
1750                 if (er->stub_and_verifier.length > available) {
1751                         dcesrv_call_disconnect_after(existing,
1752                                 "dcesrv_auth_request - existing payload too large");
1753                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1754                 }
1755                 available -= er->stub_and_verifier.length;
1756                 if (nr->alloc_hint > available) {
1757                         dcesrv_call_disconnect_after(existing,
1758                                 "dcesrv_auth_request - alloc hint too large");
1759                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1760                 }
1761                 if (nr->stub_and_verifier.length > available) {
1762                         dcesrv_call_disconnect_after(existing,
1763                                 "dcesrv_auth_request - new payload too large");
1764                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1765                 }
1766                 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1767                 /* allocate at least 1 byte */
1768                 alloc_hint = MAX(alloc_hint, 1);
1769                 alloc_size = er->stub_and_verifier.length +
1770                              nr->stub_and_verifier.length;
1771                 alloc_size = MAX(alloc_size, alloc_hint);
1772
1773                 er->stub_and_verifier.data =
1774                         talloc_realloc(existing,
1775                                        er->stub_and_verifier.data,
1776                                        uint8_t, alloc_size);
1777                 if (er->stub_and_verifier.data == NULL) {
1778                         TALLOC_FREE(call);
1779                         return dcesrv_fault_with_flags(existing,
1780                                                        DCERPC_FAULT_OUT_OF_RESOURCES,
1781                                                        DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1782                 }
1783                 memcpy(er->stub_and_verifier.data +
1784                        er->stub_and_verifier.length,
1785                        nr->stub_and_verifier.data,
1786                        nr->stub_and_verifier.length);
1787                 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1788
1789                 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1790
1791                 TALLOC_FREE(call);
1792                 call = existing;
1793         }
1794
1795         /* this may not be the last pdu in the chain - if its isn't then
1796            just put it on the incoming_fragmented_call_list and wait for the rest */
1797         if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1798             !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1799                 /*
1800                  * Up to 4 MByte are allowed by all fragments
1801                  */
1802                 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1803                         dcesrv_call_disconnect_after(call,
1804                                 "dcesrv_auth_request - initial alloc hint too large");
1805                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1806                 }
1807                 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1808                 return NT_STATUS_OK;
1809         } 
1810         
1811         /* This removes any fragments we may have had stashed away */
1812         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1813
1814         switch (call->pkt.ptype) {
1815         case DCERPC_PKT_BIND:
1816                 status = dcesrv_bind_nak(call,
1817                         DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1818                 break;
1819         case DCERPC_PKT_AUTH3:
1820                 status = dcesrv_auth3(call);
1821                 break;
1822         case DCERPC_PKT_ALTER:
1823                 status = dcesrv_alter(call);
1824                 break;
1825         case DCERPC_PKT_REQUEST:
1826                 status = dcesrv_request(call);
1827                 break;
1828         case DCERPC_PKT_CO_CANCEL:
1829         case DCERPC_PKT_ORPHANED:
1830                 /*
1831                  * Window just ignores CO_CANCEL and ORPHANED,
1832                  * so we do...
1833                  */
1834                 status = NT_STATUS_OK;
1835                 TALLOC_FREE(call);
1836                 break;
1837         case DCERPC_PKT_BIND_ACK:
1838         case DCERPC_PKT_BIND_NAK:
1839         case DCERPC_PKT_ALTER_RESP:
1840         case DCERPC_PKT_RESPONSE:
1841         case DCERPC_PKT_FAULT:
1842         case DCERPC_PKT_SHUTDOWN:
1843         default:
1844                 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1845                 break;
1846         }
1847
1848         /* if we are going to be sending a reply then add
1849            it to the list of pending calls. We add it to the end to keep the call
1850            list in the order we will answer */
1851         if (!NT_STATUS_IS_OK(status)) {
1852                 talloc_free(call);
1853         }
1854
1855         return status;
1856 }
1857
1858 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, 
1859                                       struct loadparm_context *lp_ctx,
1860                                       const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1861 {
1862         NTSTATUS status;
1863         struct dcesrv_context *dce_ctx;
1864         int i;
1865
1866         if (!endpoint_servers) {
1867                 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1868                 return NT_STATUS_INTERNAL_ERROR;
1869         }
1870
1871         dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
1872         NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
1873
1874         if (uid_wrapper_enabled()) {
1875                 setenv("UID_WRAPPER_MYUID", "1", 1);
1876         }
1877         dce_ctx->initial_euid = geteuid();
1878         if (uid_wrapper_enabled()) {
1879                 unsetenv("UID_WRAPPER_MYUID");
1880         }
1881
1882         dce_ctx->endpoint_list  = NULL;
1883         dce_ctx->lp_ctx = lp_ctx;
1884         dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
1885         NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
1886         dce_ctx->broken_connections = NULL;
1887
1888         for (i=0;endpoint_servers[i];i++) {
1889                 const struct dcesrv_endpoint_server *ep_server;
1890
1891                 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
1892                 if (!ep_server) {
1893                         DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
1894                         return NT_STATUS_INTERNAL_ERROR;
1895                 }
1896
1897                 status = ep_server->init_server(dce_ctx, ep_server);
1898                 if (!NT_STATUS_IS_OK(status)) {
1899                         DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
1900                                 nt_errstr(status)));
1901                         return status;
1902                 }
1903         }
1904
1905         *_dce_ctx = dce_ctx;
1906         return NT_STATUS_OK;
1907 }
1908
1909 /* the list of currently registered DCERPC endpoint servers.
1910  */
1911 static struct ep_server {
1912         struct dcesrv_endpoint_server *ep_server;
1913 } *ep_servers = NULL;
1914 static int num_ep_servers;
1915
1916 /*
1917   register a DCERPC endpoint server. 
1918
1919   The 'name' can be later used by other backends to find the operations
1920   structure for this backend.  
1921
1922   The 'type' is used to specify whether this is for a disk, printer or IPC$ share
1923 */
1924 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const void *_ep_server)
1925 {
1926         const struct dcesrv_endpoint_server *ep_server = _ep_server;
1927         
1928         if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1929                 /* its already registered! */
1930                 DEBUG(0,("DCERPC endpoint server '%s' already registered\n", 
1931                          ep_server->name));
1932                 return NT_STATUS_OBJECT_NAME_COLLISION;
1933         }
1934
1935         ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1936         if (!ep_servers) {
1937                 smb_panic("out of memory in dcerpc_register");
1938         }
1939
1940         ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1941         ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1942
1943         num_ep_servers++;
1944
1945         DEBUG(3,("DCERPC endpoint server '%s' registered\n", 
1946                  ep_server->name));
1947
1948         return NT_STATUS_OK;
1949 }
1950
1951 /*
1952   return the operations structure for a named backend of the specified type
1953 */
1954 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1955 {
1956         int i;
1957
1958         for (i=0;i<num_ep_servers;i++) {
1959                 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1960                         return ep_servers[i].ep_server;
1961                 }
1962         }
1963
1964         return NULL;
1965 }
1966
1967 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1968 {
1969         static bool initialized;
1970 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1971         STATIC_dcerpc_server_MODULES_PROTO;
1972         init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1973         init_module_fn *shared_init;
1974
1975         if (initialized) {
1976                 return;
1977         }
1978         initialized = true;
1979
1980         shared_init = load_samba_modules(NULL, "dcerpc_server");
1981
1982         run_init_functions(static_init);
1983         run_init_functions(shared_init);
1984
1985         talloc_free(shared_init);
1986 }
1987
1988 /*
1989   return the DCERPC module version, and the size of some critical types
1990   This can be used by endpoint server modules to either detect compilation errors, or provide
1991   multiple implementations for different smbd compilation options in one module
1992 */
1993 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1994 {
1995         static const struct dcesrv_critical_sizes critical_sizes = {
1996                 DCERPC_MODULE_VERSION,
1997                 sizeof(struct dcesrv_context),
1998                 sizeof(struct dcesrv_endpoint),
1999                 sizeof(struct dcesrv_endpoint_server),
2000                 sizeof(struct dcesrv_interface),
2001                 sizeof(struct dcesrv_if_list),
2002                 sizeof(struct dcesrv_connection),
2003                 sizeof(struct dcesrv_call_state),
2004                 sizeof(struct dcesrv_auth),
2005                 sizeof(struct dcesrv_handle)
2006         };
2007
2008         return &critical_sizes;
2009 }
2010
2011 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2012 {
2013         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2014         struct stream_connection *srv_conn;
2015         srv_conn = talloc_get_type(dce_conn->transport.private_data,
2016                                    struct stream_connection);
2017
2018         dce_conn->allow_bind = false;
2019         dce_conn->allow_auth3 = false;
2020         dce_conn->allow_alter = false;
2021         dce_conn->allow_request = false;
2022
2023         if (dce_conn->pending_call_list == NULL) {
2024                 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2025
2026                 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2027                 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2028                 return;
2029         }
2030
2031         if (dce_conn->terminate != NULL) {
2032                 return;
2033         }
2034
2035         DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
2036                  reason));
2037         dce_conn->terminate = talloc_strdup(dce_conn, reason);
2038         if (dce_conn->terminate == NULL) {
2039                 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
2040         }
2041         DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2042 }
2043
2044 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2045 {
2046         struct dcesrv_connection *cur, *next;
2047
2048         next = dce_ctx->broken_connections;
2049         while (next != NULL) {
2050                 cur = next;
2051                 next = cur->next;
2052
2053                 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2054                         struct dcesrv_connection_context *context_cur, *context_next;
2055
2056                         context_next = cur->contexts;
2057                         while (context_next != NULL) {
2058                                 context_cur = context_next;
2059                                 context_next = context_cur->next;
2060
2061                                 dcesrv_connection_context_destructor(context_cur);
2062                         }
2063                 }
2064
2065                 dcesrv_terminate_connection(cur, cur->terminate);
2066         }
2067 }
2068
2069 /* We need this include to be able to compile on some plateforms
2070  * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2071  * correctly.
2072  * It has to be that deep because otherwise we have a conflict on
2073  * const struct dcesrv_interface declaration.
2074  * This is mostly due to socket_wrapper defining #define bind swrap_bind
2075  * which conflict with the bind used before.
2076  */
2077 #include "system/network.h"
2078
2079 struct dcesrv_sock_reply_state {
2080         struct dcesrv_connection *dce_conn;
2081         struct dcesrv_call_state *call;
2082         struct iovec iov;
2083 };
2084
2085 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2086 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2087
2088 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2089 {
2090         struct dcesrv_call_state *call;
2091
2092         call = dce_conn->call_list;
2093         if (!call || !call->replies) {
2094                 return;
2095         }
2096
2097         while (call->replies) {
2098                 struct data_blob_list_item *rep = call->replies;
2099                 struct dcesrv_sock_reply_state *substate;
2100                 struct tevent_req *subreq;
2101
2102                 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2103                 if (!substate) {
2104                         dcesrv_terminate_connection(dce_conn, "no memory");
2105                         return;
2106                 }
2107
2108                 substate->dce_conn = dce_conn;
2109                 substate->call = NULL;
2110
2111                 DLIST_REMOVE(call->replies, rep);
2112
2113                 if (call->replies == NULL && call->terminate_reason == NULL) {
2114                         substate->call = call;
2115                 }
2116
2117                 substate->iov.iov_base = (void *) rep->blob.data;
2118                 substate->iov.iov_len = rep->blob.length;
2119
2120                 subreq = tstream_writev_queue_send(substate,
2121                                                    dce_conn->event_ctx,
2122                                                    dce_conn->stream,
2123                                                    dce_conn->send_queue,
2124                                                    &substate->iov, 1);
2125                 if (!subreq) {
2126                         dcesrv_terminate_connection(dce_conn, "no memory");
2127                         return;
2128                 }
2129                 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2130                                         substate);
2131         }
2132
2133         if (call->terminate_reason != NULL) {
2134                 struct tevent_req *subreq;
2135
2136                 subreq = tevent_queue_wait_send(call,
2137                                                 dce_conn->event_ctx,
2138                                                 dce_conn->send_queue);
2139                 if (!subreq) {
2140                         dcesrv_terminate_connection(dce_conn, __location__);
2141                         return;
2142                 }
2143                 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2144                                         call);
2145         }
2146
2147         DLIST_REMOVE(call->conn->call_list, call);
2148         call->list = DCESRV_LIST_NONE;
2149 }
2150
2151 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2152 {
2153         struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2154                                                 struct dcesrv_sock_reply_state);
2155         int ret;
2156         int sys_errno;
2157         NTSTATUS status;
2158         struct dcesrv_call_state *call = substate->call;
2159
2160         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2161         TALLOC_FREE(subreq);
2162         if (ret == -1) {
2163                 status = map_nt_error_from_unix_common(sys_errno);
2164                 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2165                 return;
2166         }
2167
2168         talloc_free(substate);
2169         if (call) {
2170                 talloc_free(call);
2171         }
2172 }
2173
2174 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2175
2176 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2177 {
2178         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2179                                                 struct dcesrv_call_state);
2180         bool ok;
2181         struct timeval tv;
2182
2183         /* make sure we stop send queue before removing subreq */
2184         tevent_queue_stop(call->conn->send_queue);
2185
2186         ok = tevent_queue_wait_recv(subreq);
2187         TALLOC_FREE(subreq);
2188         if (!ok) {
2189                 dcesrv_terminate_connection(call->conn, __location__);
2190                 return;
2191         }
2192
2193         /* disconnect after 200 usecs */
2194         tv = timeval_current_ofs_usec(200);
2195         subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2196         if (subreq == NULL) {
2197                 dcesrv_terminate_connection(call->conn, __location__);
2198                 return;
2199         }
2200         tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2201                                 call);
2202 }
2203
2204 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2205 {
2206         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2207                                                 struct dcesrv_call_state);
2208         bool ok;
2209
2210         ok = tevent_wakeup_recv(subreq);
2211         TALLOC_FREE(subreq);
2212         if (!ok) {
2213                 dcesrv_terminate_connection(call->conn, __location__);
2214                 return;
2215         }
2216
2217         dcesrv_terminate_connection(call->conn, call->terminate_reason);
2218 }
2219
2220 struct dcesrv_socket_context {
2221         const struct dcesrv_endpoint *endpoint;
2222         struct dcesrv_context *dcesrv_ctx;
2223 };
2224
2225
2226 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2227
2228 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2229 {
2230         NTSTATUS status;
2231         struct dcesrv_socket_context *dcesrv_sock = 
2232                 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2233         enum dcerpc_transport_t transport =
2234                 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2235         struct dcesrv_connection *dcesrv_conn = NULL;
2236         int ret;
2237         struct tevent_req *subreq;
2238         struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2239
2240         dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2241
2242         if (!srv_conn->session_info) {
2243                 status = auth_anonymous_session_info(srv_conn,
2244                                                      lp_ctx,
2245                                                      &srv_conn->session_info);
2246                 if (!NT_STATUS_IS_OK(status)) {
2247                         DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2248                                 nt_errstr(status)));
2249                         stream_terminate_connection(srv_conn, nt_errstr(status));
2250                         return;
2251                 }
2252         }
2253
2254         status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2255                                          srv_conn,
2256                                          dcesrv_sock->endpoint,
2257                                          srv_conn->session_info,
2258                                          srv_conn->event.ctx,
2259                                          srv_conn->msg_ctx,
2260                                          srv_conn->server_id,
2261                                          DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2262                                          &dcesrv_conn);
2263         if (!NT_STATUS_IS_OK(status)) {
2264                 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
2265                         nt_errstr(status)));
2266                 stream_terminate_connection(srv_conn, nt_errstr(status));
2267                 return;
2268         }
2269
2270         dcesrv_conn->transport.private_data             = srv_conn;
2271         dcesrv_conn->transport.report_output_data       = dcesrv_sock_report_output_data;
2272
2273         TALLOC_FREE(srv_conn->event.fde);
2274
2275         dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2276         if (!dcesrv_conn->send_queue) {
2277                 status = NT_STATUS_NO_MEMORY;
2278                 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2279                         nt_errstr(status)));
2280                 stream_terminate_connection(srv_conn, nt_errstr(status));
2281                 return;
2282         }
2283
2284         if (transport == NCACN_NP) {
2285                 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2286                 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2287                                                   &srv_conn->tstream);
2288         } else {
2289                 ret = tstream_bsd_existing_socket(dcesrv_conn,
2290                                                   socket_get_fd(srv_conn->socket),
2291                                                   &dcesrv_conn->stream);
2292                 if (ret == -1) {
2293                         status = map_nt_error_from_unix_common(errno);
2294                         DEBUG(0, ("dcesrv_sock_accept: "
2295                                   "failed to setup tstream: %s\n",
2296                                   nt_errstr(status)));
2297                         stream_terminate_connection(srv_conn, nt_errstr(status));
2298                         return;
2299                 }
2300                 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2301         }
2302
2303         dcesrv_conn->local_address = srv_conn->local_address;
2304         dcesrv_conn->remote_address = srv_conn->remote_address;
2305
2306         if (transport == NCALRPC) {
2307                 uid_t uid;
2308                 gid_t gid;
2309                 int sock_fd;
2310
2311                 sock_fd = socket_get_fd(srv_conn->socket);
2312                 if (sock_fd == -1) {
2313                         stream_terminate_connection(
2314                                 srv_conn, "socket_get_fd failed\n");
2315                         return;
2316                 }
2317
2318                 ret = getpeereid(sock_fd, &uid, &gid);
2319                 if (ret == -1) {
2320                         status = map_nt_error_from_unix_common(errno);
2321                         DEBUG(0, ("dcesrv_sock_accept: "
2322                                   "getpeereid() failed for NCALRPC: %s\n",
2323                                   nt_errstr(status)));
2324                         stream_terminate_connection(srv_conn, nt_errstr(status));
2325                         return;
2326                 }
2327                 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2328                         struct tsocket_address *r = NULL;
2329
2330                         ret = tsocket_address_unix_from_path(dcesrv_conn,
2331                                                              "/root/ncalrpc_as_system",
2332                                                              &r);
2333                         if (ret == -1) {
2334                                 status = map_nt_error_from_unix_common(errno);
2335                                 DEBUG(0, ("dcesrv_sock_accept: "
2336                                           "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2337                                           nt_errstr(status)));
2338                                 stream_terminate_connection(srv_conn, nt_errstr(status));
2339                                 return;
2340                         }
2341                         dcesrv_conn->remote_address = r;
2342                 }
2343         }
2344
2345         srv_conn->private_data = dcesrv_conn;
2346
2347         irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2348
2349         subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2350                                                dcesrv_conn->event_ctx,
2351                                                dcesrv_conn->stream);
2352         if (!subreq) {
2353                 status = NT_STATUS_NO_MEMORY;
2354                 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2355                         nt_errstr(status)));
2356                 stream_terminate_connection(srv_conn, nt_errstr(status));
2357                 return;
2358         }
2359         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2360
2361         return;
2362 }
2363
2364 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2365 {
2366         struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2367                                              struct dcesrv_connection);
2368         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2369         struct ncacn_packet *pkt;
2370         DATA_BLOB buffer;
2371         NTSTATUS status;
2372
2373         if (dce_conn->terminate) {
2374                 /*
2375                  * if the current connection is broken
2376                  * we need to clean it up before any other connection
2377                  */
2378                 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2379                 dcesrv_cleanup_broken_connections(dce_ctx);
2380                 return;
2381         }
2382
2383         dcesrv_cleanup_broken_connections(dce_ctx);
2384
2385         status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2386                                                &pkt, &buffer);
2387         TALLOC_FREE(subreq);
2388         if (!NT_STATUS_IS_OK(status)) {
2389                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2390                 return;
2391         }
2392
2393         status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2394         if (!NT_STATUS_IS_OK(status)) {
2395                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2396                 return;
2397         }
2398
2399         subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2400                                                dce_conn->event_ctx,
2401                                                dce_conn->stream);
2402         if (!subreq) {
2403                 status = NT_STATUS_NO_MEMORY;
2404                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2405                 return;
2406         }
2407         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2408 }
2409
2410 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2411 {
2412         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2413                                              struct dcesrv_connection);
2414         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2415 }
2416
2417 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2418 {
2419         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2420                                              struct dcesrv_connection);
2421         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2422 }
2423
2424
2425 static const struct stream_server_ops dcesrv_stream_ops = {
2426         .name                   = "rpc",
2427         .accept_connection      = dcesrv_sock_accept,
2428         .recv_handler           = dcesrv_sock_recv,
2429         .send_handler           = dcesrv_sock_send,
2430 };
2431
2432 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 
2433                                    struct loadparm_context *lp_ctx,
2434                                    struct dcesrv_endpoint *e,
2435                             struct tevent_context *event_ctx, const struct model_ops *model_ops)
2436 {
2437         struct dcesrv_socket_context *dcesrv_sock;
2438         uint16_t port = 1;
2439         NTSTATUS status;
2440         const char *endpoint;
2441
2442         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2443         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2444
2445         /* remember the endpoint of this socket */
2446         dcesrv_sock->endpoint           = e;
2447         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2448
2449         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2450
2451         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2452                                      model_ops, &dcesrv_stream_ops, 
2453                                      "unix", endpoint, &port,
2454                                      lpcfg_socket_options(lp_ctx),
2455                                      dcesrv_sock);
2456         if (!NT_STATUS_IS_OK(status)) {
2457                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2458                          endpoint, nt_errstr(status)));
2459         }
2460
2461         return status;
2462 }
2463
2464 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 
2465                                       struct loadparm_context *lp_ctx,
2466                                       struct dcesrv_endpoint *e,
2467                                       struct tevent_context *event_ctx, const struct model_ops *model_ops)
2468 {
2469         struct dcesrv_socket_context *dcesrv_sock;
2470         uint16_t port = 1;
2471         char *full_path;
2472         NTSTATUS status;
2473         const char *endpoint;
2474
2475         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2476
2477         if (endpoint == NULL) {
2478                 /*
2479                  * No identifier specified: use DEFAULT.
2480                  *
2481                  * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2482                  * no endpoint and let the epmapper worry about it.
2483                  */
2484                 endpoint = "DEFAULT";
2485                 status = dcerpc_binding_set_string_option(e->ep_description,
2486                                                           "endpoint",
2487                                                           endpoint);
2488                 if (!NT_STATUS_IS_OK(status)) {
2489                         DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2490                                   nt_errstr(status)));
2491                         return status;
2492                 }
2493         }
2494
2495         full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2496                                     endpoint);
2497
2498         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2499         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2500
2501         /* remember the endpoint of this socket */
2502         dcesrv_sock->endpoint           = e;
2503         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2504
2505         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2506                                      model_ops, &dcesrv_stream_ops, 
2507                                      "unix", full_path, &port, 
2508                                      lpcfg_socket_options(lp_ctx),
2509                                      dcesrv_sock);
2510         if (!NT_STATUS_IS_OK(status)) {
2511                 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2512                          endpoint, full_path, nt_errstr(status)));
2513         }
2514         return status;
2515 }
2516
2517 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2518                                  struct loadparm_context *lp_ctx,
2519                                  struct dcesrv_endpoint *e,
2520                                  struct tevent_context *event_ctx, const struct model_ops *model_ops)
2521 {
2522         struct dcesrv_socket_context *dcesrv_sock;
2523         NTSTATUS status;
2524         const char *endpoint;
2525
2526         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2527         if (endpoint == NULL) {
2528                 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2529                 return NT_STATUS_INVALID_PARAMETER;
2530         }
2531
2532         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2533         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2534
2535         /* remember the endpoint of this socket */
2536         dcesrv_sock->endpoint           = e;
2537         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2538
2539         status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2540                                           model_ops, &dcesrv_stream_ops,
2541                                           endpoint,
2542                                           dcesrv_sock);
2543         if (!NT_STATUS_IS_OK(status)) {
2544                 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2545                          endpoint, nt_errstr(status)));
2546                 return status;
2547         }
2548
2549         return NT_STATUS_OK;
2550 }
2551
2552 /*
2553   add a socket address to the list of events, one event per dcerpc endpoint
2554 */
2555 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2556                                          struct tevent_context *event_ctx, const struct model_ops *model_ops,
2557                                          const char *address)
2558 {
2559         struct dcesrv_socket_context *dcesrv_sock;
2560         uint16_t port = 0;
2561         NTSTATUS status;
2562         const char *endpoint;
2563         char port_str[6];
2564
2565         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2566         if (endpoint != NULL) {
2567                 port = atoi(endpoint);
2568         }
2569
2570         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2571         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2572
2573         /* remember the endpoint of this socket */
2574         dcesrv_sock->endpoint           = e;
2575         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2576
2577         status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2578                                      model_ops, &dcesrv_stream_ops, 
2579                                      "ip", address, &port,
2580                                      lpcfg_socket_options(dce_ctx->lp_ctx),
2581                                      dcesrv_sock);
2582         if (!NT_STATUS_IS_OK(status)) {
2583                 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n", 
2584                          address, port, nt_errstr(status)));
2585                 return status;
2586         }
2587
2588         snprintf(port_str, sizeof(port_str), "%u", port);
2589
2590         status = dcerpc_binding_set_string_option(e->ep_description,
2591                                                   "endpoint", port_str);
2592         if (!NT_STATUS_IS_OK(status)) {
2593                 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2594                          port_str, nt_errstr(status)));
2595                 return status;
2596         } else {
2597                 struct dcesrv_if_list *iface;
2598                 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
2599                          address, port_str));
2600                 for (iface = e->interface_list; iface; iface = iface->next) {
2601                         DEBUGADD(4, ("%s ", iface->iface.name));
2602                 }
2603                 DEBUGADD(4, ("\n"));
2604         }
2605
2606         return NT_STATUS_OK;
2607 }
2608
2609 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2610
2611 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 
2612                                   struct loadparm_context *lp_ctx,
2613                                   struct dcesrv_endpoint *e,
2614                                   struct tevent_context *event_ctx, const struct model_ops *model_ops)
2615 {
2616         NTSTATUS status;
2617
2618         /* Add TCP/IP sockets */
2619         if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2620                 int num_interfaces;
2621                 int i;
2622                 struct interface *ifaces;
2623
2624                 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2625
2626                 num_interfaces = iface_list_count(ifaces);
2627                 for(i = 0; i < num_interfaces; i++) {
2628                         const char *address = iface_list_n_ip(ifaces, i);
2629                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2630                         NT_STATUS_NOT_OK_RETURN(status);
2631                 }
2632         } else {
2633                 char **wcard;
2634                 int i;
2635                 int num_binds = 0;
2636                 wcard = iface_list_wildcard(dce_ctx);
2637                 NT_STATUS_HAVE_NO_MEMORY(wcard);
2638                 for (i=0; wcard[i]; i++) {
2639                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2640                         if (NT_STATUS_IS_OK(status)) {
2641                                 num_binds++;
2642                         }
2643                 }
2644                 talloc_free(wcard);
2645                 if (num_binds == 0) {
2646                         return NT_STATUS_INVALID_PARAMETER_MIX;
2647                 }
2648         }
2649
2650         return NT_STATUS_OK;
2651 }
2652
2653 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2654                        struct loadparm_context *lp_ctx,
2655                        struct dcesrv_endpoint *e,
2656                        struct tevent_context *event_ctx,
2657                        const struct model_ops *model_ops)
2658 {
2659         enum dcerpc_transport_t transport =
2660                 dcerpc_binding_get_transport(e->ep_description);
2661
2662         switch (transport) {
2663         case NCACN_UNIX_STREAM:
2664                 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2665
2666         case NCALRPC:
2667                 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2668
2669         case NCACN_IP_TCP:
2670                 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2671
2672         case NCACN_NP:
2673                 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2674
2675         default:
2676                 return NT_STATUS_NOT_SUPPORTED;
2677         }
2678 }
2679
2680
2681 /**
2682  * retrieve credentials from a dce_call
2683  */
2684 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2685 {
2686         return dce_call->conn->auth_state.session_info->credentials;
2687 }
2688
2689 /**
2690  * returns true if this is an authenticated call
2691  */
2692 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2693 {
2694         enum security_user_level level;
2695         level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2696         return level >= SECURITY_USER;
2697 }
2698
2699 /**
2700  * retrieve account_name for a dce_call
2701  */
2702 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2703 {
2704         return dce_call->context->conn->auth_state.session_info->info->account_name;
2705 }