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