s4-rpc_server: Use a type-safe struct signature in dcerpc_register_ep_server
[sfrench/samba-autobuild/.git] / source4 / rpc_server / dcerpc_server.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    server side dcerpc core code
5
6    Copyright (C) Andrew Tridgell 2003-2005
7    Copyright (C) Stefan (metze) Metzmacher 2004-2005
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "../lib/util/dlinklist.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/dcerpc_server_proto.h"
29 #include "rpc_server/common/proto.h"
30 #include "librpc/rpc/dcerpc_proto.h"
31 #include "system/filesys.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "../lib/tsocket/tsocket.h"
35 #include "../libcli/named_pipe_auth/npa_tstream.h"
36 #include "smbd/service_stream.h"
37 #include "../lib/tsocket/tsocket.h"
38 #include "lib/socket/socket.h"
39 #include "smbd/process_model.h"
40 #include "lib/messaging/irpc.h"
41 #include "librpc/rpc/rpc_common.h"
42 #include "lib/util/samba_modules.h"
43 #include "librpc/gen_ndr/ndr_dcerpc.h"
44
45 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 */
1923 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
1924 {
1925         
1926         if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1927                 /* its already registered! */
1928                 DEBUG(0,("DCERPC endpoint server '%s' already registered\n", 
1929                          ep_server->name));
1930                 return NT_STATUS_OBJECT_NAME_COLLISION;
1931         }
1932
1933         ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1934         if (!ep_servers) {
1935                 smb_panic("out of memory in dcerpc_register");
1936         }
1937
1938         ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1939         ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1940
1941         num_ep_servers++;
1942
1943         DEBUG(3,("DCERPC endpoint server '%s' registered\n", 
1944                  ep_server->name));
1945
1946         return NT_STATUS_OK;
1947 }
1948
1949 /*
1950   return the operations structure for a named backend of the specified type
1951 */
1952 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1953 {
1954         int i;
1955
1956         for (i=0;i<num_ep_servers;i++) {
1957                 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1958                         return ep_servers[i].ep_server;
1959                 }
1960         }
1961
1962         return NULL;
1963 }
1964
1965 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1966 {
1967         static bool initialized;
1968 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1969         STATIC_dcerpc_server_MODULES_PROTO;
1970         init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1971         init_module_fn *shared_init;
1972
1973         if (initialized) {
1974                 return;
1975         }
1976         initialized = true;
1977
1978         shared_init = load_samba_modules(NULL, "dcerpc_server");
1979
1980         run_init_functions(static_init);
1981         run_init_functions(shared_init);
1982
1983         talloc_free(shared_init);
1984 }
1985
1986 /*
1987   return the DCERPC module version, and the size of some critical types
1988   This can be used by endpoint server modules to either detect compilation errors, or provide
1989   multiple implementations for different smbd compilation options in one module
1990 */
1991 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1992 {
1993         static const struct dcesrv_critical_sizes critical_sizes = {
1994                 DCERPC_MODULE_VERSION,
1995                 sizeof(struct dcesrv_context),
1996                 sizeof(struct dcesrv_endpoint),
1997                 sizeof(struct dcesrv_endpoint_server),
1998                 sizeof(struct dcesrv_interface),
1999                 sizeof(struct dcesrv_if_list),
2000                 sizeof(struct dcesrv_connection),
2001                 sizeof(struct dcesrv_call_state),
2002                 sizeof(struct dcesrv_auth),
2003                 sizeof(struct dcesrv_handle)
2004         };
2005
2006         return &critical_sizes;
2007 }
2008
2009 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2010 {
2011         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2012         struct stream_connection *srv_conn;
2013         srv_conn = talloc_get_type(dce_conn->transport.private_data,
2014                                    struct stream_connection);
2015
2016         dce_conn->allow_bind = false;
2017         dce_conn->allow_auth3 = false;
2018         dce_conn->allow_alter = false;
2019         dce_conn->allow_request = false;
2020
2021         if (dce_conn->pending_call_list == NULL) {
2022                 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2023
2024                 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2025                 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2026                 return;
2027         }
2028
2029         if (dce_conn->terminate != NULL) {
2030                 return;
2031         }
2032
2033         DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
2034                  reason));
2035         dce_conn->terminate = talloc_strdup(dce_conn, reason);
2036         if (dce_conn->terminate == NULL) {
2037                 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
2038         }
2039         DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2040 }
2041
2042 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2043 {
2044         struct dcesrv_connection *cur, *next;
2045
2046         next = dce_ctx->broken_connections;
2047         while (next != NULL) {
2048                 cur = next;
2049                 next = cur->next;
2050
2051                 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2052                         struct dcesrv_connection_context *context_cur, *context_next;
2053
2054                         context_next = cur->contexts;
2055                         while (context_next != NULL) {
2056                                 context_cur = context_next;
2057                                 context_next = context_cur->next;
2058
2059                                 dcesrv_connection_context_destructor(context_cur);
2060                         }
2061                 }
2062
2063                 dcesrv_terminate_connection(cur, cur->terminate);
2064         }
2065 }
2066
2067 /* We need this include to be able to compile on some plateforms
2068  * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2069  * correctly.
2070  * It has to be that deep because otherwise we have a conflict on
2071  * const struct dcesrv_interface declaration.
2072  * This is mostly due to socket_wrapper defining #define bind swrap_bind
2073  * which conflict with the bind used before.
2074  */
2075 #include "system/network.h"
2076
2077 struct dcesrv_sock_reply_state {
2078         struct dcesrv_connection *dce_conn;
2079         struct dcesrv_call_state *call;
2080         struct iovec iov;
2081 };
2082
2083 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2084 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2085
2086 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2087 {
2088         struct dcesrv_call_state *call;
2089
2090         call = dce_conn->call_list;
2091         if (!call || !call->replies) {
2092                 return;
2093         }
2094
2095         while (call->replies) {
2096                 struct data_blob_list_item *rep = call->replies;
2097                 struct dcesrv_sock_reply_state *substate;
2098                 struct tevent_req *subreq;
2099
2100                 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2101                 if (!substate) {
2102                         dcesrv_terminate_connection(dce_conn, "no memory");
2103                         return;
2104                 }
2105
2106                 substate->dce_conn = dce_conn;
2107                 substate->call = NULL;
2108
2109                 DLIST_REMOVE(call->replies, rep);
2110
2111                 if (call->replies == NULL && call->terminate_reason == NULL) {
2112                         substate->call = call;
2113                 }
2114
2115                 substate->iov.iov_base = (void *) rep->blob.data;
2116                 substate->iov.iov_len = rep->blob.length;
2117
2118                 subreq = tstream_writev_queue_send(substate,
2119                                                    dce_conn->event_ctx,
2120                                                    dce_conn->stream,
2121                                                    dce_conn->send_queue,
2122                                                    &substate->iov, 1);
2123                 if (!subreq) {
2124                         dcesrv_terminate_connection(dce_conn, "no memory");
2125                         return;
2126                 }
2127                 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2128                                         substate);
2129         }
2130
2131         if (call->terminate_reason != NULL) {
2132                 struct tevent_req *subreq;
2133
2134                 subreq = tevent_queue_wait_send(call,
2135                                                 dce_conn->event_ctx,
2136                                                 dce_conn->send_queue);
2137                 if (!subreq) {
2138                         dcesrv_terminate_connection(dce_conn, __location__);
2139                         return;
2140                 }
2141                 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2142                                         call);
2143         }
2144
2145         DLIST_REMOVE(call->conn->call_list, call);
2146         call->list = DCESRV_LIST_NONE;
2147 }
2148
2149 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2150 {
2151         struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2152                                                 struct dcesrv_sock_reply_state);
2153         int ret;
2154         int sys_errno;
2155         NTSTATUS status;
2156         struct dcesrv_call_state *call = substate->call;
2157
2158         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2159         TALLOC_FREE(subreq);
2160         if (ret == -1) {
2161                 status = map_nt_error_from_unix_common(sys_errno);
2162                 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2163                 return;
2164         }
2165
2166         talloc_free(substate);
2167         if (call) {
2168                 talloc_free(call);
2169         }
2170 }
2171
2172 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2173
2174 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2175 {
2176         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2177                                                 struct dcesrv_call_state);
2178         bool ok;
2179         struct timeval tv;
2180
2181         /* make sure we stop send queue before removing subreq */
2182         tevent_queue_stop(call->conn->send_queue);
2183
2184         ok = tevent_queue_wait_recv(subreq);
2185         TALLOC_FREE(subreq);
2186         if (!ok) {
2187                 dcesrv_terminate_connection(call->conn, __location__);
2188                 return;
2189         }
2190
2191         /* disconnect after 200 usecs */
2192         tv = timeval_current_ofs_usec(200);
2193         subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2194         if (subreq == NULL) {
2195                 dcesrv_terminate_connection(call->conn, __location__);
2196                 return;
2197         }
2198         tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2199                                 call);
2200 }
2201
2202 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2203 {
2204         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2205                                                 struct dcesrv_call_state);
2206         bool ok;
2207
2208         ok = tevent_wakeup_recv(subreq);
2209         TALLOC_FREE(subreq);
2210         if (!ok) {
2211                 dcesrv_terminate_connection(call->conn, __location__);
2212                 return;
2213         }
2214
2215         dcesrv_terminate_connection(call->conn, call->terminate_reason);
2216 }
2217
2218 struct dcesrv_socket_context {
2219         const struct dcesrv_endpoint *endpoint;
2220         struct dcesrv_context *dcesrv_ctx;
2221 };
2222
2223
2224 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2225
2226 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2227 {
2228         NTSTATUS status;
2229         struct dcesrv_socket_context *dcesrv_sock = 
2230                 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2231         enum dcerpc_transport_t transport =
2232                 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2233         struct dcesrv_connection *dcesrv_conn = NULL;
2234         int ret;
2235         struct tevent_req *subreq;
2236         struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2237
2238         dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2239
2240         if (!srv_conn->session_info) {
2241                 status = auth_anonymous_session_info(srv_conn,
2242                                                      lp_ctx,
2243                                                      &srv_conn->session_info);
2244                 if (!NT_STATUS_IS_OK(status)) {
2245                         DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2246                                 nt_errstr(status)));
2247                         stream_terminate_connection(srv_conn, nt_errstr(status));
2248                         return;
2249                 }
2250         }
2251
2252         status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2253                                          srv_conn,
2254                                          dcesrv_sock->endpoint,
2255                                          srv_conn->session_info,
2256                                          srv_conn->event.ctx,
2257                                          srv_conn->msg_ctx,
2258                                          srv_conn->server_id,
2259                                          DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2260                                          &dcesrv_conn);
2261         if (!NT_STATUS_IS_OK(status)) {
2262                 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
2263                         nt_errstr(status)));
2264                 stream_terminate_connection(srv_conn, nt_errstr(status));
2265                 return;
2266         }
2267
2268         dcesrv_conn->transport.private_data             = srv_conn;
2269         dcesrv_conn->transport.report_output_data       = dcesrv_sock_report_output_data;
2270
2271         TALLOC_FREE(srv_conn->event.fde);
2272
2273         dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2274         if (!dcesrv_conn->send_queue) {
2275                 status = NT_STATUS_NO_MEMORY;
2276                 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2277                         nt_errstr(status)));
2278                 stream_terminate_connection(srv_conn, nt_errstr(status));
2279                 return;
2280         }
2281
2282         if (transport == NCACN_NP) {
2283                 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2284                 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2285                                                   &srv_conn->tstream);
2286         } else {
2287                 ret = tstream_bsd_existing_socket(dcesrv_conn,
2288                                                   socket_get_fd(srv_conn->socket),
2289                                                   &dcesrv_conn->stream);
2290                 if (ret == -1) {
2291                         status = map_nt_error_from_unix_common(errno);
2292                         DEBUG(0, ("dcesrv_sock_accept: "
2293                                   "failed to setup tstream: %s\n",
2294                                   nt_errstr(status)));
2295                         stream_terminate_connection(srv_conn, nt_errstr(status));
2296                         return;
2297                 }
2298                 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2299         }
2300
2301         dcesrv_conn->local_address = srv_conn->local_address;
2302         dcesrv_conn->remote_address = srv_conn->remote_address;
2303
2304         if (transport == NCALRPC) {
2305                 uid_t uid;
2306                 gid_t gid;
2307                 int sock_fd;
2308
2309                 sock_fd = socket_get_fd(srv_conn->socket);
2310                 if (sock_fd == -1) {
2311                         stream_terminate_connection(
2312                                 srv_conn, "socket_get_fd failed\n");
2313                         return;
2314                 }
2315
2316                 ret = getpeereid(sock_fd, &uid, &gid);
2317                 if (ret == -1) {
2318                         status = map_nt_error_from_unix_common(errno);
2319                         DEBUG(0, ("dcesrv_sock_accept: "
2320                                   "getpeereid() failed for NCALRPC: %s\n",
2321                                   nt_errstr(status)));
2322                         stream_terminate_connection(srv_conn, nt_errstr(status));
2323                         return;
2324                 }
2325                 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2326                         struct tsocket_address *r = NULL;
2327
2328                         ret = tsocket_address_unix_from_path(dcesrv_conn,
2329                                                              "/root/ncalrpc_as_system",
2330                                                              &r);
2331                         if (ret == -1) {
2332                                 status = map_nt_error_from_unix_common(errno);
2333                                 DEBUG(0, ("dcesrv_sock_accept: "
2334                                           "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2335                                           nt_errstr(status)));
2336                                 stream_terminate_connection(srv_conn, nt_errstr(status));
2337                                 return;
2338                         }
2339                         dcesrv_conn->remote_address = r;
2340                 }
2341         }
2342
2343         srv_conn->private_data = dcesrv_conn;
2344
2345         irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2346
2347         subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2348                                                dcesrv_conn->event_ctx,
2349                                                dcesrv_conn->stream);
2350         if (!subreq) {
2351                 status = NT_STATUS_NO_MEMORY;
2352                 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2353                         nt_errstr(status)));
2354                 stream_terminate_connection(srv_conn, nt_errstr(status));
2355                 return;
2356         }
2357         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2358
2359         return;
2360 }
2361
2362 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2363 {
2364         struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2365                                              struct dcesrv_connection);
2366         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2367         struct ncacn_packet *pkt;
2368         DATA_BLOB buffer;
2369         NTSTATUS status;
2370
2371         if (dce_conn->terminate) {
2372                 /*
2373                  * if the current connection is broken
2374                  * we need to clean it up before any other connection
2375                  */
2376                 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2377                 dcesrv_cleanup_broken_connections(dce_ctx);
2378                 return;
2379         }
2380
2381         dcesrv_cleanup_broken_connections(dce_ctx);
2382
2383         status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2384                                                &pkt, &buffer);
2385         TALLOC_FREE(subreq);
2386         if (!NT_STATUS_IS_OK(status)) {
2387                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2388                 return;
2389         }
2390
2391         status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2392         if (!NT_STATUS_IS_OK(status)) {
2393                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2394                 return;
2395         }
2396
2397         subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2398                                                dce_conn->event_ctx,
2399                                                dce_conn->stream);
2400         if (!subreq) {
2401                 status = NT_STATUS_NO_MEMORY;
2402                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2403                 return;
2404         }
2405         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2406 }
2407
2408 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2409 {
2410         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2411                                              struct dcesrv_connection);
2412         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2413 }
2414
2415 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2416 {
2417         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2418                                              struct dcesrv_connection);
2419         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2420 }
2421
2422
2423 static const struct stream_server_ops dcesrv_stream_ops = {
2424         .name                   = "rpc",
2425         .accept_connection      = dcesrv_sock_accept,
2426         .recv_handler           = dcesrv_sock_recv,
2427         .send_handler           = dcesrv_sock_send,
2428 };
2429
2430 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 
2431                                    struct loadparm_context *lp_ctx,
2432                                    struct dcesrv_endpoint *e,
2433                             struct tevent_context *event_ctx, const struct model_ops *model_ops)
2434 {
2435         struct dcesrv_socket_context *dcesrv_sock;
2436         uint16_t port = 1;
2437         NTSTATUS status;
2438         const char *endpoint;
2439
2440         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2441         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2442
2443         /* remember the endpoint of this socket */
2444         dcesrv_sock->endpoint           = e;
2445         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2446
2447         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2448
2449         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2450                                      model_ops, &dcesrv_stream_ops, 
2451                                      "unix", endpoint, &port,
2452                                      lpcfg_socket_options(lp_ctx),
2453                                      dcesrv_sock);
2454         if (!NT_STATUS_IS_OK(status)) {
2455                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2456                          endpoint, nt_errstr(status)));
2457         }
2458
2459         return status;
2460 }
2461
2462 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 
2463                                       struct loadparm_context *lp_ctx,
2464                                       struct dcesrv_endpoint *e,
2465                                       struct tevent_context *event_ctx, const struct model_ops *model_ops)
2466 {
2467         struct dcesrv_socket_context *dcesrv_sock;
2468         uint16_t port = 1;
2469         char *full_path;
2470         NTSTATUS status;
2471         const char *endpoint;
2472
2473         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2474
2475         if (endpoint == NULL) {
2476                 /*
2477                  * No identifier specified: use DEFAULT.
2478                  *
2479                  * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2480                  * no endpoint and let the epmapper worry about it.
2481                  */
2482                 endpoint = "DEFAULT";
2483                 status = dcerpc_binding_set_string_option(e->ep_description,
2484                                                           "endpoint",
2485                                                           endpoint);
2486                 if (!NT_STATUS_IS_OK(status)) {
2487                         DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2488                                   nt_errstr(status)));
2489                         return status;
2490                 }
2491         }
2492
2493         full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2494                                     endpoint);
2495
2496         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2497         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2498
2499         /* remember the endpoint of this socket */
2500         dcesrv_sock->endpoint           = e;
2501         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2502
2503         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2504                                      model_ops, &dcesrv_stream_ops, 
2505                                      "unix", full_path, &port, 
2506                                      lpcfg_socket_options(lp_ctx),
2507                                      dcesrv_sock);
2508         if (!NT_STATUS_IS_OK(status)) {
2509                 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2510                          endpoint, full_path, nt_errstr(status)));
2511         }
2512         return status;
2513 }
2514
2515 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2516                                  struct loadparm_context *lp_ctx,
2517                                  struct dcesrv_endpoint *e,
2518                                  struct tevent_context *event_ctx, const struct model_ops *model_ops)
2519 {
2520         struct dcesrv_socket_context *dcesrv_sock;
2521         NTSTATUS status;
2522         const char *endpoint;
2523
2524         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2525         if (endpoint == NULL) {
2526                 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2527                 return NT_STATUS_INVALID_PARAMETER;
2528         }
2529
2530         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2531         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2532
2533         /* remember the endpoint of this socket */
2534         dcesrv_sock->endpoint           = e;
2535         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2536
2537         status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2538                                           model_ops, &dcesrv_stream_ops,
2539                                           endpoint,
2540                                           dcesrv_sock);
2541         if (!NT_STATUS_IS_OK(status)) {
2542                 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2543                          endpoint, nt_errstr(status)));
2544                 return status;
2545         }
2546
2547         return NT_STATUS_OK;
2548 }
2549
2550 /*
2551   add a socket address to the list of events, one event per dcerpc endpoint
2552 */
2553 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2554                                          struct tevent_context *event_ctx, const struct model_ops *model_ops,
2555                                          const char *address)
2556 {
2557         struct dcesrv_socket_context *dcesrv_sock;
2558         uint16_t port = 0;
2559         NTSTATUS status;
2560         const char *endpoint;
2561         char port_str[6];
2562
2563         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2564         if (endpoint != NULL) {
2565                 port = atoi(endpoint);
2566         }
2567
2568         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2569         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2570
2571         /* remember the endpoint of this socket */
2572         dcesrv_sock->endpoint           = e;
2573         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2574
2575         status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2576                                      model_ops, &dcesrv_stream_ops, 
2577                                      "ip", address, &port,
2578                                      lpcfg_socket_options(dce_ctx->lp_ctx),
2579                                      dcesrv_sock);
2580         if (!NT_STATUS_IS_OK(status)) {
2581                 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n", 
2582                          address, port, nt_errstr(status)));
2583                 return status;
2584         }
2585
2586         snprintf(port_str, sizeof(port_str), "%u", port);
2587
2588         status = dcerpc_binding_set_string_option(e->ep_description,
2589                                                   "endpoint", port_str);
2590         if (!NT_STATUS_IS_OK(status)) {
2591                 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2592                          port_str, nt_errstr(status)));
2593                 return status;
2594         } else {
2595                 struct dcesrv_if_list *iface;
2596                 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
2597                          address, port_str));
2598                 for (iface = e->interface_list; iface; iface = iface->next) {
2599                         DEBUGADD(4, ("%s ", iface->iface.name));
2600                 }
2601                 DEBUGADD(4, ("\n"));
2602         }
2603
2604         return NT_STATUS_OK;
2605 }
2606
2607 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2608
2609 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 
2610                                   struct loadparm_context *lp_ctx,
2611                                   struct dcesrv_endpoint *e,
2612                                   struct tevent_context *event_ctx, const struct model_ops *model_ops)
2613 {
2614         NTSTATUS status;
2615
2616         /* Add TCP/IP sockets */
2617         if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2618                 int num_interfaces;
2619                 int i;
2620                 struct interface *ifaces;
2621
2622                 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2623
2624                 num_interfaces = iface_list_count(ifaces);
2625                 for(i = 0; i < num_interfaces; i++) {
2626                         const char *address = iface_list_n_ip(ifaces, i);
2627                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2628                         NT_STATUS_NOT_OK_RETURN(status);
2629                 }
2630         } else {
2631                 char **wcard;
2632                 int i;
2633                 int num_binds = 0;
2634                 wcard = iface_list_wildcard(dce_ctx);
2635                 NT_STATUS_HAVE_NO_MEMORY(wcard);
2636                 for (i=0; wcard[i]; i++) {
2637                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2638                         if (NT_STATUS_IS_OK(status)) {
2639                                 num_binds++;
2640                         }
2641                 }
2642                 talloc_free(wcard);
2643                 if (num_binds == 0) {
2644                         return NT_STATUS_INVALID_PARAMETER_MIX;
2645                 }
2646         }
2647
2648         return NT_STATUS_OK;
2649 }
2650
2651 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2652                        struct loadparm_context *lp_ctx,
2653                        struct dcesrv_endpoint *e,
2654                        struct tevent_context *event_ctx,
2655                        const struct model_ops *model_ops)
2656 {
2657         enum dcerpc_transport_t transport =
2658                 dcerpc_binding_get_transport(e->ep_description);
2659
2660         switch (transport) {
2661         case NCACN_UNIX_STREAM:
2662                 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2663
2664         case NCALRPC:
2665                 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2666
2667         case NCACN_IP_TCP:
2668                 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2669
2670         case NCACN_NP:
2671                 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2672
2673         default:
2674                 return NT_STATUS_NOT_SUPPORTED;
2675         }
2676 }
2677
2678
2679 /**
2680  * retrieve credentials from a dce_call
2681  */
2682 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2683 {
2684         return dce_call->conn->auth_state.session_info->credentials;
2685 }
2686
2687 /**
2688  * returns true if this is an authenticated call
2689  */
2690 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2691 {
2692         enum security_user_level level;
2693         level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2694         return level >= SECURITY_USER;
2695 }
2696
2697 /**
2698  * retrieve account_name for a dce_call
2699  */
2700 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2701 {
2702         return dce_call->context->conn->auth_state.session_info->info->account_name;
2703 }