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