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