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