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