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