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