Fix spelling s/woks/works
[sfrench/samba-autobuild/.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 #include "../lib/util/tevent_ntstatus.h"
45
46 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
47                                 const struct dcerpc_bind *b,
48                                 struct dcerpc_ack_ctx *ack_ctx_list);
49
50 /*
51   find an association group given a assoc_group_id
52  */
53 static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context *dce_ctx,
54                                                           uint32_t id)
55 {
56         void *id_ptr;
57
58         id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
59         if (id_ptr == NULL) {
60                 return NULL;
61         }
62         return talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
63 }
64
65 /*
66   take a reference to an existing association group
67  */
68 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
69                                                                struct dcesrv_context *dce_ctx,
70                                                                uint32_t id)
71 {
72         struct dcesrv_assoc_group *assoc_group;
73
74         assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
75         if (assoc_group == NULL) {
76                 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
77                 return NULL;
78         }
79         return talloc_reference(mem_ctx, assoc_group);
80 }
81
82 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
83 {
84         int ret;
85         ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
86         if (ret != 0) {
87                 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
88                          assoc_group->id));
89         }
90         return 0;
91 }
92
93 /*
94   allocate a new association group
95  */
96 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
97                                                          struct dcesrv_context *dce_ctx)
98 {
99         struct dcesrv_assoc_group *assoc_group;
100         int id;
101
102         assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
103         if (assoc_group == NULL) {
104                 return NULL;
105         }
106         
107         id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
108         if (id == -1) {
109                 talloc_free(assoc_group);
110                 DEBUG(0,(__location__ ": Out of association groups!\n"));
111                 return NULL;
112         }
113
114         assoc_group->id = id;
115         assoc_group->dce_ctx = dce_ctx;
116
117         talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
118
119         return assoc_group;
120 }
121
122
123 /*
124   see if two endpoints match
125 */
126 static bool endpoints_match(const struct dcerpc_binding *ep1,
127                             const struct dcerpc_binding *ep2)
128 {
129         enum dcerpc_transport_t t1;
130         enum dcerpc_transport_t t2;
131         const char *e1;
132         const char *e2;
133
134         t1 = dcerpc_binding_get_transport(ep1);
135         t2 = dcerpc_binding_get_transport(ep2);
136
137         e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
138         e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
139
140         if (t1 != t2) {
141                 return false;
142         }
143
144         if (!e1 || !e2) {
145                 return e1 == e2;
146         }
147
148         if (strcasecmp(e1, e2) != 0) {
149                 return false;
150         }
151
152         return true;
153 }
154
155 /*
156   find an endpoint in the dcesrv_context
157 */
158 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
159                                              const struct dcerpc_binding *ep_description)
160 {
161         struct dcesrv_endpoint *ep;
162         for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
163                 if (endpoints_match(ep->ep_description, ep_description)) {
164                         return ep;
165                 }
166         }
167         return NULL;
168 }
169
170 /*
171   find a registered context_id from a bind or alter_context
172 */
173 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn, 
174                                                              uint16_t context_id)
175 {
176         struct dcesrv_connection_context *c;
177         for (c=conn->contexts;c;c=c->next) {
178                 if (c->context_id == context_id) return c;
179         }
180         return NULL;
181 }
182
183 /*
184   see if a uuid and if_version match to an interface
185 */
186 static bool interface_match(const struct dcesrv_interface *if1,
187                                                         const struct dcesrv_interface *if2)
188 {
189         return (if1->syntax_id.if_version == if2->syntax_id.if_version && 
190                         GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
191 }
192
193 /*
194   find the interface operations on any endpoint with this binding
195 */
196 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
197                                                                 struct dcerpc_binding *binding,
198                                                                 const struct dcesrv_interface *iface)
199 {
200         struct dcesrv_endpoint *ep;
201         for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
202                 if (endpoints_match(ep->ep_description, binding)) {
203                         struct dcesrv_if_list *ifl;
204                         for (ifl=ep->interface_list; ifl; ifl=ifl->next) {
205                                 if (interface_match(&(ifl->iface), iface)) {
206                                         return &(ifl->iface);
207                                 }
208                         }
209                 }
210         }
211         return NULL;
212 }
213
214 /*
215   see if a uuid and if_version match to an interface
216 */
217 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
218                                     const struct GUID *uuid, uint32_t if_version)
219 {
220         return (iface->syntax_id.if_version == if_version && 
221                         GUID_equal(&iface->syntax_id.uuid, uuid));
222 }
223
224 /*
225   find the interface operations on an endpoint by uuid
226 */
227 const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
228                                                       const struct GUID *uuid, uint32_t if_version)
229 {
230         struct dcesrv_if_list *ifl;
231         for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
232                 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
233                         return &(ifl->iface);
234                 }
235         }
236         return NULL;
237 }
238
239 /*
240   find the earlier parts of a fragmented call awaiting reassembily
241 */
242 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint32_t call_id)
243 {
244         struct dcesrv_call_state *c;
245         for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
246                 if (c->pkt.call_id == call_id) {
247                         return c;
248                 }
249         }
250         return NULL;
251 }
252
253 /*
254   register an interface on an endpoint
255
256   An endpoint is one unix domain socket (for ncalrpc), one TCP port
257   (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
258
259   Each endpoint can have many interfaces such as netlogon, lsa or
260   samr.  Some have essentially the full set.
261
262   This is driven from the set of interfaces listed in each IDL file
263   via the PIDL generated *__op_init_server() functions.
264 */
265 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
266                                    const char *ep_name,
267                                    const struct dcesrv_interface *iface,
268                                    const struct security_descriptor *sd)
269 {
270         struct dcesrv_endpoint *ep;
271         struct dcesrv_if_list *ifl;
272         struct dcerpc_binding *binding;
273         bool add_ep = false;
274         NTSTATUS status;
275         enum dcerpc_transport_t transport;
276         char *ep_string = NULL;
277         bool use_single_process = true;
278         const char *ep_process_string;
279
280         /*
281          * If we are not using handles, there is no need for force
282          * this service into using a single process.
283          *
284          * However, due to the way we listen for RPC packets, we can
285          * only do this if we have a single service per pipe or TCP
286          * port, so we still force a single combined process for
287          * ncalrpc.
288          */
289         if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
290                 use_single_process = false;
291         }
292
293         status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
294
295         if (NT_STATUS_IS_ERR(status)) {
296                 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
297                 return status;
298         }
299
300         transport = dcerpc_binding_get_transport(binding);
301         if (transport == NCACN_IP_TCP) {
302                 int port;
303                 char port_str[6];
304
305                 /* 
306                  * First check if there is already a port specified, eg
307                  * for epmapper on ncacn_ip_tcp:[135]
308                  */
309                 const char *endpoint
310                         = dcerpc_binding_get_string_option(binding,
311                                                            "endpoint");
312                 if (endpoint == NULL) {
313                         port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
314                                               "rpc server port", iface->name, 0);
315                         
316                         /*
317                          * For RPC services that are not set to use a single
318                          * process, we do not default to using the 'rpc server
319                          * port' because that would cause a double-bind on
320                          * that port.
321                          */
322                         if (port == 0 && !use_single_process) {
323                                 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
324                         }
325                         if (port != 0) {
326                                 snprintf(port_str, sizeof(port_str), "%u", port);
327                                 status = dcerpc_binding_set_string_option(binding,
328                                                                           "endpoint",
329                                                                           port_str);
330                                 if (!NT_STATUS_IS_OK(status)) {
331                                         return status;
332                                 }
333                         }
334                 }
335         }
336
337         /* see if the interface is already registered on the endpoint */
338         if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
339                 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
340                          iface->name, ep_name));
341                 return NT_STATUS_OBJECT_NAME_COLLISION;
342         }
343
344         /* check if this endpoint exists
345          */
346         ep = find_endpoint(dce_ctx, binding);
347
348         if (ep != NULL) {
349                 /*
350                  * We want a new port on ncacn_ip_tcp for NETLOGON, so
351                  * it can be multi-process.  Other processes can also
352                  * listen on distinct ports, if they have one forced
353                  * in the code above with eg 'rpc server port:drsuapi = 1027'
354                  *
355                  * If we have mulitiple endpoints on port 0, they each
356                  * get an epemeral port (currently by walking up from
357                  * 1024).
358                  *
359                  * Because one endpoint can only have one process
360                  * model, we add a new IP_TCP endpoint for each model.
361                  *
362                  * This works in conjunction with the forced overwrite
363                  * of ep->use_single_process below.
364                  */
365                 if (ep->use_single_process != use_single_process
366                     && transport == NCACN_IP_TCP) {
367                         add_ep = true;
368                 }
369         }
370
371         if (ep == NULL || add_ep) {
372                 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
373                 if (!ep) {
374                         return NT_STATUS_NO_MEMORY;
375                 }
376                 ZERO_STRUCTP(ep);
377                 ep->ep_description = talloc_move(ep, &binding);
378                 add_ep = true;
379
380                 /* add mgmt interface */
381                 ifl = talloc_zero(ep, struct dcesrv_if_list);
382                 if (!ifl) {
383                         return NT_STATUS_NO_MEMORY;
384                 }
385
386                 ifl->iface = dcesrv_get_mgmt_interface();
387
388                 DLIST_ADD(ep->interface_list, ifl);
389         }
390
391         /*
392          * By default don't force into a single process, but if any
393          * interface on this endpoint on this service uses handles
394          * (most do), then we must force into single process mode
395          *
396          * By overwriting this each time a new interface is added to
397          * this endpoint, we end up with the most restrictive setting.
398          */
399         if (use_single_process) {
400                 ep->use_single_process = true;
401         }
402
403         /* talloc a new interface list element */
404         ifl = talloc_zero(ep, struct dcesrv_if_list);
405         if (!ifl) {
406                 return NT_STATUS_NO_MEMORY;
407         }
408
409         /* copy the given interface struct to the one on the endpoints interface list */
410         memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
411
412         /* if we have a security descriptor given,
413          * we should see if we can set it up on the endpoint
414          */
415         if (sd != NULL) {
416                 /* if there's currently no security descriptor given on the endpoint
417                  * we try to set it
418                  */
419                 if (ep->sd == NULL) {
420                         ep->sd = security_descriptor_copy(ep, sd);
421                 }
422
423                 /* if now there's no security descriptor given on the endpoint
424                  * something goes wrong, either we failed to copy the security descriptor
425                  * or there was already one on the endpoint
426                  */
427                 if (ep->sd != NULL) {
428                         DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
429                                  "                           on endpoint '%s'\n",
430                                 iface->name, ep_name));
431                         if (add_ep) free(ep);
432                         free(ifl);
433                         return NT_STATUS_OBJECT_NAME_COLLISION;
434                 }
435         }
436
437         /* finally add the interface on the endpoint */
438         DLIST_ADD(ep->interface_list, ifl);
439
440         /* if it's a new endpoint add it to the dcesrv_context */
441         if (add_ep) {
442                 DLIST_ADD(dce_ctx->endpoint_list, ep);
443         }
444
445         /* Re-get the string as we may have set a port */
446         ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
447
448         if (use_single_process) {
449                 ep_process_string = "single process required";
450         } else {
451                 ep_process_string = "multi process compatible";
452         }
453
454         DBG_INFO("dcesrv_interface_register: interface '%s' "
455                  "registered on endpoint '%s' (%s)\n",
456                  iface->name, ep_string, ep_process_string);
457         TALLOC_FREE(ep_string);
458
459         return NT_STATUS_OK;
460 }
461
462 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
463                                       DATA_BLOB *session_key)
464 {
465         if (p->auth_state.session_info->session_key.length) {
466                 *session_key = p->auth_state.session_info->session_key;
467                 return NT_STATUS_OK;
468         }
469         return NT_STATUS_NO_USER_SESSION_KEY;
470 }
471
472 /*
473   fetch the user session key - may be default (above) or the SMB session key
474
475   The key is always truncated to 16 bytes 
476 */
477 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
478                                   DATA_BLOB *session_key)
479 {
480         NTSTATUS status = p->auth_state.session_key(p, session_key);
481         if (!NT_STATUS_IS_OK(status)) {
482                 return status;
483         }
484
485         session_key->length = MIN(session_key->length, 16);
486
487         return NT_STATUS_OK;
488 }
489
490 /*
491   connect to a dcerpc endpoint
492 */
493 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
494                                  TALLOC_CTX *mem_ctx,
495                                  const struct dcesrv_endpoint *ep,
496                                  struct auth_session_info *session_info,
497                                  struct tevent_context *event_ctx,
498                                  struct imessaging_context *msg_ctx,
499                                  struct server_id server_id,
500                                  uint32_t state_flags,
501                                  struct dcesrv_connection **_p)
502 {
503         struct dcesrv_connection *p;
504
505         if (!session_info) {
506                 return NT_STATUS_ACCESS_DENIED;
507         }
508
509         p = talloc_zero(mem_ctx, struct dcesrv_connection);
510         NT_STATUS_HAVE_NO_MEMORY(p);
511
512         if (!talloc_reference(p, session_info)) {
513                 talloc_free(p);
514                 return NT_STATUS_NO_MEMORY;
515         }
516
517         p->dce_ctx = dce_ctx;
518         p->endpoint = ep;
519         p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
520         p->auth_state.session_info = session_info;
521         p->auth_state.session_key = dcesrv_generic_session_key;
522         p->event_ctx = event_ctx;
523         p->msg_ctx = msg_ctx;
524         p->server_id = server_id;
525         p->state_flags = state_flags;
526         p->allow_bind = true;
527         p->max_recv_frag = 5840;
528         p->max_xmit_frag = 5840;
529         p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
530
531         /*
532          * For now we only support NDR32.
533          */
534         p->preferred_transfer = &ndr_transfer_syntax_ndr;
535
536         *_p = p;
537         return NT_STATUS_OK;
538 }
539
540 /*
541   move a call from an existing linked list to the specified list. This
542   prevents bugs where we forget to remove the call from a previous
543   list when moving it.
544  */
545 static void dcesrv_call_set_list(struct dcesrv_call_state *call, 
546                                  enum dcesrv_call_list list)
547 {
548         switch (call->list) {
549         case DCESRV_LIST_NONE:
550                 break;
551         case DCESRV_LIST_CALL_LIST:
552                 DLIST_REMOVE(call->conn->call_list, call);
553                 break;
554         case DCESRV_LIST_FRAGMENTED_CALL_LIST:
555                 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
556                 break;
557         case DCESRV_LIST_PENDING_CALL_LIST:
558                 DLIST_REMOVE(call->conn->pending_call_list, call);
559                 break;
560         }
561         call->list = list;
562         switch (list) {
563         case DCESRV_LIST_NONE:
564                 break;
565         case DCESRV_LIST_CALL_LIST:
566                 DLIST_ADD_END(call->conn->call_list, call);
567                 break;
568         case DCESRV_LIST_FRAGMENTED_CALL_LIST:
569                 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
570                 break;
571         case DCESRV_LIST_PENDING_CALL_LIST:
572                 DLIST_ADD_END(call->conn->pending_call_list, call);
573                 break;
574         }
575 }
576
577 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
578                                          const char *reason)
579 {
580         if (call->conn->terminate != NULL) {
581                 return;
582         }
583
584         call->conn->allow_bind = false;
585         call->conn->allow_alter = false;
586         call->conn->allow_auth3 = false;
587         call->conn->allow_request = false;
588
589         call->terminate_reason = talloc_strdup(call, reason);
590         if (call->terminate_reason == NULL) {
591                 call->terminate_reason = __location__;
592         }
593 }
594
595 /*
596   return a dcerpc bind_nak
597 */
598 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
599 {
600         struct ncacn_packet pkt;
601         struct dcerpc_bind_nak_version version;
602         struct data_blob_list_item *rep;
603         NTSTATUS status;
604         static const uint8_t _pad[3] = { 0, };
605
606         /*
607          * We add the call to the pending_call_list
608          * in order to defer the termination.
609          */
610         dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
611
612         /* setup a bind_nak */
613         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
614         pkt.auth_length = 0;
615         pkt.call_id = call->pkt.call_id;
616         pkt.ptype = DCERPC_PKT_BIND_NAK;
617         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
618         pkt.u.bind_nak.reject_reason = reason;
619         version.rpc_vers = 5;
620         version.rpc_vers_minor = 0;
621         pkt.u.bind_nak.num_versions = 1;
622         pkt.u.bind_nak.versions = &version;
623         pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
624
625         rep = talloc_zero(call, struct data_blob_list_item);
626         if (!rep) {
627                 return NT_STATUS_NO_MEMORY;
628         }
629
630         status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
631         if (!NT_STATUS_IS_OK(status)) {
632                 return status;
633         }
634
635         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
636
637         DLIST_ADD_END(call->replies, rep);
638         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
639
640         if (call->conn->call_list && call->conn->call_list->replies) {
641                 if (call->conn->transport.report_output_data) {
642                         call->conn->transport.report_output_data(call->conn);
643                 }
644         }
645
646         return NT_STATUS_OK;    
647 }
648
649 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
650                                  uint32_t fault_code)
651 {
652         /*
653          * We add the call to the pending_call_list
654          * in order to defer the termination.
655          */
656         dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
657
658         return dcesrv_fault_with_flags(call, fault_code,
659                                        DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
660 }
661
662 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
663 {
664         DLIST_REMOVE(c->conn->contexts, c);
665
666         if (c->iface && c->iface->unbind) {
667                 c->iface->unbind(c, c->iface);
668                 c->iface = NULL;
669         }
670
671         return 0;
672 }
673
674 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
675 {
676         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
677         const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
678         enum dcerpc_transport_t transport =
679                 dcerpc_binding_get_transport(endpoint->ep_description);
680         struct dcesrv_connection_context *context = dce_call->context;
681         const struct dcesrv_interface *iface = context->iface;
682
683         context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
684
685         if (transport == NCALRPC) {
686                 context->allow_connect = true;
687                 return;
688         }
689
690         /*
691          * allow overwrite per interface
692          * allow dcerpc auth level connect:<interface>
693          */
694         context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
695         context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
696                                         "allow dcerpc auth level connect",
697                                         iface->name,
698                                         context->allow_connect);
699 }
700
701 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
702                                                  const struct dcesrv_interface *iface)
703 {
704         if (dce_call->context == NULL) {
705                 return NT_STATUS_INTERNAL_ERROR;
706         }
707
708         /*
709          * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
710          * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
711          */
712         dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
713         return NT_STATUS_OK;
714 }
715
716 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
717                                                const struct dcesrv_interface *iface)
718 {
719         if (dce_call->context == NULL) {
720                 return NT_STATUS_INTERNAL_ERROR;
721         }
722
723         dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
724         return NT_STATUS_OK;
725 }
726
727 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
728                                                        const struct dcesrv_interface *iface)
729 {
730         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
731         const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
732         enum dcerpc_transport_t transport =
733                 dcerpc_binding_get_transport(endpoint->ep_description);
734         struct dcesrv_connection_context *context = dce_call->context;
735
736         if (context == NULL) {
737                 return NT_STATUS_INTERNAL_ERROR;
738         }
739
740         if (transport == NCALRPC) {
741                 context->allow_connect = true;
742                 return NT_STATUS_OK;
743         }
744
745         /*
746          * allow overwrite per interface
747          * allow dcerpc auth level connect:<interface>
748          */
749         context->allow_connect = false;
750         context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
751                                         "allow dcerpc auth level connect",
752                                         iface->name,
753                                         context->allow_connect);
754         return NT_STATUS_OK;
755 }
756
757 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
758                                                       const struct dcesrv_interface *iface)
759 {
760         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
761         const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
762         enum dcerpc_transport_t transport =
763                 dcerpc_binding_get_transport(endpoint->ep_description);
764         struct dcesrv_connection_context *context = dce_call->context;
765
766         if (context == NULL) {
767                 return NT_STATUS_INTERNAL_ERROR;
768         }
769
770         if (transport == NCALRPC) {
771                 context->allow_connect = true;
772                 return NT_STATUS_OK;
773         }
774
775         /*
776          * allow overwrite per interface
777          * allow dcerpc auth level connect:<interface>
778          */
779         context->allow_connect = true;
780         context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
781                                         "allow dcerpc auth level connect",
782                                         iface->name,
783                                         context->allow_connect);
784         return NT_STATUS_OK;
785 }
786
787 struct dcesrv_conn_auth_wait_context {
788         struct tevent_req *req;
789         bool done;
790         NTSTATUS status;
791 };
792
793 struct dcesrv_conn_auth_wait_state {
794         uint8_t dummy;
795 };
796
797 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
798                                                      struct tevent_context *ev,
799                                                      void *private_data)
800 {
801         struct dcesrv_conn_auth_wait_context *auth_wait =
802                 talloc_get_type_abort(private_data,
803                 struct dcesrv_conn_auth_wait_context);
804         struct tevent_req *req = NULL;
805         struct dcesrv_conn_auth_wait_state *state = NULL;
806
807         req = tevent_req_create(mem_ctx, &state,
808                                 struct dcesrv_conn_auth_wait_state);
809         if (req == NULL) {
810                 return NULL;
811         }
812         auth_wait->req = req;
813
814         tevent_req_defer_callback(req, ev);
815
816         if (!auth_wait->done) {
817                 return req;
818         }
819
820         if (tevent_req_nterror(req, auth_wait->status)) {
821                 return tevent_req_post(req, ev);
822         }
823
824         tevent_req_done(req);
825         return tevent_req_post(req, ev);
826 }
827
828 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
829 {
830         return tevent_req_simple_recv_ntstatus(req);
831 }
832
833 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
834 {
835         struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
836
837         if (conn->wait_send != NULL) {
838                 return NT_STATUS_INTERNAL_ERROR;
839         }
840
841         auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
842         if (auth_wait == NULL) {
843                 return NT_STATUS_NO_MEMORY;
844         }
845
846         conn->wait_private = auth_wait;
847         conn->wait_send = dcesrv_conn_auth_wait_send;
848         conn->wait_recv = dcesrv_conn_auth_wait_recv;
849         return NT_STATUS_OK;
850 }
851
852 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
853                                            NTSTATUS status)
854 {
855         struct dcesrv_conn_auth_wait_context *auth_wait =
856                 talloc_get_type_abort(conn->wait_private,
857                 struct dcesrv_conn_auth_wait_context);
858
859         auth_wait->done = true;
860         auth_wait->status = status;
861
862         if (auth_wait->req == NULL) {
863                 return;
864         }
865
866         if (tevent_req_nterror(auth_wait->req, status)) {
867                 return;
868         }
869
870         tevent_req_done(auth_wait->req);
871 }
872
873 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
874
875 static void dcesrv_bind_done(struct tevent_req *subreq);
876
877 /*
878   handle a bind request
879 */
880 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
881 {
882         struct dcesrv_connection *conn = call->conn;
883         struct ncacn_packet *pkt = &call->ack_pkt;
884         NTSTATUS status;
885         uint32_t extra_flags = 0;
886         uint16_t max_req = 0;
887         uint16_t max_rep = 0;
888         const char *ep_prefix = "";
889         const char *endpoint = NULL;
890         struct dcesrv_auth *auth = &call->conn->auth_state;
891         struct dcerpc_ack_ctx *ack_ctx_list = NULL;
892         struct dcerpc_ack_ctx *ack_features = NULL;
893         struct tevent_req *subreq = NULL;
894         size_t i;
895
896         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
897                         DCERPC_PKT_BIND,
898                         call->pkt.u.bind.auth_info.length,
899                         0, /* required flags */
900                         DCERPC_PFC_FLAG_FIRST |
901                         DCERPC_PFC_FLAG_LAST |
902                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
903                         0x08 | /* this is not defined, but should be ignored */
904                         DCERPC_PFC_FLAG_CONC_MPX |
905                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
906                         DCERPC_PFC_FLAG_MAYBE |
907                         DCERPC_PFC_FLAG_OBJECT_UUID);
908         if (!NT_STATUS_IS_OK(status)) {
909                 return dcesrv_bind_nak(call,
910                         DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
911         }
912
913         /* max_recv_frag and max_xmit_frag result always in the same value! */
914         max_req = MIN(call->pkt.u.bind.max_xmit_frag,
915                       call->pkt.u.bind.max_recv_frag);
916         /*
917          * The values are between 2048 and 5840 tested against Windows 2012R2
918          * via ncacn_ip_tcp on port 135.
919          */
920         max_req = MAX(2048, max_req);
921         max_rep = MIN(max_req, call->conn->max_recv_frag);
922         /* They are truncated to an 8 byte boundary. */
923         max_rep &= 0xFFF8;
924
925         /* max_recv_frag and max_xmit_frag result always in the same value! */
926         call->conn->max_recv_frag = max_rep;
927         call->conn->max_xmit_frag = max_rep;
928
929         /*
930           if provided, check the assoc_group is valid
931          */
932         if (call->pkt.u.bind.assoc_group_id != 0) {
933                 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
934                                                                        call->conn->dce_ctx,
935                                                                        call->pkt.u.bind.assoc_group_id);
936         } else {
937                 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
938                                                                  call->conn->dce_ctx);
939         }
940
941         /*
942          * The NETLOGON server does not use handles and so
943          * there is no need to support association groups, but
944          * we need to give back a number regardless.
945          *
946          * We have to do this when it is not run as a single process,
947          * because then it can't see the other valid association
948          * groups.  We handle this genericly for all endpoints not
949          * running in single process mode.
950          *
951          * We know which endpoint we are on even before checking the
952          * iface UUID, so for simplicity we enforce the same policy
953          * for all interfaces on the endpoint.
954          *
955          * This means that where NETLOGON
956          * shares an endpoint (such as ncalrpc or of 'lsa over
957          * netlogon' is set) we will still check association groups.
958          *
959          */
960
961         if (call->conn->assoc_group == NULL &&
962             !call->conn->endpoint->use_single_process) {
963                 call->conn->assoc_group
964                         = dcesrv_assoc_group_new(call->conn,
965                                                  call->conn->dce_ctx);
966         }
967         if (call->conn->assoc_group == NULL) {
968                 return dcesrv_bind_nak(call, 0);
969         }
970
971         if (call->pkt.u.bind.num_contexts < 1) {
972                 return dcesrv_bind_nak(call, 0);
973         }
974
975         ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
976                                          call->pkt.u.bind.num_contexts);
977         if (ack_ctx_list == NULL) {
978                 return dcesrv_bind_nak(call, 0);
979         }
980
981         /*
982          * Set some sane defaults (required by dcesrv_negotiate_contexts()/
983          * dcesrv_check_or_create_context()) and do some protocol validation
984          * and set sane defaults.
985          */
986         for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
987                 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
988                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
989                 bool is_feature = false;
990                 uint64_t features = 0;
991
992                 if (c->num_transfer_syntaxes == 0) {
993                         return dcesrv_bind_nak(call, 0);
994                 }
995
996                 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
997                 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
998
999                 /*
1000                  * It's only treated as bind time feature request, if the first
1001                  * transfer_syntax matches, all others are ignored.
1002                  */
1003                 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1004                                                                &features);
1005                 if (!is_feature) {
1006                         continue;
1007                 }
1008
1009                 if (ack_features != NULL) {
1010                         /*
1011                          * Only one bind time feature context is allowed.
1012                          */
1013                         return dcesrv_bind_nak(call, 0);
1014                 }
1015                 ack_features = a;
1016
1017                 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1018                 a->reason.negotiate = 0;
1019                 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1020                         /* not supported yet */
1021                 }
1022                 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1023                         a->reason.negotiate |=
1024                                 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1025                 }
1026
1027                 call->conn->bind_time_features = a->reason.negotiate;
1028         }
1029
1030         /*
1031          * Try to negotiate one new presentation context.
1032          *
1033          * Deep in here we locate the iface (by uuid) that the client
1034          * requested, from the list of interfaces on the
1035          * call->conn->endpoint, and call iface->bind() on that iface.
1036          *
1037          * call->conn was set up at the accept() of the socket, and
1038          * call->conn->endpoint has a list of interfaces restricted to
1039          * this port or pipe.
1040          */
1041         status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1042         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1043                 return dcesrv_bind_nak(call, 0);
1044         }
1045         if (!NT_STATUS_IS_OK(status)) {
1046                 return status;
1047         }
1048
1049         /*
1050          * At this point we still don't know which interface (eg
1051          * netlogon, lsa, drsuapi) the caller requested in this bind!
1052          * The most recently added context is available as the first
1053          * element in the linked list at call->conn->contexts, that is
1054          * call->conn->contexts->iface, but they may not have
1055          * requested one at all!
1056          */
1057
1058         if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1059             (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1060                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1061                 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1062         }
1063
1064         if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1065                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1066         }
1067
1068         /*
1069          * After finding the interface and setting up the NDR
1070          * transport negotiation etc, handle any authentication that
1071          * is being requested.
1072          */
1073         if (!dcesrv_auth_bind(call)) {
1074
1075                 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1076                         /*
1077                          * With DCERPC_AUTH_LEVEL_NONE, we get the
1078                          * reject_reason in auth->auth_context_id.
1079                          */
1080                         return dcesrv_bind_nak(call, auth->auth_context_id);
1081                 }
1082
1083                 /*
1084                  * This must a be a temporary failure e.g. talloc or invalid
1085                  * configuration, e.g. no machine account.
1086                  */
1087                 return dcesrv_bind_nak(call,
1088                                 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1089         }
1090
1091         /* setup a bind_ack */
1092         dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1093         pkt->auth_length = 0;
1094         pkt->call_id = call->pkt.call_id;
1095         pkt->ptype = DCERPC_PKT_BIND_ACK;
1096         pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1097         pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1098         pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1099         pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1100
1101         endpoint = dcerpc_binding_get_string_option(
1102                                 call->conn->endpoint->ep_description,
1103                                 "endpoint");
1104         if (endpoint == NULL) {
1105                 endpoint = "";
1106         }
1107
1108         if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1109                 /*
1110                  * TODO: check if this is really needed
1111                  *
1112                  * Or if we should fix this in our idl files.
1113                  */
1114                 ep_prefix = "\\PIPE\\";
1115                 endpoint += 6;
1116         }
1117
1118         pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1119                                                            ep_prefix,
1120                                                            endpoint);
1121         if (pkt->u.bind_ack.secondary_address == NULL) {
1122                 return NT_STATUS_NO_MEMORY;
1123         }
1124         pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1125         pkt->u.bind_ack.ctx_list = ack_ctx_list;
1126         pkt->u.bind_ack.auth_info = data_blob_null;
1127
1128         status = dcesrv_auth_prepare_bind_ack(call, pkt);
1129         if (!NT_STATUS_IS_OK(status)) {
1130                 return dcesrv_bind_nak(call, 0);
1131         }
1132
1133         if (auth->auth_finished) {
1134                 return dcesrv_auth_reply(call);
1135         }
1136
1137         subreq = gensec_update_send(call, call->event_ctx,
1138                                     auth->gensec_security,
1139                                     call->in_auth_info.credentials);
1140         if (subreq == NULL) {
1141                 return NT_STATUS_NO_MEMORY;
1142         }
1143         tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1144
1145         return dcesrv_conn_auth_wait_setup(conn);
1146 }
1147
1148 static void dcesrv_bind_done(struct tevent_req *subreq)
1149 {
1150         struct dcesrv_call_state *call =
1151                 tevent_req_callback_data(subreq,
1152                 struct dcesrv_call_state);
1153         struct dcesrv_connection *conn = call->conn;
1154         NTSTATUS status;
1155
1156         status = gensec_update_recv(subreq, call,
1157                                     &call->out_auth_info->credentials);
1158         TALLOC_FREE(subreq);
1159
1160         status = dcesrv_auth_complete(call, status);
1161         if (!NT_STATUS_IS_OK(status)) {
1162                 status = dcesrv_bind_nak(call, 0);
1163                 dcesrv_conn_auth_wait_finished(conn, status);
1164                 return;
1165         }
1166
1167         status = dcesrv_auth_reply(call);
1168         dcesrv_conn_auth_wait_finished(conn, status);
1169         return;
1170 }
1171
1172 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1173 {
1174         struct ncacn_packet *pkt = &call->ack_pkt;
1175         struct data_blob_list_item *rep = NULL;
1176         NTSTATUS status;
1177
1178         rep = talloc_zero(call, struct data_blob_list_item);
1179         if (!rep) {
1180                 return NT_STATUS_NO_MEMORY;
1181         }
1182
1183         status = ncacn_push_auth(&rep->blob, call, pkt,
1184                                  call->out_auth_info);
1185         if (!NT_STATUS_IS_OK(status)) {
1186                 return status;
1187         }
1188
1189         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1190
1191         DLIST_ADD_END(call->replies, rep);
1192         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1193
1194         if (call->conn->call_list && call->conn->call_list->replies) {
1195                 if (call->conn->transport.report_output_data) {
1196                         call->conn->transport.report_output_data(call->conn);
1197                 }
1198         }
1199
1200         return NT_STATUS_OK;
1201 }
1202
1203
1204 static void dcesrv_auth3_done(struct tevent_req *subreq);
1205
1206 /*
1207   handle a auth3 request
1208 */
1209 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1210 {
1211         struct dcesrv_connection *conn = call->conn;
1212         struct dcesrv_auth *auth = &call->conn->auth_state;
1213         struct tevent_req *subreq = NULL;
1214         NTSTATUS status;
1215
1216         if (!call->conn->allow_auth3) {
1217                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1218         }
1219
1220         if (call->conn->auth_state.auth_finished) {
1221                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1222         }
1223
1224         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1225                         DCERPC_PKT_AUTH3,
1226                         call->pkt.u.auth3.auth_info.length,
1227                         0, /* required flags */
1228                         DCERPC_PFC_FLAG_FIRST |
1229                         DCERPC_PFC_FLAG_LAST |
1230                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1231                         0x08 | /* this is not defined, but should be ignored */
1232                         DCERPC_PFC_FLAG_CONC_MPX |
1233                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1234                         DCERPC_PFC_FLAG_MAYBE |
1235                         DCERPC_PFC_FLAG_OBJECT_UUID);
1236         if (!NT_STATUS_IS_OK(status)) {
1237                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1238         }
1239
1240         /* handle the auth3 in the auth code */
1241         if (!dcesrv_auth_prepare_auth3(call)) {
1242                 /*
1243                  * we don't send a reply to a auth3 request,
1244                  * except by a fault.
1245                  *
1246                  * In anycase we mark the connection as
1247                  * invalid.
1248                  */
1249                 call->conn->auth_state.auth_invalid = true;
1250                 if (call->fault_code != 0) {
1251                         return dcesrv_fault_disconnect(call, call->fault_code);
1252                 }
1253                 TALLOC_FREE(call);
1254                 return NT_STATUS_OK;
1255         }
1256
1257         subreq = gensec_update_send(call, call->event_ctx,
1258                                     auth->gensec_security,
1259                                     call->in_auth_info.credentials);
1260         if (subreq == NULL) {
1261                 return NT_STATUS_NO_MEMORY;
1262         }
1263         tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1264
1265         return dcesrv_conn_auth_wait_setup(conn);
1266 }
1267
1268 static void dcesrv_auth3_done(struct tevent_req *subreq)
1269 {
1270         struct dcesrv_call_state *call =
1271                 tevent_req_callback_data(subreq,
1272                 struct dcesrv_call_state);
1273         struct dcesrv_connection *conn = call->conn;
1274         NTSTATUS status;
1275
1276         status = gensec_update_recv(subreq, call,
1277                                     &call->out_auth_info->credentials);
1278         TALLOC_FREE(subreq);
1279
1280         status = dcesrv_auth_complete(call, status);
1281         if (!NT_STATUS_IS_OK(status)) {
1282                 /*
1283                  * we don't send a reply to a auth3 request,
1284                  * except by a fault.
1285                  *
1286                  * In anycase we mark the connection as
1287                  * invalid.
1288                  */
1289                 call->conn->auth_state.auth_invalid = true;
1290                 if (call->fault_code != 0) {
1291                         status = dcesrv_fault_disconnect(call, call->fault_code);
1292                         dcesrv_conn_auth_wait_finished(conn, status);
1293                         return;
1294                 }
1295                 TALLOC_FREE(call);
1296                 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1297                 return;
1298         }
1299
1300         /*
1301          * we don't send a reply to a auth3 request.
1302          */
1303         TALLOC_FREE(call);
1304         dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1305         return;
1306 }
1307
1308
1309 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1310                                 const struct dcerpc_bind *b,
1311                                 const struct dcerpc_ctx_list *ctx,
1312                                 struct dcerpc_ack_ctx *ack,
1313                                 bool validate_only,
1314                                 const struct ndr_syntax_id *supported_transfer)
1315 {
1316         uint32_t if_version;
1317         struct dcesrv_connection_context *context;
1318         const struct dcesrv_interface *iface;
1319         struct GUID uuid;
1320         NTSTATUS status;
1321         const struct ndr_syntax_id *selected_transfer = NULL;
1322         size_t i;
1323         bool ok;
1324
1325         if (b == NULL) {
1326                 return NT_STATUS_INTERNAL_ERROR;
1327         }
1328         if (ctx == NULL) {
1329                 return NT_STATUS_INTERNAL_ERROR;
1330         }
1331         if (ctx->num_transfer_syntaxes < 1) {
1332                 return NT_STATUS_INTERNAL_ERROR;
1333         }
1334         if (ack == NULL) {
1335                 return NT_STATUS_INTERNAL_ERROR;
1336         }
1337         if (supported_transfer == NULL) {
1338                 return NT_STATUS_INTERNAL_ERROR;
1339         }
1340
1341         switch (ack->result) {
1342         case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1343         case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1344                 /*
1345                  * We is already completed.
1346                  */
1347                 return NT_STATUS_OK;
1348         default:
1349                 break;
1350         }
1351
1352         ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1353         ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1354
1355         if_version = ctx->abstract_syntax.if_version;
1356         uuid = ctx->abstract_syntax.uuid;
1357
1358         iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1359         if (iface == NULL) {
1360                 char *uuid_str = GUID_string(call, &uuid);
1361                 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1362                 talloc_free(uuid_str);
1363                 /*
1364                  * We report this only via ack->result
1365                  */
1366                 return NT_STATUS_OK;
1367         }
1368
1369         ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1370         ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1371
1372         if (validate_only) {
1373                 /*
1374                  * We report this only via ack->result
1375                  */
1376                 return NT_STATUS_OK;
1377         }
1378
1379         for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1380                 /*
1381                  * we only do NDR encoded dcerpc for now.
1382                  */
1383                 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1384                                          supported_transfer);
1385                 if (ok) {
1386                         selected_transfer = supported_transfer;
1387                         break;
1388                 }
1389         }
1390
1391         context = dcesrv_find_context(call->conn, ctx->context_id);
1392         if (context != NULL) {
1393                 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1394                                          &ctx->abstract_syntax);
1395                 if (!ok) {
1396                         return NT_STATUS_RPC_PROTOCOL_ERROR;
1397                 }
1398
1399                 if (selected_transfer != NULL) {
1400                         ok = ndr_syntax_id_equal(&context->transfer_syntax,
1401                                                  selected_transfer);
1402                         if (!ok) {
1403                                 return NT_STATUS_RPC_PROTOCOL_ERROR;
1404                         }
1405
1406                         ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1407                         ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1408                         ack->syntax = context->transfer_syntax;
1409                 }
1410
1411                 /*
1412                  * We report this only via ack->result
1413                  */
1414                 return NT_STATUS_OK;
1415         }
1416
1417         if (selected_transfer == NULL) {
1418                 /*
1419                  * We report this only via ack->result
1420                  */
1421                 return NT_STATUS_OK;
1422         }
1423
1424         ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1425         ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1426
1427         /* add this context to the list of available context_ids */
1428         context = talloc_zero(call->conn, struct dcesrv_connection_context);
1429         if (context == NULL) {
1430                 return NT_STATUS_NO_MEMORY;
1431         }
1432         context->conn = call->conn;
1433         context->context_id = ctx->context_id;
1434         context->iface = iface;
1435         context->transfer_syntax = *selected_transfer;
1436         context->private_data = NULL;
1437         DLIST_ADD(call->conn->contexts, context);
1438         call->context = context;
1439         talloc_set_destructor(context, dcesrv_connection_context_destructor);
1440
1441         dcesrv_prepare_context_auth(call);
1442
1443         /*
1444          * Multiplex is supported by default
1445          */
1446         call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1447
1448         status = iface->bind(call, iface, if_version);
1449         call->context = NULL;
1450         if (!NT_STATUS_IS_OK(status)) {
1451                 /* we don't want to trigger the iface->unbind() hook */
1452                 context->iface = NULL;
1453                 talloc_free(context);
1454                 /*
1455                  * We report this only via ack->result
1456                  */
1457                 return NT_STATUS_OK;
1458         }
1459
1460         ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1461         ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1462         ack->syntax = context->transfer_syntax;
1463         return NT_STATUS_OK;
1464 }
1465
1466 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1467                                 const struct dcerpc_bind *b,
1468                                 struct dcerpc_ack_ctx *ack_ctx_list)
1469 {
1470         NTSTATUS status;
1471         size_t i;
1472         bool validate_only = false;
1473         bool preferred_ndr32;
1474
1475         /*
1476          * Try to negotiate one new presentation context,
1477          * using our preferred transfer syntax.
1478          */
1479         for (i = 0; i < b->num_contexts; i++) {
1480                 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1481                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1482
1483                 status = dcesrv_check_or_create_context(call, b, c, a,
1484                                                 validate_only,
1485                                                 call->conn->preferred_transfer);
1486                 if (!NT_STATUS_IS_OK(status)) {
1487                         return status;
1488                 }
1489
1490                 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1491                         /*
1492                          * We managed to negotiate one context.
1493                          *
1494                          * => we're done.
1495                          */
1496                         validate_only = true;
1497                 }
1498         }
1499
1500         preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1501                                         call->conn->preferred_transfer);
1502         if (preferred_ndr32) {
1503                 /*
1504                  * We're done.
1505                  */
1506                 return NT_STATUS_OK;
1507         }
1508
1509         /*
1510          * Try to negotiate one new presentation context,
1511          * using NDR 32 as fallback.
1512          */
1513         for (i = 0; i < b->num_contexts; i++) {
1514                 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1515                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1516
1517                 status = dcesrv_check_or_create_context(call, b, c, a,
1518                                                 validate_only,
1519                                                 &ndr_transfer_syntax_ndr);
1520                 if (!NT_STATUS_IS_OK(status)) {
1521                         return status;
1522                 }
1523
1524                 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1525                         /*
1526                          * We managed to negotiate one context.
1527                          *
1528                          * => we're done.
1529                          */
1530                         validate_only = true;
1531                 }
1532         }
1533
1534         return NT_STATUS_OK;
1535 }
1536
1537 static void dcesrv_alter_done(struct tevent_req *subreq);
1538
1539 /*
1540   handle a alter context request
1541 */
1542 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1543 {
1544         struct dcesrv_connection *conn = call->conn;
1545         NTSTATUS status;
1546         bool auth_ok = false;
1547         struct ncacn_packet *pkt = &call->ack_pkt;
1548         uint32_t extra_flags = 0;
1549         struct dcesrv_auth *auth = &call->conn->auth_state;
1550         struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1551         struct tevent_req *subreq = NULL;
1552         size_t i;
1553
1554         if (!call->conn->allow_alter) {
1555                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1556         }
1557
1558         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1559                         DCERPC_PKT_ALTER,
1560                         call->pkt.u.alter.auth_info.length,
1561                         0, /* required flags */
1562                         DCERPC_PFC_FLAG_FIRST |
1563                         DCERPC_PFC_FLAG_LAST |
1564                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1565                         0x08 | /* this is not defined, but should be ignored */
1566                         DCERPC_PFC_FLAG_CONC_MPX |
1567                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1568                         DCERPC_PFC_FLAG_MAYBE |
1569                         DCERPC_PFC_FLAG_OBJECT_UUID);
1570         if (!NT_STATUS_IS_OK(status)) {
1571                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1572         }
1573
1574         auth_ok = dcesrv_auth_alter(call);
1575         if (!auth_ok) {
1576                 if (call->fault_code != 0) {
1577                         return dcesrv_fault_disconnect(call, call->fault_code);
1578                 }
1579         }
1580
1581         if (call->pkt.u.alter.num_contexts < 1) {
1582                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1583         }
1584
1585         ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1586                                          call->pkt.u.alter.num_contexts);
1587         if (ack_ctx_list == NULL) {
1588                 return NT_STATUS_NO_MEMORY;
1589         }
1590
1591         /*
1592          * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1593          * dcesrv_check_or_create_context()) and do some protocol validation
1594          * and set sane defaults.
1595          */
1596         for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1597                 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1598                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1599
1600                 if (c->num_transfer_syntaxes == 0) {
1601                         return dcesrv_fault_disconnect(call,
1602                                         DCERPC_NCA_S_PROTO_ERROR);
1603                 }
1604
1605                 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1606                 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1607         }
1608
1609         /*
1610          * Try to negotiate one new presentation context.
1611          */
1612         status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1613         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1614                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1615         }
1616         if (!NT_STATUS_IS_OK(status)) {
1617                 return status;
1618         }
1619
1620         if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1621             (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1622                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1623                 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1624         }
1625
1626         if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1627                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1628         }
1629
1630         /* handle any authentication that is being requested */
1631         if (!auth_ok) {
1632                 if (call->in_auth_info.auth_type !=
1633                     call->conn->auth_state.auth_type)
1634                 {
1635                         return dcesrv_fault_disconnect(call,
1636                                         DCERPC_FAULT_SEC_PKG_ERROR);
1637                 }
1638                 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1639         }
1640
1641         dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1642         pkt->auth_length = 0;
1643         pkt->call_id = call->pkt.call_id;
1644         pkt->ptype = DCERPC_PKT_ALTER_RESP;
1645         pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1646         pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1647         pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1648         pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1649         pkt->u.alter_resp.secondary_address = "";
1650         pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1651         pkt->u.alter_resp.ctx_list = ack_ctx_list;
1652         pkt->u.alter_resp.auth_info = data_blob_null;
1653
1654         status = dcesrv_auth_prepare_alter_ack(call, pkt);
1655         if (!NT_STATUS_IS_OK(status)) {
1656                 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1657         }
1658
1659         if (auth->auth_finished) {
1660                 return dcesrv_auth_reply(call);
1661         }
1662
1663         subreq = gensec_update_send(call, call->event_ctx,
1664                                     auth->gensec_security,
1665                                     call->in_auth_info.credentials);
1666         if (subreq == NULL) {
1667                 return NT_STATUS_NO_MEMORY;
1668         }
1669         tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1670
1671         return dcesrv_conn_auth_wait_setup(conn);
1672 }
1673
1674 static void dcesrv_alter_done(struct tevent_req *subreq)
1675 {
1676         struct dcesrv_call_state *call =
1677                 tevent_req_callback_data(subreq,
1678                 struct dcesrv_call_state);
1679         struct dcesrv_connection *conn = call->conn;
1680         NTSTATUS status;
1681
1682         status = gensec_update_recv(subreq, call,
1683                                     &call->out_auth_info->credentials);
1684         TALLOC_FREE(subreq);
1685
1686         status = dcesrv_auth_complete(call, status);
1687         if (!NT_STATUS_IS_OK(status)) {
1688                 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1689                 dcesrv_conn_auth_wait_finished(conn, status);
1690                 return;
1691         }
1692
1693         status = dcesrv_auth_reply(call);
1694         dcesrv_conn_auth_wait_finished(conn, status);
1695         return;
1696 }
1697
1698 /*
1699   possibly save the call for inspection with ndrdump
1700  */
1701 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1702 {
1703 #ifdef DEVELOPER
1704         char *fname;
1705         const char *dump_dir;
1706         dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1707         if (!dump_dir) {
1708                 return;
1709         }
1710         fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1711                                 dump_dir,
1712                                 call->context->iface->name,
1713                                 call->pkt.u.request.opnum,
1714                                 why);
1715         if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1716                 DEBUG(0,("RPC SAVED %s\n", fname));
1717         }
1718         talloc_free(fname);
1719 #endif
1720 }
1721
1722 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1723 {
1724         TALLOC_CTX *frame = talloc_stackframe();
1725         const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1726                 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1727         const struct dcerpc_sec_vt_pcontext pcontext = {
1728                 .abstract_syntax = call->context->iface->syntax_id,
1729                 .transfer_syntax = call->context->transfer_syntax,
1730         };
1731         const struct dcerpc_sec_vt_header2 header2 =
1732                 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1733         enum ndr_err_code ndr_err;
1734         struct dcerpc_sec_verification_trailer *vt = NULL;
1735         NTSTATUS status = NT_STATUS_OK;
1736         bool ok;
1737
1738         SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1739
1740         ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1741                                                           frame, &vt);
1742         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1743                 status = ndr_map_error2ntstatus(ndr_err);
1744                 goto done;
1745         }
1746
1747         ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1748                                                    &pcontext, &header2);
1749         if (!ok) {
1750                 status = NT_STATUS_ACCESS_DENIED;
1751                 goto done;
1752         }
1753 done:
1754         TALLOC_FREE(frame);
1755         return status;
1756 }
1757
1758 /*
1759   handle a dcerpc request packet
1760 */
1761 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1762 {
1763         const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1764         enum dcerpc_transport_t transport =
1765                 dcerpc_binding_get_transport(endpoint->ep_description);
1766         struct ndr_pull *pull;
1767         NTSTATUS status;
1768
1769         if (!call->conn->allow_request) {
1770                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1771         }
1772
1773         /* if authenticated, and the mech we use can't do async replies, don't use them... */
1774         if (call->conn->auth_state.gensec_security && 
1775             !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1776                 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1777         }
1778
1779         if (call->context == NULL) {
1780                 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1781                                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1782         }
1783
1784         switch (call->conn->auth_state.auth_level) {
1785         case DCERPC_AUTH_LEVEL_NONE:
1786         case DCERPC_AUTH_LEVEL_PACKET:
1787         case DCERPC_AUTH_LEVEL_INTEGRITY:
1788         case DCERPC_AUTH_LEVEL_PRIVACY:
1789                 break;
1790         default:
1791                 if (!call->context->allow_connect) {
1792                         char *addr;
1793
1794                         addr = tsocket_address_string(call->conn->remote_address,
1795                                                       call);
1796
1797                         DEBUG(2, ("%s: restrict auth_level_connect access "
1798                                   "to [%s] with auth[type=0x%x,level=0x%x] "
1799                                   "on [%s] from [%s]\n",
1800                                   __func__, call->context->iface->name,
1801                                   call->conn->auth_state.auth_type,
1802                                   call->conn->auth_state.auth_level,
1803                                   derpc_transport_string_by_transport(transport),
1804                                   addr));
1805                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1806                 }
1807                 break;
1808         }
1809
1810         if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1811                 char *addr;
1812
1813                 addr = tsocket_address_string(call->conn->remote_address, call);
1814
1815                 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1816                           "to [%s] with auth[type=0x%x,level=0x%x] "
1817                           "on [%s] from [%s]\n",
1818                           __func__,
1819                           call->context->min_auth_level,
1820                           call->context->iface->name,
1821                           call->conn->auth_state.auth_type,
1822                           call->conn->auth_state.auth_level,
1823                           derpc_transport_string_by_transport(transport),
1824                           addr));
1825                 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1826         }
1827
1828         pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1829         NT_STATUS_HAVE_NO_MEMORY(pull);
1830
1831         pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1832
1833         call->ndr_pull  = pull;
1834
1835         if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1836                 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1837         }
1838
1839         status = dcesrv_check_verification_trailer(call);
1840         if (!NT_STATUS_IS_OK(status)) {
1841                 uint32_t faultcode = DCERPC_FAULT_OTHER;
1842                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1843                         faultcode = DCERPC_FAULT_ACCESS_DENIED;
1844                 }
1845                 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1846                            nt_errstr(status)));
1847                 return dcesrv_fault(call, faultcode);
1848         }
1849
1850         /* unravel the NDR for the packet */
1851         status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1852         if (!NT_STATUS_IS_OK(status)) {
1853                 uint8_t extra_flags = 0;
1854                 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1855                         /* we got an unknown call */
1856                         DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1857                                  call->pkt.u.request.opnum,
1858                                  call->context->iface->name));
1859                         dcesrv_save_call(call, "unknown");
1860                         extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1861                 } else {
1862                         dcesrv_save_call(call, "pullfail");
1863                 }
1864                 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1865         }
1866
1867         if (pull->offset != pull->data_size) {
1868                 dcesrv_save_call(call, "extrabytes");
1869                 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n", 
1870                          pull->data_size - pull->offset));
1871         }
1872
1873         /* call the dispatch function */
1874         status = call->context->iface->dispatch(call, call, call->r);
1875         if (!NT_STATUS_IS_OK(status)) {
1876                 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1877                          call->context->iface->name,
1878                          call->pkt.u.request.opnum,
1879                          dcerpc_errstr(pull, call->fault_code)));
1880                 return dcesrv_fault(call, call->fault_code);
1881         }
1882
1883         /* add the call to the pending list */
1884         dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1885
1886         if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1887                 return NT_STATUS_OK;
1888         }
1889
1890         return dcesrv_reply(call);
1891 }
1892
1893
1894 /*
1895   remove the call from the right list when freed
1896  */
1897 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1898 {
1899         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1900         return 0;
1901 }
1902
1903 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1904 {
1905         return conn->local_address;
1906 }
1907
1908 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1909 {
1910         return conn->remote_address;
1911 }
1912
1913 /*
1914   process some input to a dcerpc endpoint server.
1915 */
1916 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1917                                             struct ncacn_packet *pkt,
1918                                             DATA_BLOB blob)
1919 {
1920         NTSTATUS status;
1921         struct dcesrv_call_state *call;
1922         struct dcesrv_call_state *existing = NULL;
1923
1924         call = talloc_zero(dce_conn, struct dcesrv_call_state);
1925         if (!call) {
1926                 data_blob_free(&blob);
1927                 talloc_free(pkt);
1928                 return NT_STATUS_NO_MEMORY;
1929         }
1930         call->conn              = dce_conn;
1931         call->event_ctx         = dce_conn->event_ctx;
1932         call->msg_ctx           = dce_conn->msg_ctx;
1933         call->state_flags       = call->conn->state_flags;
1934         call->time              = timeval_current();
1935         call->list              = DCESRV_LIST_NONE;
1936
1937         talloc_steal(call, pkt);
1938         talloc_steal(call, blob.data);
1939         call->pkt = *pkt;
1940
1941         talloc_set_destructor(call, dcesrv_call_dequeue);
1942
1943         if (call->conn->allow_bind) {
1944                 /*
1945                  * Only one bind is possible per connection
1946                  */
1947                 call->conn->allow_bind = false;
1948                 return dcesrv_bind(call);
1949         }
1950
1951         /* we have to check the signing here, before combining the
1952            pdus */
1953         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1954                 if (!call->conn->allow_request) {
1955                         return dcesrv_fault_disconnect(call,
1956                                         DCERPC_NCA_S_PROTO_ERROR);
1957                 }
1958
1959                 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1960                                 DCERPC_PKT_REQUEST,
1961                                 call->pkt.u.request.stub_and_verifier.length,
1962                                 0, /* required_flags */
1963                                 DCERPC_PFC_FLAG_FIRST |
1964                                 DCERPC_PFC_FLAG_LAST |
1965                                 DCERPC_PFC_FLAG_PENDING_CANCEL |
1966                                 0x08 | /* this is not defined, but should be ignored */
1967                                 DCERPC_PFC_FLAG_CONC_MPX |
1968                                 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1969                                 DCERPC_PFC_FLAG_MAYBE |
1970                                 DCERPC_PFC_FLAG_OBJECT_UUID);
1971                 if (!NT_STATUS_IS_OK(status)) {
1972                         return dcesrv_fault_disconnect(call,
1973                                         DCERPC_NCA_S_PROTO_ERROR);
1974                 }
1975
1976                 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1977                         /*
1978                          * We don't use dcesrv_fault_disconnect()
1979                          * here, because we don't want to set
1980                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1981                          *
1982                          * Note that we don't check against the negotiated
1983                          * max_recv_frag, but a hard coded value.
1984                          */
1985                         dcesrv_call_disconnect_after(call,
1986                                 "dcesrv_auth_request - frag_length too large");
1987                         return dcesrv_fault(call,
1988                                         DCERPC_NCA_S_PROTO_ERROR);
1989                 }
1990
1991                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1992                         if (dce_conn->pending_call_list != NULL) {
1993                                 /*
1994                                  * concurrent requests are only allowed
1995                                  * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1996                                  */
1997                                 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1998                                         dcesrv_call_disconnect_after(call,
1999                                                 "dcesrv_auth_request - "
2000                                                 "existing pending call without CONN_MPX");
2001                                         return dcesrv_fault(call,
2002                                                 DCERPC_NCA_S_PROTO_ERROR);
2003                                 }
2004                         }
2005                         /* only one request is possible in the fragmented list */
2006                         if (dce_conn->incoming_fragmented_call_list != NULL) {
2007                                 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2008                                         /*
2009                                          * Without DCERPC_PFC_FLAG_CONC_MPX
2010                                          * we need to return the FAULT on the
2011                                          * already existing call.
2012                                          *
2013                                          * This is important to get the
2014                                          * call_id and context_id right.
2015                                          */
2016                                         TALLOC_FREE(call);
2017                                         call = dce_conn->incoming_fragmented_call_list;
2018                                 }
2019                                 dcesrv_call_disconnect_after(call,
2020                                         "dcesrv_auth_request - "
2021                                         "existing fragmented call");
2022                                 return dcesrv_fault(call,
2023                                                 DCERPC_NCA_S_PROTO_ERROR);
2024                         }
2025                         if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2026                                 return dcesrv_fault_disconnect(call,
2027                                                 DCERPC_FAULT_NO_CALL_ACTIVE);
2028                         }
2029                         call->context = dcesrv_find_context(call->conn,
2030                                                 call->pkt.u.request.context_id);
2031                         if (call->context == NULL) {
2032                                 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2033                                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2034                         }
2035                 } else {
2036                         const struct dcerpc_request *nr = &call->pkt.u.request;
2037                         const struct dcerpc_request *er = NULL;
2038                         int cmp;
2039
2040                         existing = dcesrv_find_fragmented_call(dce_conn,
2041                                                         call->pkt.call_id);
2042                         if (existing == NULL) {
2043                                 dcesrv_call_disconnect_after(call,
2044                                         "dcesrv_auth_request - "
2045                                         "no existing fragmented call");
2046                                 return dcesrv_fault(call,
2047                                                 DCERPC_NCA_S_PROTO_ERROR);
2048                         }
2049                         er = &existing->pkt.u.request;
2050
2051                         if (call->pkt.ptype != existing->pkt.ptype) {
2052                                 /* trying to play silly buggers are we? */
2053                                 return dcesrv_fault_disconnect(existing,
2054                                                 DCERPC_NCA_S_PROTO_ERROR);
2055                         }
2056                         cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2057                                      sizeof(pkt->drep));
2058                         if (cmp != 0) {
2059                                 return dcesrv_fault_disconnect(existing,
2060                                                 DCERPC_NCA_S_PROTO_ERROR);
2061                         }
2062                         if (nr->context_id != er->context_id)  {
2063                                 return dcesrv_fault_disconnect(existing,
2064                                                 DCERPC_NCA_S_PROTO_ERROR);
2065                         }
2066                         if (nr->opnum != er->opnum)  {
2067                                 return dcesrv_fault_disconnect(existing,
2068                                                 DCERPC_NCA_S_PROTO_ERROR);
2069                         }
2070                 }
2071         }
2072
2073         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2074                 bool ok;
2075                 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2076
2077                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2078                         payload_offset += 16;
2079                 }
2080
2081                 ok = dcesrv_auth_pkt_pull(call, &blob,
2082                                           0, /* required_flags */
2083                                           DCERPC_PFC_FLAG_FIRST |
2084                                           DCERPC_PFC_FLAG_LAST |
2085                                           DCERPC_PFC_FLAG_PENDING_CANCEL |
2086                                           0x08 | /* this is not defined, but should be ignored */
2087                                           DCERPC_PFC_FLAG_CONC_MPX |
2088                                           DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2089                                           DCERPC_PFC_FLAG_MAYBE |
2090                                           DCERPC_PFC_FLAG_OBJECT_UUID,
2091                                           payload_offset,
2092                                           &call->pkt.u.request.stub_and_verifier);
2093                 if (!ok) {
2094                         /*
2095                          * We don't use dcesrv_fault_disconnect()
2096                          * here, because we don't want to set
2097                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2098                          */
2099                         dcesrv_call_disconnect_after(call,
2100                                                 "dcesrv_auth_request - failed");
2101                         if (call->fault_code == 0) {
2102                                 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2103                         }
2104                         return dcesrv_fault(call, call->fault_code);
2105                 }
2106         }
2107
2108         /* see if this is a continued packet */
2109         if (existing != NULL) {
2110                 struct dcerpc_request *er = &existing->pkt.u.request;
2111                 const struct dcerpc_request *nr = &call->pkt.u.request;
2112                 size_t available;
2113                 size_t alloc_size;
2114                 size_t alloc_hint;
2115
2116                 /*
2117                  * Up to 4 MByte are allowed by all fragments
2118                  */
2119                 available = dce_conn->max_total_request_size;
2120                 if (er->stub_and_verifier.length > available) {
2121                         dcesrv_call_disconnect_after(existing,
2122                                 "dcesrv_auth_request - existing payload too large");
2123                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2124                 }
2125                 available -= er->stub_and_verifier.length;
2126                 if (nr->alloc_hint > available) {
2127                         dcesrv_call_disconnect_after(existing,
2128                                 "dcesrv_auth_request - alloc hint too large");
2129                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2130                 }
2131                 if (nr->stub_and_verifier.length > available) {
2132                         dcesrv_call_disconnect_after(existing,
2133                                 "dcesrv_auth_request - new payload too large");
2134                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2135                 }
2136                 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2137                 /* allocate at least 1 byte */
2138                 alloc_hint = MAX(alloc_hint, 1);
2139                 alloc_size = er->stub_and_verifier.length +
2140                              nr->stub_and_verifier.length;
2141                 alloc_size = MAX(alloc_size, alloc_hint);
2142
2143                 er->stub_and_verifier.data =
2144                         talloc_realloc(existing,
2145                                        er->stub_and_verifier.data,
2146                                        uint8_t, alloc_size);
2147                 if (er->stub_and_verifier.data == NULL) {
2148                         TALLOC_FREE(call);
2149                         return dcesrv_fault_with_flags(existing,
2150                                                        DCERPC_FAULT_OUT_OF_RESOURCES,
2151                                                        DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2152                 }
2153                 memcpy(er->stub_and_verifier.data +
2154                        er->stub_and_verifier.length,
2155                        nr->stub_and_verifier.data,
2156                        nr->stub_and_verifier.length);
2157                 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2158
2159                 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2160
2161                 TALLOC_FREE(call);
2162                 call = existing;
2163         }
2164
2165         /* this may not be the last pdu in the chain - if its isn't then
2166            just put it on the incoming_fragmented_call_list and wait for the rest */
2167         if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2168             !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2169                 /*
2170                  * Up to 4 MByte are allowed by all fragments
2171                  */
2172                 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2173                         dcesrv_call_disconnect_after(call,
2174                                 "dcesrv_auth_request - initial alloc hint too large");
2175                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2176                 }
2177                 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2178                 return NT_STATUS_OK;
2179         } 
2180         
2181         /* This removes any fragments we may have had stashed away */
2182         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2183
2184         switch (call->pkt.ptype) {
2185         case DCERPC_PKT_BIND:
2186                 status = dcesrv_bind_nak(call,
2187                         DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2188                 break;
2189         case DCERPC_PKT_AUTH3:
2190                 status = dcesrv_auth3(call);
2191                 break;
2192         case DCERPC_PKT_ALTER:
2193                 status = dcesrv_alter(call);
2194                 break;
2195         case DCERPC_PKT_REQUEST:
2196                 status = dcesrv_request(call);
2197                 break;
2198         case DCERPC_PKT_CO_CANCEL:
2199         case DCERPC_PKT_ORPHANED:
2200                 /*
2201                  * Window just ignores CO_CANCEL and ORPHANED,
2202                  * so we do...
2203                  */
2204                 status = NT_STATUS_OK;
2205                 TALLOC_FREE(call);
2206                 break;
2207         case DCERPC_PKT_BIND_ACK:
2208         case DCERPC_PKT_BIND_NAK:
2209         case DCERPC_PKT_ALTER_RESP:
2210         case DCERPC_PKT_RESPONSE:
2211         case DCERPC_PKT_FAULT:
2212         case DCERPC_PKT_SHUTDOWN:
2213         default:
2214                 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2215                 break;
2216         }
2217
2218         /* if we are going to be sending a reply then add
2219            it to the list of pending calls. We add it to the end to keep the call
2220            list in the order we will answer */
2221         if (!NT_STATUS_IS_OK(status)) {
2222                 talloc_free(call);
2223         }
2224
2225         return status;
2226 }
2227
2228 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, 
2229                                       struct loadparm_context *lp_ctx,
2230                                       const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2231 {
2232         NTSTATUS status;
2233         struct dcesrv_context *dce_ctx;
2234         int i;
2235
2236         if (!endpoint_servers) {
2237                 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2238                 return NT_STATUS_INTERNAL_ERROR;
2239         }
2240
2241         dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2242         NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2243
2244         if (uid_wrapper_enabled()) {
2245                 setenv("UID_WRAPPER_MYUID", "1", 1);
2246         }
2247         dce_ctx->initial_euid = geteuid();
2248         if (uid_wrapper_enabled()) {
2249                 unsetenv("UID_WRAPPER_MYUID");
2250         }
2251
2252         dce_ctx->endpoint_list  = NULL;
2253         dce_ctx->lp_ctx = lp_ctx;
2254         dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2255         NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2256         dce_ctx->broken_connections = NULL;
2257
2258         for (i=0;endpoint_servers[i];i++) {
2259                 const struct dcesrv_endpoint_server *ep_server;
2260
2261                 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2262                 if (!ep_server) {
2263                         DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2264                         return NT_STATUS_INTERNAL_ERROR;
2265                 }
2266
2267                 status = ep_server->init_server(dce_ctx, ep_server);
2268                 if (!NT_STATUS_IS_OK(status)) {
2269                         DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2270                                 nt_errstr(status)));
2271                         return status;
2272                 }
2273         }
2274
2275         *_dce_ctx = dce_ctx;
2276         return NT_STATUS_OK;
2277 }
2278
2279 /* the list of currently registered DCERPC endpoint servers.
2280  */
2281 static struct ep_server {
2282         struct dcesrv_endpoint_server *ep_server;
2283 } *ep_servers = NULL;
2284 static int num_ep_servers;
2285
2286 /*
2287   register a DCERPC endpoint server. 
2288
2289   The 'name' can be later used by other backends to find the operations
2290   structure for this backend.  
2291
2292 */
2293 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2294 {
2295         
2296         if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2297                 /* its already registered! */
2298                 DEBUG(0,("DCERPC endpoint server '%s' already registered\n", 
2299                          ep_server->name));
2300                 return NT_STATUS_OBJECT_NAME_COLLISION;
2301         }
2302
2303         ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2304         if (!ep_servers) {
2305                 smb_panic("out of memory in dcerpc_register");
2306         }
2307
2308         ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2309         ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2310
2311         num_ep_servers++;
2312
2313         DEBUG(3,("DCERPC endpoint server '%s' registered\n", 
2314                  ep_server->name));
2315
2316         return NT_STATUS_OK;
2317 }
2318
2319 /*
2320   return the operations structure for a named backend of the specified type
2321 */
2322 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2323 {
2324         int i;
2325
2326         for (i=0;i<num_ep_servers;i++) {
2327                 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2328                         return ep_servers[i].ep_server;
2329                 }
2330         }
2331
2332         return NULL;
2333 }
2334
2335 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2336 {
2337         static bool initialized;
2338 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2339         STATIC_dcerpc_server_MODULES_PROTO;
2340         init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2341         init_module_fn *shared_init;
2342
2343         if (initialized) {
2344                 return;
2345         }
2346         initialized = true;
2347
2348         shared_init = load_samba_modules(NULL, "dcerpc_server");
2349
2350         run_init_functions(NULL, static_init);
2351         run_init_functions(NULL, shared_init);
2352
2353         talloc_free(shared_init);
2354 }
2355
2356 /*
2357   return the DCERPC module version, and the size of some critical types
2358   This can be used by endpoint server modules to either detect compilation errors, or provide
2359   multiple implementations for different smbd compilation options in one module
2360 */
2361 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2362 {
2363         static const struct dcesrv_critical_sizes critical_sizes = {
2364                 DCERPC_MODULE_VERSION,
2365                 sizeof(struct dcesrv_context),
2366                 sizeof(struct dcesrv_endpoint),
2367                 sizeof(struct dcesrv_endpoint_server),
2368                 sizeof(struct dcesrv_interface),
2369                 sizeof(struct dcesrv_if_list),
2370                 sizeof(struct dcesrv_connection),
2371                 sizeof(struct dcesrv_call_state),
2372                 sizeof(struct dcesrv_auth),
2373                 sizeof(struct dcesrv_handle)
2374         };
2375
2376         return &critical_sizes;
2377 }
2378
2379 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2380 {
2381         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2382         struct stream_connection *srv_conn;
2383         srv_conn = talloc_get_type(dce_conn->transport.private_data,
2384                                    struct stream_connection);
2385
2386         dce_conn->wait_send = NULL;
2387         dce_conn->wait_recv = NULL;
2388         dce_conn->wait_private = NULL;
2389
2390         dce_conn->allow_bind = false;
2391         dce_conn->allow_auth3 = false;
2392         dce_conn->allow_alter = false;
2393         dce_conn->allow_request = false;
2394
2395         if (dce_conn->pending_call_list == NULL) {
2396                 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2397
2398                 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2399                 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2400                 return;
2401         }
2402
2403         if (dce_conn->terminate != NULL) {
2404                 return;
2405         }
2406
2407         DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2408                  reason));
2409         dce_conn->terminate = talloc_strdup(dce_conn, reason);
2410         if (dce_conn->terminate == NULL) {
2411                 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2412         }
2413         DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2414 }
2415
2416 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2417 {
2418         struct dcesrv_connection *cur, *next;
2419
2420         next = dce_ctx->broken_connections;
2421         while (next != NULL) {
2422                 cur = next;
2423                 next = cur->next;
2424
2425                 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2426                         struct dcesrv_connection_context *context_cur, *context_next;
2427
2428                         context_next = cur->contexts;
2429                         while (context_next != NULL) {
2430                                 context_cur = context_next;
2431                                 context_next = context_cur->next;
2432
2433                                 dcesrv_connection_context_destructor(context_cur);
2434                         }
2435                 }
2436
2437                 dcesrv_terminate_connection(cur, cur->terminate);
2438         }
2439 }
2440
2441 /* We need this include to be able to compile on some plateforms
2442  * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2443  * correctly.
2444  * It has to be that deep because otherwise we have a conflict on
2445  * const struct dcesrv_interface declaration.
2446  * This is mostly due to socket_wrapper defining #define bind swrap_bind
2447  * which conflict with the bind used before.
2448  */
2449 #include "system/network.h"
2450
2451 struct dcesrv_sock_reply_state {
2452         struct dcesrv_connection *dce_conn;
2453         struct dcesrv_call_state *call;
2454         struct iovec iov;
2455 };
2456
2457 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2458 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2459
2460 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2461 {
2462         struct dcesrv_call_state *call;
2463
2464         call = dce_conn->call_list;
2465         if (!call || !call->replies) {
2466                 return;
2467         }
2468
2469         while (call->replies) {
2470                 struct data_blob_list_item *rep = call->replies;
2471                 struct dcesrv_sock_reply_state *substate;
2472                 struct tevent_req *subreq;
2473
2474                 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2475                 if (!substate) {
2476                         dcesrv_terminate_connection(dce_conn, "no memory");
2477                         return;
2478                 }
2479
2480                 substate->dce_conn = dce_conn;
2481                 substate->call = NULL;
2482
2483                 DLIST_REMOVE(call->replies, rep);
2484
2485                 if (call->replies == NULL && call->terminate_reason == NULL) {
2486                         substate->call = call;
2487                 }
2488
2489                 substate->iov.iov_base = (void *) rep->blob.data;
2490                 substate->iov.iov_len = rep->blob.length;
2491
2492                 subreq = tstream_writev_queue_send(substate,
2493                                                    dce_conn->event_ctx,
2494                                                    dce_conn->stream,
2495                                                    dce_conn->send_queue,
2496                                                    &substate->iov, 1);
2497                 if (!subreq) {
2498                         dcesrv_terminate_connection(dce_conn, "no memory");
2499                         return;
2500                 }
2501                 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2502                                         substate);
2503         }
2504
2505         if (call->terminate_reason != NULL) {
2506                 struct tevent_req *subreq;
2507
2508                 subreq = tevent_queue_wait_send(call,
2509                                                 dce_conn->event_ctx,
2510                                                 dce_conn->send_queue);
2511                 if (!subreq) {
2512                         dcesrv_terminate_connection(dce_conn, __location__);
2513                         return;
2514                 }
2515                 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2516                                         call);
2517         }
2518
2519         DLIST_REMOVE(call->conn->call_list, call);
2520         call->list = DCESRV_LIST_NONE;
2521 }
2522
2523 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2524 {
2525         struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2526                                                 struct dcesrv_sock_reply_state);
2527         int ret;
2528         int sys_errno;
2529         NTSTATUS status;
2530         struct dcesrv_call_state *call = substate->call;
2531
2532         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2533         TALLOC_FREE(subreq);
2534         if (ret == -1) {
2535                 status = map_nt_error_from_unix_common(sys_errno);
2536                 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2537                 return;
2538         }
2539
2540         talloc_free(substate);
2541         if (call) {
2542                 talloc_free(call);
2543         }
2544 }
2545
2546 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2547
2548 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2549 {
2550         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2551                                                 struct dcesrv_call_state);
2552         bool ok;
2553         struct timeval tv;
2554
2555         /* make sure we stop send queue before removing subreq */
2556         tevent_queue_stop(call->conn->send_queue);
2557
2558         ok = tevent_queue_wait_recv(subreq);
2559         TALLOC_FREE(subreq);
2560         if (!ok) {
2561                 dcesrv_terminate_connection(call->conn, __location__);
2562                 return;
2563         }
2564
2565         /* disconnect after 200 usecs */
2566         tv = timeval_current_ofs_usec(200);
2567         subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2568         if (subreq == NULL) {
2569                 dcesrv_terminate_connection(call->conn, __location__);
2570                 return;
2571         }
2572         tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2573                                 call);
2574 }
2575
2576 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2577 {
2578         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2579                                                 struct dcesrv_call_state);
2580         bool ok;
2581
2582         ok = tevent_wakeup_recv(subreq);
2583         TALLOC_FREE(subreq);
2584         if (!ok) {
2585                 dcesrv_terminate_connection(call->conn, __location__);
2586                 return;
2587         }
2588
2589         dcesrv_terminate_connection(call->conn, call->terminate_reason);
2590 }
2591
2592 struct dcesrv_socket_context {
2593         const struct dcesrv_endpoint *endpoint;
2594         struct dcesrv_context *dcesrv_ctx;
2595 };
2596
2597
2598 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2599
2600 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2601 {
2602         NTSTATUS status;
2603         struct dcesrv_socket_context *dcesrv_sock = 
2604                 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2605         enum dcerpc_transport_t transport =
2606                 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2607         struct dcesrv_connection *dcesrv_conn = NULL;
2608         int ret;
2609         struct tevent_req *subreq;
2610         struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2611
2612         dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2613
2614         if (!srv_conn->session_info) {
2615                 status = auth_anonymous_session_info(srv_conn,
2616                                                      lp_ctx,
2617                                                      &srv_conn->session_info);
2618                 if (!NT_STATUS_IS_OK(status)) {
2619                         DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2620                                 nt_errstr(status)));
2621                         stream_terminate_connection(srv_conn, nt_errstr(status));
2622                         return;
2623                 }
2624         }
2625
2626         /*
2627          * This fills in dcesrv_conn->endpoint with the endpoint
2628          * associated with the socket.  From this point on we know
2629          * which (group of) services we are handling, but not the
2630          * specific interface.
2631          */
2632
2633         status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2634                                          srv_conn,
2635                                          dcesrv_sock->endpoint,
2636                                          srv_conn->session_info,
2637                                          srv_conn->event.ctx,
2638                                          srv_conn->msg_ctx,
2639                                          srv_conn->server_id,
2640                                          DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2641                                          &dcesrv_conn);
2642         if (!NT_STATUS_IS_OK(status)) {
2643                 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
2644                         nt_errstr(status)));
2645                 stream_terminate_connection(srv_conn, nt_errstr(status));
2646                 return;
2647         }
2648
2649         dcesrv_conn->transport.private_data             = srv_conn;
2650         dcesrv_conn->transport.report_output_data       = dcesrv_sock_report_output_data;
2651
2652         TALLOC_FREE(srv_conn->event.fde);
2653
2654         dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2655         if (!dcesrv_conn->send_queue) {
2656                 status = NT_STATUS_NO_MEMORY;
2657                 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2658                         nt_errstr(status)));
2659                 stream_terminate_connection(srv_conn, nt_errstr(status));
2660                 return;
2661         }
2662
2663         if (transport == NCACN_NP) {
2664                 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2665                 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2666                                                   &srv_conn->tstream);
2667         } else {
2668                 ret = tstream_bsd_existing_socket(dcesrv_conn,
2669                                                   socket_get_fd(srv_conn->socket),
2670                                                   &dcesrv_conn->stream);
2671                 if (ret == -1) {
2672                         status = map_nt_error_from_unix_common(errno);
2673                         DEBUG(0, ("dcesrv_sock_accept: "
2674                                   "failed to setup tstream: %s\n",
2675                                   nt_errstr(status)));
2676                         stream_terminate_connection(srv_conn, nt_errstr(status));
2677                         return;
2678                 }
2679                 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2680         }
2681
2682         dcesrv_conn->local_address = srv_conn->local_address;
2683         dcesrv_conn->remote_address = srv_conn->remote_address;
2684
2685         if (transport == NCALRPC) {
2686                 uid_t uid;
2687                 gid_t gid;
2688                 int sock_fd;
2689
2690                 sock_fd = socket_get_fd(srv_conn->socket);
2691                 if (sock_fd == -1) {
2692                         stream_terminate_connection(
2693                                 srv_conn, "socket_get_fd failed\n");
2694                         return;
2695                 }
2696
2697                 ret = getpeereid(sock_fd, &uid, &gid);
2698                 if (ret == -1) {
2699                         status = map_nt_error_from_unix_common(errno);
2700                         DEBUG(0, ("dcesrv_sock_accept: "
2701                                   "getpeereid() failed for NCALRPC: %s\n",
2702                                   nt_errstr(status)));
2703                         stream_terminate_connection(srv_conn, nt_errstr(status));
2704                         return;
2705                 }
2706                 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2707                         struct tsocket_address *r = NULL;
2708
2709                         ret = tsocket_address_unix_from_path(dcesrv_conn,
2710                                                              AS_SYSTEM_MAGIC_PATH_TOKEN,
2711                                                              &r);
2712                         if (ret == -1) {
2713                                 status = map_nt_error_from_unix_common(errno);
2714                                 DEBUG(0, ("dcesrv_sock_accept: "
2715                                           "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2716                                           nt_errstr(status)));
2717                                 stream_terminate_connection(srv_conn, nt_errstr(status));
2718                                 return;
2719                         }
2720                         dcesrv_conn->remote_address = r;
2721                 }
2722         }
2723
2724         srv_conn->private_data = dcesrv_conn;
2725
2726         irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2727
2728         subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2729                                                dcesrv_conn->event_ctx,
2730                                                dcesrv_conn->stream);
2731         if (!subreq) {
2732                 status = NT_STATUS_NO_MEMORY;
2733                 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2734                         nt_errstr(status)));
2735                 stream_terminate_connection(srv_conn, nt_errstr(status));
2736                 return;
2737         }
2738         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2739
2740         return;
2741 }
2742
2743 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2744
2745 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2746 {
2747         struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2748                                              struct dcesrv_connection);
2749         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2750         struct ncacn_packet *pkt;
2751         DATA_BLOB buffer;
2752         NTSTATUS status;
2753
2754         if (dce_conn->terminate) {
2755                 /*
2756                  * if the current connection is broken
2757                  * we need to clean it up before any other connection
2758                  */
2759                 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2760                 dcesrv_cleanup_broken_connections(dce_ctx);
2761                 return;
2762         }
2763
2764         dcesrv_cleanup_broken_connections(dce_ctx);
2765
2766         status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2767                                                &pkt, &buffer);
2768         TALLOC_FREE(subreq);
2769         if (!NT_STATUS_IS_OK(status)) {
2770                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2771                 return;
2772         }
2773
2774         status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2775         if (!NT_STATUS_IS_OK(status)) {
2776                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2777                 return;
2778         }
2779
2780         /*
2781          * This is used to block the connection during
2782          * pending authentication.
2783          */
2784         if (dce_conn->wait_send != NULL) {
2785                 subreq = dce_conn->wait_send(dce_conn,
2786                                              dce_conn->event_ctx,
2787                                              dce_conn->wait_private);
2788                 if (!subreq) {
2789                         status = NT_STATUS_NO_MEMORY;
2790                         dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2791                         return;
2792                 }
2793                 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2794                 return;
2795         }
2796
2797         subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2798                                                dce_conn->event_ctx,
2799                                                dce_conn->stream);
2800         if (!subreq) {
2801                 status = NT_STATUS_NO_MEMORY;
2802                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2803                 return;
2804         }
2805         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2806 }
2807
2808 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2809 {
2810         struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2811                                              struct dcesrv_connection);
2812         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2813         NTSTATUS status;
2814
2815         if (dce_conn->terminate) {
2816                 /*
2817                  * if the current connection is broken
2818                  * we need to clean it up before any other connection
2819                  */
2820                 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2821                 dcesrv_cleanup_broken_connections(dce_ctx);
2822                 return;
2823         }
2824
2825         dcesrv_cleanup_broken_connections(dce_ctx);
2826
2827         status = dce_conn->wait_recv(subreq);
2828         dce_conn->wait_send = NULL;
2829         dce_conn->wait_recv = NULL;
2830         dce_conn->wait_private = NULL;
2831         TALLOC_FREE(subreq);
2832         if (!NT_STATUS_IS_OK(status)) {
2833                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2834                 return;
2835         }
2836
2837         subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2838                                                dce_conn->event_ctx,
2839                                                dce_conn->stream);
2840         if (!subreq) {
2841                 status = NT_STATUS_NO_MEMORY;
2842                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2843                 return;
2844         }
2845         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2846 }
2847
2848 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2849 {
2850         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2851                                              struct dcesrv_connection);
2852         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2853 }
2854
2855 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2856 {
2857         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2858                                              struct dcesrv_connection);
2859         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2860 }
2861
2862
2863 static const struct stream_server_ops dcesrv_stream_ops = {
2864         .name                   = "rpc",
2865         .accept_connection      = dcesrv_sock_accept,
2866         .recv_handler           = dcesrv_sock_recv,
2867         .send_handler           = dcesrv_sock_send,
2868 };
2869
2870 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 
2871                                    struct loadparm_context *lp_ctx,
2872                                    struct dcesrv_endpoint *e,
2873                                    struct tevent_context *event_ctx,
2874                                    const struct model_ops *model_ops,
2875                                    void *process_context)
2876 {
2877         struct dcesrv_socket_context *dcesrv_sock;
2878         uint16_t port = 1;
2879         NTSTATUS status;
2880         const char *endpoint;
2881
2882         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2883         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2884
2885         /* remember the endpoint of this socket */
2886         dcesrv_sock->endpoint           = e;
2887         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2888
2889         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2890
2891         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2892                                      model_ops, &dcesrv_stream_ops, 
2893                                      "unix", endpoint, &port,
2894                                      lpcfg_socket_options(lp_ctx),
2895                                      dcesrv_sock, process_context);
2896         if (!NT_STATUS_IS_OK(status)) {
2897                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2898                          endpoint, nt_errstr(status)));
2899         }
2900
2901         return status;
2902 }
2903
2904 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 
2905                                       struct loadparm_context *lp_ctx,
2906                                       struct dcesrv_endpoint *e,
2907                                       struct tevent_context *event_ctx,
2908                                       const struct model_ops *model_ops,
2909                                       void *process_context)
2910 {
2911         struct dcesrv_socket_context *dcesrv_sock;
2912         uint16_t port = 1;
2913         char *full_path;
2914         NTSTATUS status;
2915         const char *endpoint;
2916
2917         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2918
2919         if (endpoint == NULL) {
2920                 /*
2921                  * No identifier specified: use DEFAULT.
2922                  *
2923                  * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2924                  * no endpoint and let the epmapper worry about it.
2925                  */
2926                 endpoint = "DEFAULT";
2927                 status = dcerpc_binding_set_string_option(e->ep_description,
2928                                                           "endpoint",
2929                                                           endpoint);
2930                 if (!NT_STATUS_IS_OK(status)) {
2931                         DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2932                                   nt_errstr(status)));
2933                         return status;
2934                 }
2935         }
2936
2937         full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2938                                     endpoint);
2939
2940         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2941         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2942
2943         /* remember the endpoint of this socket */
2944         dcesrv_sock->endpoint           = e;
2945         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2946
2947         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2948                                      model_ops, &dcesrv_stream_ops, 
2949                                      "unix", full_path, &port, 
2950                                      lpcfg_socket_options(lp_ctx),
2951                                      dcesrv_sock, process_context);
2952         if (!NT_STATUS_IS_OK(status)) {
2953                 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2954                          endpoint, full_path, nt_errstr(status)));
2955         }
2956         return status;
2957 }
2958
2959 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2960                                  struct loadparm_context *lp_ctx,
2961                                  struct dcesrv_endpoint *e,
2962                                  struct tevent_context *event_ctx,
2963                                  const struct model_ops *model_ops,
2964                                  void *process_context)
2965 {
2966         struct dcesrv_socket_context *dcesrv_sock;
2967         NTSTATUS status;
2968         const char *endpoint;
2969
2970         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2971         if (endpoint == NULL) {
2972                 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2973                 return NT_STATUS_INVALID_PARAMETER;
2974         }
2975
2976         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2977         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2978
2979         /* remember the endpoint of this socket */
2980         dcesrv_sock->endpoint           = e;
2981         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2982
2983         status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2984                                           model_ops, &dcesrv_stream_ops,
2985                                           endpoint,
2986                                           dcesrv_sock, process_context);
2987         if (!NT_STATUS_IS_OK(status)) {
2988                 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2989                          endpoint, nt_errstr(status)));
2990                 return status;
2991         }
2992
2993         return NT_STATUS_OK;
2994 }
2995
2996 /*
2997   add a socket address to the list of events, one event per dcerpc endpoint
2998 */
2999 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3000                                          struct dcesrv_endpoint *e,
3001                                          struct tevent_context *event_ctx,
3002                                          const struct model_ops *model_ops,
3003                                          const char *address,
3004                                          void *process_context)
3005 {
3006         struct dcesrv_socket_context *dcesrv_sock;
3007         uint16_t port = 0;
3008         NTSTATUS status;
3009         const char *endpoint;
3010         char port_str[6];
3011
3012         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3013         if (endpoint != NULL) {
3014                 port = atoi(endpoint);
3015         }
3016
3017         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3018         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3019
3020         /* remember the endpoint of this socket */
3021         dcesrv_sock->endpoint           = e;
3022         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
3023
3024         status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3025                                      model_ops, &dcesrv_stream_ops, 
3026                                      "ip", address, &port,
3027                                      lpcfg_socket_options(dce_ctx->lp_ctx),
3028                                      dcesrv_sock, process_context);
3029         if (!NT_STATUS_IS_OK(status)) {
3030                 struct dcesrv_if_list *iface;
3031                 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3032                          address, port));
3033                 for (iface = e->interface_list; iface; iface = iface->next) {
3034                         DEBUGADD(0, ("%s ", iface->iface.name));
3035                 }
3036                 DEBUGADD(0, ("failed - %s",
3037                              nt_errstr(status)));
3038                 return status;
3039         }
3040
3041         snprintf(port_str, sizeof(port_str), "%u", port);
3042
3043         status = dcerpc_binding_set_string_option(e->ep_description,
3044                                                   "endpoint", port_str);
3045         if (!NT_STATUS_IS_OK(status)) {
3046                 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3047                          port_str, nt_errstr(status)));
3048                 return status;
3049         } else {
3050                 struct dcesrv_if_list *iface;
3051                 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3052                          address, port_str));
3053                 for (iface = e->interface_list; iface; iface = iface->next) {
3054                         DEBUGADD(4, ("%s ", iface->iface.name));
3055                 }
3056                 DEBUGADD(4, ("\n"));
3057         }
3058
3059         return NT_STATUS_OK;
3060 }
3061
3062 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3063
3064 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 
3065                                   struct loadparm_context *lp_ctx,
3066                                   struct dcesrv_endpoint *e,
3067                                   struct tevent_context *event_ctx,
3068                                   const struct model_ops *model_ops,
3069                                   void *process_context)
3070 {
3071         NTSTATUS status;
3072
3073         /* Add TCP/IP sockets */
3074         if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3075                 int num_interfaces;
3076                 int i;
3077                 struct interface *ifaces;
3078
3079                 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3080
3081                 num_interfaces = iface_list_count(ifaces);
3082                 for(i = 0; i < num_interfaces; i++) {
3083                         const char *address = iface_list_n_ip(ifaces, i);
3084                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3085                                                           model_ops, address,
3086                                                           process_context);
3087                         NT_STATUS_NOT_OK_RETURN(status);
3088                 }
3089         } else {
3090                 char **wcard;
3091                 size_t i;
3092                 size_t num_binds = 0;
3093                 wcard = iface_list_wildcard(dce_ctx);
3094                 NT_STATUS_HAVE_NO_MEMORY(wcard);
3095                 for (i=0; wcard[i]; i++) {
3096                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3097                                                           model_ops, wcard[i],
3098                                                           process_context);
3099                         if (NT_STATUS_IS_OK(status)) {
3100                                 num_binds++;
3101                         }
3102                 }
3103                 talloc_free(wcard);
3104                 if (num_binds == 0) {
3105                         return NT_STATUS_INVALID_PARAMETER_MIX;
3106                 }
3107         }
3108
3109         return NT_STATUS_OK;
3110 }
3111
3112 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3113                        struct loadparm_context *lp_ctx,
3114                        struct dcesrv_endpoint *e,
3115                        struct tevent_context *event_ctx,
3116                        const struct model_ops *model_ops,
3117                        void *process_context)
3118 {
3119         enum dcerpc_transport_t transport =
3120                 dcerpc_binding_get_transport(e->ep_description);
3121
3122         switch (transport) {
3123         case NCACN_UNIX_STREAM:
3124                 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3125                                           model_ops, process_context);
3126
3127         case NCALRPC:
3128                 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3129                                              model_ops, process_context);
3130
3131         case NCACN_IP_TCP:
3132                 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3133                                          model_ops, process_context);
3134
3135         case NCACN_NP:
3136                 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3137                                         model_ops, process_context);
3138
3139         default:
3140                 return NT_STATUS_NOT_SUPPORTED;
3141         }
3142 }
3143
3144
3145 /**
3146  * retrieve credentials from a dce_call
3147  */
3148 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3149 {
3150         return dce_call->conn->auth_state.session_info->credentials;
3151 }
3152
3153 /**
3154  * returns true if this is an authenticated call
3155  */
3156 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3157 {
3158         enum security_user_level level;
3159         level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
3160         return level >= SECURITY_USER;
3161 }
3162
3163 /**
3164  * retrieve account_name for a dce_call
3165  */
3166 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3167 {
3168         return dce_call->context->conn->auth_state.session_info->info->account_name;
3169 }