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