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