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