s4-netlogon: Push the netlogon server in the AD DC into multiple processes
[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;
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 know which interface (eg netlogon, lsa,
943          * drsuapi) the caller requested.  This is available on
944          * call->conntext->iface.
945          */
946
947         if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
948             (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
949                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
950                 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
951         }
952
953         if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
954                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
955         }
956
957         /*
958          * After finding the interface and setting up the NDR
959          * transport negotiation etc, handle any authentication that
960          * is being requested.
961          */
962         if (!dcesrv_auth_bind(call)) {
963                 struct dcesrv_auth *auth = &call->conn->auth_state;
964
965                 TALLOC_FREE(call->context);
966
967                 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
968                         /*
969                          * With DCERPC_AUTH_LEVEL_NONE, we get the
970                          * reject_reason in auth->auth_context_id.
971                          */
972                         return dcesrv_bind_nak(call, auth->auth_context_id);
973                 }
974
975                 /*
976                  * This must a be a temporary failure e.g. talloc or invalid
977                  * configuration, e.g. no machine account.
978                  */
979                 return dcesrv_bind_nak(call,
980                                 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
981         }
982
983         /* setup a bind_ack */
984         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
985         pkt.auth_length = 0;
986         pkt.call_id = call->pkt.call_id;
987         pkt.ptype = DCERPC_PKT_BIND_ACK;
988         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
989         pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
990         pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
991         pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
992
993         endpoint = dcerpc_binding_get_string_option(
994                                 call->conn->endpoint->ep_description,
995                                 "endpoint");
996         if (endpoint == NULL) {
997                 endpoint = "";
998         }
999
1000         if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1001                 /*
1002                  * TODO: check if this is really needed
1003                  *
1004                  * Or if we should fix this in our idl files.
1005                  */
1006                 ep_prefix = "\\PIPE\\";
1007                 endpoint += 6;
1008         }
1009
1010         pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1011                                                            ep_prefix,
1012                                                            endpoint);
1013         if (pkt.u.bind_ack.secondary_address == NULL) {
1014                 TALLOC_FREE(call->context);
1015                 return NT_STATUS_NO_MEMORY;
1016         }
1017         pkt.u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1018         pkt.u.bind_ack.ctx_list = ack_ctx_list;
1019         pkt.u.bind_ack.auth_info = data_blob_null;
1020
1021         status = dcesrv_auth_bind_ack(call, &pkt);
1022         if (!NT_STATUS_IS_OK(status)) {
1023                 TALLOC_FREE(call->context);
1024                 return dcesrv_bind_nak(call, 0);
1025         }
1026
1027         rep = talloc_zero(call, struct data_blob_list_item);
1028         if (!rep) {
1029                 TALLOC_FREE(call->context);
1030                 return NT_STATUS_NO_MEMORY;
1031         }
1032
1033         status = ncacn_push_auth(&rep->blob, call, &pkt,
1034                                  call->out_auth_info);
1035         if (!NT_STATUS_IS_OK(status)) {
1036                 TALLOC_FREE(call->context);
1037                 return status;
1038         }
1039
1040         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1041
1042         DLIST_ADD_END(call->replies, rep);
1043         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1044
1045         if (call->conn->call_list && call->conn->call_list->replies) {
1046                 if (call->conn->transport.report_output_data) {
1047                         call->conn->transport.report_output_data(call->conn);
1048                 }
1049         }
1050
1051         return NT_STATUS_OK;
1052 }
1053
1054
1055 /*
1056   handle a auth3 request
1057 */
1058 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1059 {
1060         NTSTATUS status;
1061
1062         if (!call->conn->allow_auth3) {
1063                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1064         }
1065
1066         if (call->conn->auth_state.auth_finished) {
1067                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1068         }
1069
1070         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1071                         DCERPC_PKT_AUTH3,
1072                         call->pkt.u.auth3.auth_info.length,
1073                         0, /* required flags */
1074                         DCERPC_PFC_FLAG_FIRST |
1075                         DCERPC_PFC_FLAG_LAST |
1076                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1077                         0x08 | /* this is not defined, but should be ignored */
1078                         DCERPC_PFC_FLAG_CONC_MPX |
1079                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1080                         DCERPC_PFC_FLAG_MAYBE |
1081                         DCERPC_PFC_FLAG_OBJECT_UUID);
1082         if (!NT_STATUS_IS_OK(status)) {
1083                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1084         }
1085
1086         /* handle the auth3 in the auth code */
1087         if (!dcesrv_auth_auth3(call)) {
1088                 call->conn->auth_state.auth_invalid = true;
1089                 if (call->fault_code != 0) {
1090                         return dcesrv_fault_disconnect(call, call->fault_code);
1091                 }
1092         }
1093
1094         talloc_free(call);
1095
1096         /* we don't send a reply to a auth3 request, except by a
1097            fault */
1098         return NT_STATUS_OK;
1099 }
1100
1101
1102 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1103                                 const struct dcerpc_bind *b,
1104                                 const struct dcerpc_ctx_list *ctx,
1105                                 struct dcerpc_ack_ctx *ack,
1106                                 bool validate_only,
1107                                 const struct ndr_syntax_id *supported_transfer)
1108 {
1109         uint32_t if_version;
1110         struct dcesrv_connection_context *context;
1111         const struct dcesrv_interface *iface;
1112         struct GUID uuid;
1113         NTSTATUS status;
1114         const struct ndr_syntax_id *selected_transfer = NULL;
1115         size_t i;
1116         bool ok;
1117
1118         if (b == NULL) {
1119                 return NT_STATUS_INTERNAL_ERROR;
1120         }
1121         if (ctx == NULL) {
1122                 return NT_STATUS_INTERNAL_ERROR;
1123         }
1124         if (ctx->num_transfer_syntaxes < 1) {
1125                 return NT_STATUS_INTERNAL_ERROR;
1126         }
1127         if (ack == NULL) {
1128                 return NT_STATUS_INTERNAL_ERROR;
1129         }
1130         if (supported_transfer == NULL) {
1131                 return NT_STATUS_INTERNAL_ERROR;
1132         }
1133
1134         switch (ack->result) {
1135         case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1136         case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1137                 /*
1138                  * We is already completed.
1139                  */
1140                 return NT_STATUS_OK;
1141         default:
1142                 break;
1143         }
1144
1145         ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1146         ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1147
1148         if_version = ctx->abstract_syntax.if_version;
1149         uuid = ctx->abstract_syntax.uuid;
1150
1151         iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1152         if (iface == NULL) {
1153                 char *uuid_str = GUID_string(call, &uuid);
1154                 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1155                 talloc_free(uuid_str);
1156                 /*
1157                  * We report this only via ack->result
1158                  */
1159                 return NT_STATUS_OK;
1160         }
1161
1162         ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1163         ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1164
1165         if (validate_only) {
1166                 /*
1167                  * We report this only via ack->result
1168                  */
1169                 return NT_STATUS_OK;
1170         }
1171
1172         for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1173                 /*
1174                  * we only do NDR encoded dcerpc for now.
1175                  */
1176                 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1177                                          supported_transfer);
1178                 if (ok) {
1179                         selected_transfer = supported_transfer;
1180                         break;
1181                 }
1182         }
1183
1184         context = dcesrv_find_context(call->conn, ctx->context_id);
1185         if (context != NULL) {
1186                 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1187                                          &ctx->abstract_syntax);
1188                 if (!ok) {
1189                         return NT_STATUS_RPC_PROTOCOL_ERROR;
1190                 }
1191
1192                 if (selected_transfer != NULL) {
1193                         ok = ndr_syntax_id_equal(&context->transfer_syntax,
1194                                                  selected_transfer);
1195                         if (!ok) {
1196                                 return NT_STATUS_RPC_PROTOCOL_ERROR;
1197                         }
1198
1199                         ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1200                         ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1201                         ack->syntax = context->transfer_syntax;
1202                 }
1203
1204                 /*
1205                  * We report this only via ack->result
1206                  */
1207                 return NT_STATUS_OK;
1208         }
1209
1210         if (selected_transfer == NULL) {
1211                 /*
1212                  * We report this only via ack->result
1213                  */
1214                 return NT_STATUS_OK;
1215         }
1216
1217         ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1218         ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1219
1220         /* add this context to the list of available context_ids */
1221         context = talloc_zero(call->conn, struct dcesrv_connection_context);
1222         if (context == NULL) {
1223                 return NT_STATUS_NO_MEMORY;
1224         }
1225         context->conn = call->conn;
1226         context->context_id = ctx->context_id;
1227         context->iface = iface;
1228         context->transfer_syntax = *selected_transfer;
1229         context->private_data = NULL;
1230         DLIST_ADD(call->conn->contexts, context);
1231         call->context = context;
1232         talloc_set_destructor(context, dcesrv_connection_context_destructor);
1233
1234         dcesrv_prepare_context_auth(call);
1235
1236         /*
1237          * Multiplex is supported by default
1238          */
1239         call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1240
1241         status = iface->bind(call, iface, if_version);
1242         call->context = NULL;
1243         if (!NT_STATUS_IS_OK(status)) {
1244                 /* we don't want to trigger the iface->unbind() hook */
1245                 context->iface = NULL;
1246                 talloc_free(context);
1247                 /*
1248                  * We report this only via ack->result
1249                  */
1250                 return NT_STATUS_OK;
1251         }
1252
1253         ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1254         ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1255         ack->syntax = context->transfer_syntax;
1256         return NT_STATUS_OK;
1257 }
1258
1259 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1260                                 const struct dcerpc_bind *b,
1261                                 struct dcerpc_ack_ctx *ack_ctx_list)
1262 {
1263         NTSTATUS status;
1264         size_t i;
1265         bool validate_only = false;
1266         bool preferred_ndr32;
1267
1268         /*
1269          * Try to negotiate one new presentation context,
1270          * using our preferred transfer syntax.
1271          */
1272         for (i = 0; i < b->num_contexts; i++) {
1273                 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1274                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1275
1276                 status = dcesrv_check_or_create_context(call, b, c, a,
1277                                                 validate_only,
1278                                                 call->conn->preferred_transfer);
1279                 if (!NT_STATUS_IS_OK(status)) {
1280                         return status;
1281                 }
1282
1283                 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1284                         /*
1285                          * We managed to negotiate one context.
1286                          *
1287                          * => we're done.
1288                          */
1289                         validate_only = true;
1290                 }
1291         }
1292
1293         preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1294                                         call->conn->preferred_transfer);
1295         if (preferred_ndr32) {
1296                 /*
1297                  * We're done.
1298                  */
1299                 return NT_STATUS_OK;
1300         }
1301
1302         /*
1303          * Try to negotiate one new presentation context,
1304          * using NDR 32 as fallback.
1305          */
1306         for (i = 0; i < b->num_contexts; i++) {
1307                 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1308                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1309
1310                 status = dcesrv_check_or_create_context(call, b, c, a,
1311                                                 validate_only,
1312                                                 &ndr_transfer_syntax_ndr);
1313                 if (!NT_STATUS_IS_OK(status)) {
1314                         return status;
1315                 }
1316
1317                 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1318                         /*
1319                          * We managed to negotiate one context.
1320                          *
1321                          * => we're done.
1322                          */
1323                         validate_only = true;
1324                 }
1325         }
1326
1327         return NT_STATUS_OK;
1328 }
1329
1330 /*
1331   handle a alter context request
1332 */
1333 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1334 {
1335         NTSTATUS status;
1336         bool auth_ok = false;
1337         struct ncacn_packet pkt;
1338         uint32_t extra_flags = 0;
1339         struct data_blob_list_item *rep = NULL;
1340         struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1341         size_t i;
1342
1343         if (!call->conn->allow_alter) {
1344                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1345         }
1346
1347         status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1348                         DCERPC_PKT_ALTER,
1349                         call->pkt.u.alter.auth_info.length,
1350                         0, /* required flags */
1351                         DCERPC_PFC_FLAG_FIRST |
1352                         DCERPC_PFC_FLAG_LAST |
1353                         DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1354                         0x08 | /* this is not defined, but should be ignored */
1355                         DCERPC_PFC_FLAG_CONC_MPX |
1356                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1357                         DCERPC_PFC_FLAG_MAYBE |
1358                         DCERPC_PFC_FLAG_OBJECT_UUID);
1359         if (!NT_STATUS_IS_OK(status)) {
1360                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1361         }
1362
1363         auth_ok = dcesrv_auth_alter(call);
1364         if (!auth_ok) {
1365                 if (call->fault_code != 0) {
1366                         return dcesrv_fault_disconnect(call, call->fault_code);
1367                 }
1368         }
1369
1370         if (call->pkt.u.alter.num_contexts < 1) {
1371                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1372         }
1373
1374         ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1375                                          call->pkt.u.alter.num_contexts);
1376         if (ack_ctx_list == NULL) {
1377                 return NT_STATUS_NO_MEMORY;
1378         }
1379
1380         /*
1381          * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1382          * dcesrv_check_or_create_context()) and do some protocol validation
1383          * and set sane defaults.
1384          */
1385         for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1386                 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1387                 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1388
1389                 if (c->num_transfer_syntaxes == 0) {
1390                         return dcesrv_fault_disconnect(call,
1391                                         DCERPC_NCA_S_PROTO_ERROR);
1392                 }
1393
1394                 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1395                 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1396         }
1397
1398         /*
1399          * Try to negotiate one new presentation context.
1400          */
1401         status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1402         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1403                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1404         }
1405         if (!NT_STATUS_IS_OK(status)) {
1406                 return status;
1407         }
1408
1409         if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1410             (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1411                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1412                 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1413         }
1414
1415         if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1416                 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1417         }
1418
1419         /* handle any authentication that is being requested */
1420         if (!auth_ok) {
1421                 if (call->in_auth_info.auth_type !=
1422                     call->conn->auth_state.auth_type)
1423                 {
1424                         return dcesrv_fault_disconnect(call,
1425                                         DCERPC_FAULT_SEC_PKG_ERROR);
1426                 }
1427                 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1428         }
1429
1430         dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1431         pkt.auth_length = 0;
1432         pkt.call_id = call->pkt.call_id;
1433         pkt.ptype = DCERPC_PKT_ALTER_RESP;
1434         pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1435         pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1436         pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1437         pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1438         pkt.u.alter_resp.secondary_address = "";
1439         pkt.u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1440         pkt.u.alter_resp.ctx_list = ack_ctx_list;
1441         pkt.u.alter_resp.auth_info = data_blob_null;
1442
1443         status = dcesrv_auth_alter_ack(call, &pkt);
1444         if (!NT_STATUS_IS_OK(status)) {
1445                 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1446         }
1447
1448         rep = talloc_zero(call, struct data_blob_list_item);
1449         if (!rep) {
1450                 return NT_STATUS_NO_MEMORY;
1451         }
1452
1453         status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1454         if (!NT_STATUS_IS_OK(status)) {
1455                 return status;
1456         }
1457
1458         dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1459
1460         DLIST_ADD_END(call->replies, rep);
1461         dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1462
1463         if (call->conn->call_list && call->conn->call_list->replies) {
1464                 if (call->conn->transport.report_output_data) {
1465                         call->conn->transport.report_output_data(call->conn);
1466                 }
1467         }
1468
1469         return NT_STATUS_OK;
1470 }
1471
1472 /*
1473   possibly save the call for inspection with ndrdump
1474  */
1475 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1476 {
1477 #ifdef DEVELOPER
1478         char *fname;
1479         const char *dump_dir;
1480         dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1481         if (!dump_dir) {
1482                 return;
1483         }
1484         fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1485                                 dump_dir,
1486                                 call->context->iface->name,
1487                                 call->pkt.u.request.opnum,
1488                                 why);
1489         if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1490                 DEBUG(0,("RPC SAVED %s\n", fname));
1491         }
1492         talloc_free(fname);
1493 #endif
1494 }
1495
1496 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1497 {
1498         TALLOC_CTX *frame = talloc_stackframe();
1499         const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1500                 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1501         const struct dcerpc_sec_vt_pcontext pcontext = {
1502                 .abstract_syntax = call->context->iface->syntax_id,
1503                 .transfer_syntax = call->context->transfer_syntax,
1504         };
1505         const struct dcerpc_sec_vt_header2 header2 =
1506                 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1507         enum ndr_err_code ndr_err;
1508         struct dcerpc_sec_verification_trailer *vt = NULL;
1509         NTSTATUS status = NT_STATUS_OK;
1510         bool ok;
1511
1512         SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1513
1514         ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1515                                                           frame, &vt);
1516         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1517                 status = ndr_map_error2ntstatus(ndr_err);
1518                 goto done;
1519         }
1520
1521         ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1522                                                    &pcontext, &header2);
1523         if (!ok) {
1524                 status = NT_STATUS_ACCESS_DENIED;
1525                 goto done;
1526         }
1527 done:
1528         TALLOC_FREE(frame);
1529         return status;
1530 }
1531
1532 /*
1533   handle a dcerpc request packet
1534 */
1535 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1536 {
1537         const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1538         enum dcerpc_transport_t transport =
1539                 dcerpc_binding_get_transport(endpoint->ep_description);
1540         struct ndr_pull *pull;
1541         NTSTATUS status;
1542
1543         if (!call->conn->allow_request) {
1544                 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1545         }
1546
1547         /* if authenticated, and the mech we use can't do async replies, don't use them... */
1548         if (call->conn->auth_state.gensec_security && 
1549             !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1550                 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1551         }
1552
1553         if (call->context == NULL) {
1554                 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1555                                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1556         }
1557
1558         switch (call->conn->auth_state.auth_level) {
1559         case DCERPC_AUTH_LEVEL_NONE:
1560         case DCERPC_AUTH_LEVEL_PACKET:
1561         case DCERPC_AUTH_LEVEL_INTEGRITY:
1562         case DCERPC_AUTH_LEVEL_PRIVACY:
1563                 break;
1564         default:
1565                 if (!call->context->allow_connect) {
1566                         char *addr;
1567
1568                         addr = tsocket_address_string(call->conn->remote_address,
1569                                                       call);
1570
1571                         DEBUG(2, ("%s: restrict auth_level_connect access "
1572                                   "to [%s] with auth[type=0x%x,level=0x%x] "
1573                                   "on [%s] from [%s]\n",
1574                                   __func__, call->context->iface->name,
1575                                   call->conn->auth_state.auth_type,
1576                                   call->conn->auth_state.auth_level,
1577                                   derpc_transport_string_by_transport(transport),
1578                                   addr));
1579                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1580                 }
1581                 break;
1582         }
1583
1584         if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1585                 char *addr;
1586
1587                 addr = tsocket_address_string(call->conn->remote_address, call);
1588
1589                 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1590                           "to [%s] with auth[type=0x%x,level=0x%x] "
1591                           "on [%s] from [%s]\n",
1592                           __func__,
1593                           call->context->min_auth_level,
1594                           call->context->iface->name,
1595                           call->conn->auth_state.auth_type,
1596                           call->conn->auth_state.auth_level,
1597                           derpc_transport_string_by_transport(transport),
1598                           addr));
1599                 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1600         }
1601
1602         pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1603         NT_STATUS_HAVE_NO_MEMORY(pull);
1604
1605         pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1606
1607         call->ndr_pull  = pull;
1608
1609         if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1610                 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1611         }
1612
1613         status = dcesrv_check_verification_trailer(call);
1614         if (!NT_STATUS_IS_OK(status)) {
1615                 uint32_t faultcode = DCERPC_FAULT_OTHER;
1616                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1617                         faultcode = DCERPC_FAULT_ACCESS_DENIED;
1618                 }
1619                 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1620                            nt_errstr(status)));
1621                 return dcesrv_fault(call, faultcode);
1622         }
1623
1624         /* unravel the NDR for the packet */
1625         status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1626         if (!NT_STATUS_IS_OK(status)) {
1627                 uint8_t extra_flags = 0;
1628                 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1629                         /* we got an unknown call */
1630                         DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1631                                  call->pkt.u.request.opnum,
1632                                  call->context->iface->name));
1633                         dcesrv_save_call(call, "unknown");
1634                         extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1635                 } else {
1636                         dcesrv_save_call(call, "pullfail");
1637                 }
1638                 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1639         }
1640
1641         if (pull->offset != pull->data_size) {
1642                 dcesrv_save_call(call, "extrabytes");
1643                 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n", 
1644                          pull->data_size - pull->offset));
1645         }
1646
1647         /* call the dispatch function */
1648         status = call->context->iface->dispatch(call, call, call->r);
1649         if (!NT_STATUS_IS_OK(status)) {
1650                 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1651                          call->context->iface->name,
1652                          call->pkt.u.request.opnum,
1653                          dcerpc_errstr(pull, call->fault_code)));
1654                 return dcesrv_fault(call, call->fault_code);
1655         }
1656
1657         /* add the call to the pending list */
1658         dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1659
1660         if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1661                 return NT_STATUS_OK;
1662         }
1663
1664         return dcesrv_reply(call);
1665 }
1666
1667
1668 /*
1669   remove the call from the right list when freed
1670  */
1671 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1672 {
1673         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1674         return 0;
1675 }
1676
1677 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1678 {
1679         return conn->local_address;
1680 }
1681
1682 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1683 {
1684         return conn->remote_address;
1685 }
1686
1687 /*
1688   process some input to a dcerpc endpoint server.
1689 */
1690 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1691                                             struct ncacn_packet *pkt,
1692                                             DATA_BLOB blob)
1693 {
1694         NTSTATUS status;
1695         struct dcesrv_call_state *call;
1696         struct dcesrv_call_state *existing = NULL;
1697
1698         call = talloc_zero(dce_conn, struct dcesrv_call_state);
1699         if (!call) {
1700                 data_blob_free(&blob);
1701                 talloc_free(pkt);
1702                 return NT_STATUS_NO_MEMORY;
1703         }
1704         call->conn              = dce_conn;
1705         call->event_ctx         = dce_conn->event_ctx;
1706         call->msg_ctx           = dce_conn->msg_ctx;
1707         call->state_flags       = call->conn->state_flags;
1708         call->time              = timeval_current();
1709         call->list              = DCESRV_LIST_NONE;
1710
1711         talloc_steal(call, pkt);
1712         talloc_steal(call, blob.data);
1713         call->pkt = *pkt;
1714
1715         talloc_set_destructor(call, dcesrv_call_dequeue);
1716
1717         if (call->conn->allow_bind) {
1718                 /*
1719                  * Only one bind is possible per connection
1720                  */
1721                 call->conn->allow_bind = false;
1722                 return dcesrv_bind(call);
1723         }
1724
1725         /* we have to check the signing here, before combining the
1726            pdus */
1727         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1728                 if (!call->conn->allow_request) {
1729                         return dcesrv_fault_disconnect(call,
1730                                         DCERPC_NCA_S_PROTO_ERROR);
1731                 }
1732
1733                 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1734                                 DCERPC_PKT_REQUEST,
1735                                 call->pkt.u.request.stub_and_verifier.length,
1736                                 0, /* required_flags */
1737                                 DCERPC_PFC_FLAG_FIRST |
1738                                 DCERPC_PFC_FLAG_LAST |
1739                                 DCERPC_PFC_FLAG_PENDING_CANCEL |
1740                                 0x08 | /* this is not defined, but should be ignored */
1741                                 DCERPC_PFC_FLAG_CONC_MPX |
1742                                 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1743                                 DCERPC_PFC_FLAG_MAYBE |
1744                                 DCERPC_PFC_FLAG_OBJECT_UUID);
1745                 if (!NT_STATUS_IS_OK(status)) {
1746                         return dcesrv_fault_disconnect(call,
1747                                         DCERPC_NCA_S_PROTO_ERROR);
1748                 }
1749
1750                 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1751                         /*
1752                          * We don't use dcesrv_fault_disconnect()
1753                          * here, because we don't want to set
1754                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1755                          *
1756                          * Note that we don't check against the negotiated
1757                          * max_recv_frag, but a hard coded value.
1758                          */
1759                         dcesrv_call_disconnect_after(call,
1760                                 "dcesrv_auth_request - frag_length too large");
1761                         return dcesrv_fault(call,
1762                                         DCERPC_NCA_S_PROTO_ERROR);
1763                 }
1764
1765                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1766                         if (dce_conn->pending_call_list != NULL) {
1767                                 /*
1768                                  * concurrent requests are only allowed
1769                                  * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1770                                  */
1771                                 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1772                                         dcesrv_call_disconnect_after(call,
1773                                                 "dcesrv_auth_request - "
1774                                                 "existing pending call without CONN_MPX");
1775                                         return dcesrv_fault(call,
1776                                                 DCERPC_NCA_S_PROTO_ERROR);
1777                                 }
1778                         }
1779                         /* only one request is possible in the fragmented list */
1780                         if (dce_conn->incoming_fragmented_call_list != NULL) {
1781                                 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1782                                         /*
1783                                          * Without DCERPC_PFC_FLAG_CONC_MPX
1784                                          * we need to return the FAULT on the
1785                                          * already existing call.
1786                                          *
1787                                          * This is important to get the
1788                                          * call_id and context_id right.
1789                                          */
1790                                         TALLOC_FREE(call);
1791                                         call = dce_conn->incoming_fragmented_call_list;
1792                                 }
1793                                 dcesrv_call_disconnect_after(call,
1794                                         "dcesrv_auth_request - "
1795                                         "existing fragmented call");
1796                                 return dcesrv_fault(call,
1797                                                 DCERPC_NCA_S_PROTO_ERROR);
1798                         }
1799                         if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1800                                 return dcesrv_fault_disconnect(call,
1801                                                 DCERPC_FAULT_NO_CALL_ACTIVE);
1802                         }
1803                         call->context = dcesrv_find_context(call->conn,
1804                                                 call->pkt.u.request.context_id);
1805                         if (call->context == NULL) {
1806                                 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1807                                         DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1808                         }
1809                 } else {
1810                         const struct dcerpc_request *nr = &call->pkt.u.request;
1811                         const struct dcerpc_request *er = NULL;
1812                         int cmp;
1813
1814                         existing = dcesrv_find_fragmented_call(dce_conn,
1815                                                         call->pkt.call_id);
1816                         if (existing == NULL) {
1817                                 dcesrv_call_disconnect_after(call,
1818                                         "dcesrv_auth_request - "
1819                                         "no existing fragmented call");
1820                                 return dcesrv_fault(call,
1821                                                 DCERPC_NCA_S_PROTO_ERROR);
1822                         }
1823                         er = &existing->pkt.u.request;
1824
1825                         if (call->pkt.ptype != existing->pkt.ptype) {
1826                                 /* trying to play silly buggers are we? */
1827                                 return dcesrv_fault_disconnect(existing,
1828                                                 DCERPC_NCA_S_PROTO_ERROR);
1829                         }
1830                         cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1831                                      sizeof(pkt->drep));
1832                         if (cmp != 0) {
1833                                 return dcesrv_fault_disconnect(existing,
1834                                                 DCERPC_NCA_S_PROTO_ERROR);
1835                         }
1836                         if (nr->context_id != er->context_id)  {
1837                                 return dcesrv_fault_disconnect(existing,
1838                                                 DCERPC_NCA_S_PROTO_ERROR);
1839                         }
1840                         if (nr->opnum != er->opnum)  {
1841                                 return dcesrv_fault_disconnect(existing,
1842                                                 DCERPC_NCA_S_PROTO_ERROR);
1843                         }
1844                 }
1845         }
1846
1847         if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1848                 bool ok;
1849                 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1850
1851                 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1852                         payload_offset += 16;
1853                 }
1854
1855                 ok = dcesrv_auth_pkt_pull(call, &blob,
1856                                           0, /* required_flags */
1857                                           DCERPC_PFC_FLAG_FIRST |
1858                                           DCERPC_PFC_FLAG_LAST |
1859                                           DCERPC_PFC_FLAG_PENDING_CANCEL |
1860                                           0x08 | /* this is not defined, but should be ignored */
1861                                           DCERPC_PFC_FLAG_CONC_MPX |
1862                                           DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1863                                           DCERPC_PFC_FLAG_MAYBE |
1864                                           DCERPC_PFC_FLAG_OBJECT_UUID,
1865                                           payload_offset,
1866                                           &call->pkt.u.request.stub_and_verifier);
1867                 if (!ok) {
1868                         /*
1869                          * We don't use dcesrv_fault_disconnect()
1870                          * here, because we don't want to set
1871                          * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1872                          */
1873                         dcesrv_call_disconnect_after(call,
1874                                                 "dcesrv_auth_request - failed");
1875                         if (call->fault_code == 0) {
1876                                 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1877                         }
1878                         return dcesrv_fault(call, call->fault_code);
1879                 }
1880         }
1881
1882         /* see if this is a continued packet */
1883         if (existing != NULL) {
1884                 struct dcerpc_request *er = &existing->pkt.u.request;
1885                 const struct dcerpc_request *nr = &call->pkt.u.request;
1886                 size_t available;
1887                 size_t alloc_size;
1888                 size_t alloc_hint;
1889
1890                 /*
1891                  * Up to 4 MByte are allowed by all fragments
1892                  */
1893                 available = dce_conn->max_total_request_size;
1894                 if (er->stub_and_verifier.length > available) {
1895                         dcesrv_call_disconnect_after(existing,
1896                                 "dcesrv_auth_request - existing payload too large");
1897                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1898                 }
1899                 available -= er->stub_and_verifier.length;
1900                 if (nr->alloc_hint > available) {
1901                         dcesrv_call_disconnect_after(existing,
1902                                 "dcesrv_auth_request - alloc hint too large");
1903                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1904                 }
1905                 if (nr->stub_and_verifier.length > available) {
1906                         dcesrv_call_disconnect_after(existing,
1907                                 "dcesrv_auth_request - new payload too large");
1908                         return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1909                 }
1910                 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1911                 /* allocate at least 1 byte */
1912                 alloc_hint = MAX(alloc_hint, 1);
1913                 alloc_size = er->stub_and_verifier.length +
1914                              nr->stub_and_verifier.length;
1915                 alloc_size = MAX(alloc_size, alloc_hint);
1916
1917                 er->stub_and_verifier.data =
1918                         talloc_realloc(existing,
1919                                        er->stub_and_verifier.data,
1920                                        uint8_t, alloc_size);
1921                 if (er->stub_and_verifier.data == NULL) {
1922                         TALLOC_FREE(call);
1923                         return dcesrv_fault_with_flags(existing,
1924                                                        DCERPC_FAULT_OUT_OF_RESOURCES,
1925                                                        DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1926                 }
1927                 memcpy(er->stub_and_verifier.data +
1928                        er->stub_and_verifier.length,
1929                        nr->stub_and_verifier.data,
1930                        nr->stub_and_verifier.length);
1931                 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1932
1933                 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1934
1935                 TALLOC_FREE(call);
1936                 call = existing;
1937         }
1938
1939         /* this may not be the last pdu in the chain - if its isn't then
1940            just put it on the incoming_fragmented_call_list and wait for the rest */
1941         if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1942             !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1943                 /*
1944                  * Up to 4 MByte are allowed by all fragments
1945                  */
1946                 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1947                         dcesrv_call_disconnect_after(call,
1948                                 "dcesrv_auth_request - initial alloc hint too large");
1949                         return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1950                 }
1951                 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1952                 return NT_STATUS_OK;
1953         } 
1954         
1955         /* This removes any fragments we may have had stashed away */
1956         dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1957
1958         switch (call->pkt.ptype) {
1959         case DCERPC_PKT_BIND:
1960                 status = dcesrv_bind_nak(call,
1961                         DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1962                 break;
1963         case DCERPC_PKT_AUTH3:
1964                 status = dcesrv_auth3(call);
1965                 break;
1966         case DCERPC_PKT_ALTER:
1967                 status = dcesrv_alter(call);
1968                 break;
1969         case DCERPC_PKT_REQUEST:
1970                 status = dcesrv_request(call);
1971                 break;
1972         case DCERPC_PKT_CO_CANCEL:
1973         case DCERPC_PKT_ORPHANED:
1974                 /*
1975                  * Window just ignores CO_CANCEL and ORPHANED,
1976                  * so we do...
1977                  */
1978                 status = NT_STATUS_OK;
1979                 TALLOC_FREE(call);
1980                 break;
1981         case DCERPC_PKT_BIND_ACK:
1982         case DCERPC_PKT_BIND_NAK:
1983         case DCERPC_PKT_ALTER_RESP:
1984         case DCERPC_PKT_RESPONSE:
1985         case DCERPC_PKT_FAULT:
1986         case DCERPC_PKT_SHUTDOWN:
1987         default:
1988                 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1989                 break;
1990         }
1991
1992         /* if we are going to be sending a reply then add
1993            it to the list of pending calls. We add it to the end to keep the call
1994            list in the order we will answer */
1995         if (!NT_STATUS_IS_OK(status)) {
1996                 talloc_free(call);
1997         }
1998
1999         return status;
2000 }
2001
2002 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, 
2003                                       struct loadparm_context *lp_ctx,
2004                                       const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2005 {
2006         NTSTATUS status;
2007         struct dcesrv_context *dce_ctx;
2008         int i;
2009
2010         if (!endpoint_servers) {
2011                 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2012                 return NT_STATUS_INTERNAL_ERROR;
2013         }
2014
2015         dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2016         NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2017
2018         if (uid_wrapper_enabled()) {
2019                 setenv("UID_WRAPPER_MYUID", "1", 1);
2020         }
2021         dce_ctx->initial_euid = geteuid();
2022         if (uid_wrapper_enabled()) {
2023                 unsetenv("UID_WRAPPER_MYUID");
2024         }
2025
2026         dce_ctx->endpoint_list  = NULL;
2027         dce_ctx->lp_ctx = lp_ctx;
2028         dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2029         NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2030         dce_ctx->broken_connections = NULL;
2031
2032         for (i=0;endpoint_servers[i];i++) {
2033                 const struct dcesrv_endpoint_server *ep_server;
2034
2035                 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2036                 if (!ep_server) {
2037                         DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2038                         return NT_STATUS_INTERNAL_ERROR;
2039                 }
2040
2041                 status = ep_server->init_server(dce_ctx, ep_server);
2042                 if (!NT_STATUS_IS_OK(status)) {
2043                         DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2044                                 nt_errstr(status)));
2045                         return status;
2046                 }
2047         }
2048
2049         *_dce_ctx = dce_ctx;
2050         return NT_STATUS_OK;
2051 }
2052
2053 /* the list of currently registered DCERPC endpoint servers.
2054  */
2055 static struct ep_server {
2056         struct dcesrv_endpoint_server *ep_server;
2057 } *ep_servers = NULL;
2058 static int num_ep_servers;
2059
2060 /*
2061   register a DCERPC endpoint server. 
2062
2063   The 'name' can be later used by other backends to find the operations
2064   structure for this backend.  
2065
2066 */
2067 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2068 {
2069         
2070         if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2071                 /* its already registered! */
2072                 DEBUG(0,("DCERPC endpoint server '%s' already registered\n", 
2073                          ep_server->name));
2074                 return NT_STATUS_OBJECT_NAME_COLLISION;
2075         }
2076
2077         ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2078         if (!ep_servers) {
2079                 smb_panic("out of memory in dcerpc_register");
2080         }
2081
2082         ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2083         ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2084
2085         num_ep_servers++;
2086
2087         DEBUG(3,("DCERPC endpoint server '%s' registered\n", 
2088                  ep_server->name));
2089
2090         return NT_STATUS_OK;
2091 }
2092
2093 /*
2094   return the operations structure for a named backend of the specified type
2095 */
2096 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2097 {
2098         int i;
2099
2100         for (i=0;i<num_ep_servers;i++) {
2101                 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2102                         return ep_servers[i].ep_server;
2103                 }
2104         }
2105
2106         return NULL;
2107 }
2108
2109 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2110 {
2111         static bool initialized;
2112 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
2113         STATIC_dcerpc_server_MODULES_PROTO;
2114         init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2115         init_module_fn *shared_init;
2116
2117         if (initialized) {
2118                 return;
2119         }
2120         initialized = true;
2121
2122         shared_init = load_samba_modules(NULL, "dcerpc_server");
2123
2124         run_init_functions(static_init);
2125         run_init_functions(shared_init);
2126
2127         talloc_free(shared_init);
2128 }
2129
2130 /*
2131   return the DCERPC module version, and the size of some critical types
2132   This can be used by endpoint server modules to either detect compilation errors, or provide
2133   multiple implementations for different smbd compilation options in one module
2134 */
2135 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2136 {
2137         static const struct dcesrv_critical_sizes critical_sizes = {
2138                 DCERPC_MODULE_VERSION,
2139                 sizeof(struct dcesrv_context),
2140                 sizeof(struct dcesrv_endpoint),
2141                 sizeof(struct dcesrv_endpoint_server),
2142                 sizeof(struct dcesrv_interface),
2143                 sizeof(struct dcesrv_if_list),
2144                 sizeof(struct dcesrv_connection),
2145                 sizeof(struct dcesrv_call_state),
2146                 sizeof(struct dcesrv_auth),
2147                 sizeof(struct dcesrv_handle)
2148         };
2149
2150         return &critical_sizes;
2151 }
2152
2153 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2154 {
2155         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2156         struct stream_connection *srv_conn;
2157         srv_conn = talloc_get_type(dce_conn->transport.private_data,
2158                                    struct stream_connection);
2159
2160         dce_conn->allow_bind = false;
2161         dce_conn->allow_auth3 = false;
2162         dce_conn->allow_alter = false;
2163         dce_conn->allow_request = false;
2164
2165         if (dce_conn->pending_call_list == NULL) {
2166                 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2167
2168                 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2169                 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2170                 return;
2171         }
2172
2173         if (dce_conn->terminate != NULL) {
2174                 return;
2175         }
2176
2177         DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
2178                  reason));
2179         dce_conn->terminate = talloc_strdup(dce_conn, reason);
2180         if (dce_conn->terminate == NULL) {
2181                 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
2182         }
2183         DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2184 }
2185
2186 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2187 {
2188         struct dcesrv_connection *cur, *next;
2189
2190         next = dce_ctx->broken_connections;
2191         while (next != NULL) {
2192                 cur = next;
2193                 next = cur->next;
2194
2195                 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2196                         struct dcesrv_connection_context *context_cur, *context_next;
2197
2198                         context_next = cur->contexts;
2199                         while (context_next != NULL) {
2200                                 context_cur = context_next;
2201                                 context_next = context_cur->next;
2202
2203                                 dcesrv_connection_context_destructor(context_cur);
2204                         }
2205                 }
2206
2207                 dcesrv_terminate_connection(cur, cur->terminate);
2208         }
2209 }
2210
2211 /* We need this include to be able to compile on some plateforms
2212  * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2213  * correctly.
2214  * It has to be that deep because otherwise we have a conflict on
2215  * const struct dcesrv_interface declaration.
2216  * This is mostly due to socket_wrapper defining #define bind swrap_bind
2217  * which conflict with the bind used before.
2218  */
2219 #include "system/network.h"
2220
2221 struct dcesrv_sock_reply_state {
2222         struct dcesrv_connection *dce_conn;
2223         struct dcesrv_call_state *call;
2224         struct iovec iov;
2225 };
2226
2227 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2228 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2229
2230 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2231 {
2232         struct dcesrv_call_state *call;
2233
2234         call = dce_conn->call_list;
2235         if (!call || !call->replies) {
2236                 return;
2237         }
2238
2239         while (call->replies) {
2240                 struct data_blob_list_item *rep = call->replies;
2241                 struct dcesrv_sock_reply_state *substate;
2242                 struct tevent_req *subreq;
2243
2244                 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2245                 if (!substate) {
2246                         dcesrv_terminate_connection(dce_conn, "no memory");
2247                         return;
2248                 }
2249
2250                 substate->dce_conn = dce_conn;
2251                 substate->call = NULL;
2252
2253                 DLIST_REMOVE(call->replies, rep);
2254
2255                 if (call->replies == NULL && call->terminate_reason == NULL) {
2256                         substate->call = call;
2257                 }
2258
2259                 substate->iov.iov_base = (void *) rep->blob.data;
2260                 substate->iov.iov_len = rep->blob.length;
2261
2262                 subreq = tstream_writev_queue_send(substate,
2263                                                    dce_conn->event_ctx,
2264                                                    dce_conn->stream,
2265                                                    dce_conn->send_queue,
2266                                                    &substate->iov, 1);
2267                 if (!subreq) {
2268                         dcesrv_terminate_connection(dce_conn, "no memory");
2269                         return;
2270                 }
2271                 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2272                                         substate);
2273         }
2274
2275         if (call->terminate_reason != NULL) {
2276                 struct tevent_req *subreq;
2277
2278                 subreq = tevent_queue_wait_send(call,
2279                                                 dce_conn->event_ctx,
2280                                                 dce_conn->send_queue);
2281                 if (!subreq) {
2282                         dcesrv_terminate_connection(dce_conn, __location__);
2283                         return;
2284                 }
2285                 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2286                                         call);
2287         }
2288
2289         DLIST_REMOVE(call->conn->call_list, call);
2290         call->list = DCESRV_LIST_NONE;
2291 }
2292
2293 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2294 {
2295         struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2296                                                 struct dcesrv_sock_reply_state);
2297         int ret;
2298         int sys_errno;
2299         NTSTATUS status;
2300         struct dcesrv_call_state *call = substate->call;
2301
2302         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2303         TALLOC_FREE(subreq);
2304         if (ret == -1) {
2305                 status = map_nt_error_from_unix_common(sys_errno);
2306                 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2307                 return;
2308         }
2309
2310         talloc_free(substate);
2311         if (call) {
2312                 talloc_free(call);
2313         }
2314 }
2315
2316 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2317
2318 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2319 {
2320         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2321                                                 struct dcesrv_call_state);
2322         bool ok;
2323         struct timeval tv;
2324
2325         /* make sure we stop send queue before removing subreq */
2326         tevent_queue_stop(call->conn->send_queue);
2327
2328         ok = tevent_queue_wait_recv(subreq);
2329         TALLOC_FREE(subreq);
2330         if (!ok) {
2331                 dcesrv_terminate_connection(call->conn, __location__);
2332                 return;
2333         }
2334
2335         /* disconnect after 200 usecs */
2336         tv = timeval_current_ofs_usec(200);
2337         subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2338         if (subreq == NULL) {
2339                 dcesrv_terminate_connection(call->conn, __location__);
2340                 return;
2341         }
2342         tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2343                                 call);
2344 }
2345
2346 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2347 {
2348         struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2349                                                 struct dcesrv_call_state);
2350         bool ok;
2351
2352         ok = tevent_wakeup_recv(subreq);
2353         TALLOC_FREE(subreq);
2354         if (!ok) {
2355                 dcesrv_terminate_connection(call->conn, __location__);
2356                 return;
2357         }
2358
2359         dcesrv_terminate_connection(call->conn, call->terminate_reason);
2360 }
2361
2362 struct dcesrv_socket_context {
2363         const struct dcesrv_endpoint *endpoint;
2364         struct dcesrv_context *dcesrv_ctx;
2365 };
2366
2367
2368 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2369
2370 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2371 {
2372         NTSTATUS status;
2373         struct dcesrv_socket_context *dcesrv_sock = 
2374                 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2375         enum dcerpc_transport_t transport =
2376                 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2377         struct dcesrv_connection *dcesrv_conn = NULL;
2378         int ret;
2379         struct tevent_req *subreq;
2380         struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2381
2382         dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2383
2384         if (!srv_conn->session_info) {
2385                 status = auth_anonymous_session_info(srv_conn,
2386                                                      lp_ctx,
2387                                                      &srv_conn->session_info);
2388                 if (!NT_STATUS_IS_OK(status)) {
2389                         DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2390                                 nt_errstr(status)));
2391                         stream_terminate_connection(srv_conn, nt_errstr(status));
2392                         return;
2393                 }
2394         }
2395
2396         /*
2397          * This fills in dcesrv_conn->endpoint with the endpoint
2398          * associated with the socket.  From this point on we know
2399          * which (group of) services we are handling, but not the
2400          * specific interface.
2401          */
2402
2403         status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2404                                          srv_conn,
2405                                          dcesrv_sock->endpoint,
2406                                          srv_conn->session_info,
2407                                          srv_conn->event.ctx,
2408                                          srv_conn->msg_ctx,
2409                                          srv_conn->server_id,
2410                                          DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2411                                          &dcesrv_conn);
2412         if (!NT_STATUS_IS_OK(status)) {
2413                 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
2414                         nt_errstr(status)));
2415                 stream_terminate_connection(srv_conn, nt_errstr(status));
2416                 return;
2417         }
2418
2419         dcesrv_conn->transport.private_data             = srv_conn;
2420         dcesrv_conn->transport.report_output_data       = dcesrv_sock_report_output_data;
2421
2422         TALLOC_FREE(srv_conn->event.fde);
2423
2424         dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2425         if (!dcesrv_conn->send_queue) {
2426                 status = NT_STATUS_NO_MEMORY;
2427                 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2428                         nt_errstr(status)));
2429                 stream_terminate_connection(srv_conn, nt_errstr(status));
2430                 return;
2431         }
2432
2433         if (transport == NCACN_NP) {
2434                 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2435                 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2436                                                   &srv_conn->tstream);
2437         } else {
2438                 ret = tstream_bsd_existing_socket(dcesrv_conn,
2439                                                   socket_get_fd(srv_conn->socket),
2440                                                   &dcesrv_conn->stream);
2441                 if (ret == -1) {
2442                         status = map_nt_error_from_unix_common(errno);
2443                         DEBUG(0, ("dcesrv_sock_accept: "
2444                                   "failed to setup tstream: %s\n",
2445                                   nt_errstr(status)));
2446                         stream_terminate_connection(srv_conn, nt_errstr(status));
2447                         return;
2448                 }
2449                 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2450         }
2451
2452         dcesrv_conn->local_address = srv_conn->local_address;
2453         dcesrv_conn->remote_address = srv_conn->remote_address;
2454
2455         if (transport == NCALRPC) {
2456                 uid_t uid;
2457                 gid_t gid;
2458                 int sock_fd;
2459
2460                 sock_fd = socket_get_fd(srv_conn->socket);
2461                 if (sock_fd == -1) {
2462                         stream_terminate_connection(
2463                                 srv_conn, "socket_get_fd failed\n");
2464                         return;
2465                 }
2466
2467                 ret = getpeereid(sock_fd, &uid, &gid);
2468                 if (ret == -1) {
2469                         status = map_nt_error_from_unix_common(errno);
2470                         DEBUG(0, ("dcesrv_sock_accept: "
2471                                   "getpeereid() failed for NCALRPC: %s\n",
2472                                   nt_errstr(status)));
2473                         stream_terminate_connection(srv_conn, nt_errstr(status));
2474                         return;
2475                 }
2476                 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2477                         struct tsocket_address *r = NULL;
2478
2479                         ret = tsocket_address_unix_from_path(dcesrv_conn,
2480                                                              "/root/ncalrpc_as_system",
2481                                                              &r);
2482                         if (ret == -1) {
2483                                 status = map_nt_error_from_unix_common(errno);
2484                                 DEBUG(0, ("dcesrv_sock_accept: "
2485                                           "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2486                                           nt_errstr(status)));
2487                                 stream_terminate_connection(srv_conn, nt_errstr(status));
2488                                 return;
2489                         }
2490                         dcesrv_conn->remote_address = r;
2491                 }
2492         }
2493
2494         srv_conn->private_data = dcesrv_conn;
2495
2496         irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2497
2498         subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2499                                                dcesrv_conn->event_ctx,
2500                                                dcesrv_conn->stream);
2501         if (!subreq) {
2502                 status = NT_STATUS_NO_MEMORY;
2503                 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2504                         nt_errstr(status)));
2505                 stream_terminate_connection(srv_conn, nt_errstr(status));
2506                 return;
2507         }
2508         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2509
2510         return;
2511 }
2512
2513 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2514 {
2515         struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2516                                              struct dcesrv_connection);
2517         struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2518         struct ncacn_packet *pkt;
2519         DATA_BLOB buffer;
2520         NTSTATUS status;
2521
2522         if (dce_conn->terminate) {
2523                 /*
2524                  * if the current connection is broken
2525                  * we need to clean it up before any other connection
2526                  */
2527                 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2528                 dcesrv_cleanup_broken_connections(dce_ctx);
2529                 return;
2530         }
2531
2532         dcesrv_cleanup_broken_connections(dce_ctx);
2533
2534         status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2535                                                &pkt, &buffer);
2536         TALLOC_FREE(subreq);
2537         if (!NT_STATUS_IS_OK(status)) {
2538                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2539                 return;
2540         }
2541
2542         status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2543         if (!NT_STATUS_IS_OK(status)) {
2544                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2545                 return;
2546         }
2547
2548         subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2549                                                dce_conn->event_ctx,
2550                                                dce_conn->stream);
2551         if (!subreq) {
2552                 status = NT_STATUS_NO_MEMORY;
2553                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2554                 return;
2555         }
2556         tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2557 }
2558
2559 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2560 {
2561         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2562                                              struct dcesrv_connection);
2563         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2564 }
2565
2566 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2567 {
2568         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2569                                              struct dcesrv_connection);
2570         dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2571 }
2572
2573
2574 static const struct stream_server_ops dcesrv_stream_ops = {
2575         .name                   = "rpc",
2576         .accept_connection      = dcesrv_sock_accept,
2577         .recv_handler           = dcesrv_sock_recv,
2578         .send_handler           = dcesrv_sock_send,
2579 };
2580
2581 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 
2582                                    struct loadparm_context *lp_ctx,
2583                                    struct dcesrv_endpoint *e,
2584                             struct tevent_context *event_ctx, const struct model_ops *model_ops)
2585 {
2586         struct dcesrv_socket_context *dcesrv_sock;
2587         uint16_t port = 1;
2588         NTSTATUS status;
2589         const char *endpoint;
2590
2591         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2592         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2593
2594         /* remember the endpoint of this socket */
2595         dcesrv_sock->endpoint           = e;
2596         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2597
2598         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2599
2600         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2601                                      model_ops, &dcesrv_stream_ops, 
2602                                      "unix", endpoint, &port,
2603                                      lpcfg_socket_options(lp_ctx),
2604                                      dcesrv_sock);
2605         if (!NT_STATUS_IS_OK(status)) {
2606                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2607                          endpoint, nt_errstr(status)));
2608         }
2609
2610         return status;
2611 }
2612
2613 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 
2614                                       struct loadparm_context *lp_ctx,
2615                                       struct dcesrv_endpoint *e,
2616                                       struct tevent_context *event_ctx, const struct model_ops *model_ops)
2617 {
2618         struct dcesrv_socket_context *dcesrv_sock;
2619         uint16_t port = 1;
2620         char *full_path;
2621         NTSTATUS status;
2622         const char *endpoint;
2623
2624         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2625
2626         if (endpoint == NULL) {
2627                 /*
2628                  * No identifier specified: use DEFAULT.
2629                  *
2630                  * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2631                  * no endpoint and let the epmapper worry about it.
2632                  */
2633                 endpoint = "DEFAULT";
2634                 status = dcerpc_binding_set_string_option(e->ep_description,
2635                                                           "endpoint",
2636                                                           endpoint);
2637                 if (!NT_STATUS_IS_OK(status)) {
2638                         DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2639                                   nt_errstr(status)));
2640                         return status;
2641                 }
2642         }
2643
2644         full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2645                                     endpoint);
2646
2647         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2648         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2649
2650         /* remember the endpoint of this socket */
2651         dcesrv_sock->endpoint           = e;
2652         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2653
2654         status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2655                                      model_ops, &dcesrv_stream_ops, 
2656                                      "unix", full_path, &port, 
2657                                      lpcfg_socket_options(lp_ctx),
2658                                      dcesrv_sock);
2659         if (!NT_STATUS_IS_OK(status)) {
2660                 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2661                          endpoint, full_path, nt_errstr(status)));
2662         }
2663         return status;
2664 }
2665
2666 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2667                                  struct loadparm_context *lp_ctx,
2668                                  struct dcesrv_endpoint *e,
2669                                  struct tevent_context *event_ctx, const struct model_ops *model_ops)
2670 {
2671         struct dcesrv_socket_context *dcesrv_sock;
2672         NTSTATUS status;
2673         const char *endpoint;
2674
2675         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2676         if (endpoint == NULL) {
2677                 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2678                 return NT_STATUS_INVALID_PARAMETER;
2679         }
2680
2681         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2682         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2683
2684         /* remember the endpoint of this socket */
2685         dcesrv_sock->endpoint           = e;
2686         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2687
2688         status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2689                                           model_ops, &dcesrv_stream_ops,
2690                                           endpoint,
2691                                           dcesrv_sock);
2692         if (!NT_STATUS_IS_OK(status)) {
2693                 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2694                          endpoint, nt_errstr(status)));
2695                 return status;
2696         }
2697
2698         return NT_STATUS_OK;
2699 }
2700
2701 /*
2702   add a socket address to the list of events, one event per dcerpc endpoint
2703 */
2704 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2705                                          struct tevent_context *event_ctx, const struct model_ops *model_ops,
2706                                          const char *address)
2707 {
2708         struct dcesrv_socket_context *dcesrv_sock;
2709         uint16_t port = 0;
2710         NTSTATUS status;
2711         const char *endpoint;
2712         char port_str[6];
2713
2714         endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2715         if (endpoint != NULL) {
2716                 port = atoi(endpoint);
2717         }
2718
2719         dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2720         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2721
2722         /* remember the endpoint of this socket */
2723         dcesrv_sock->endpoint           = e;
2724         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
2725
2726         status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2727                                      model_ops, &dcesrv_stream_ops, 
2728                                      "ip", address, &port,
2729                                      lpcfg_socket_options(dce_ctx->lp_ctx),
2730                                      dcesrv_sock);
2731         if (!NT_STATUS_IS_OK(status)) {
2732                 struct dcesrv_if_list *iface;
2733                 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
2734                          address, port));
2735                 for (iface = e->interface_list; iface; iface = iface->next) {
2736                         DEBUGADD(0, ("%s ", iface->iface.name));
2737                 }
2738                 DEBUGADD(0, ("failed - %s",
2739                              nt_errstr(status)));
2740                 return status;
2741         }
2742
2743         snprintf(port_str, sizeof(port_str), "%u", port);
2744
2745         status = dcerpc_binding_set_string_option(e->ep_description,
2746                                                   "endpoint", port_str);
2747         if (!NT_STATUS_IS_OK(status)) {
2748                 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2749                          port_str, nt_errstr(status)));
2750                 return status;
2751         } else {
2752                 struct dcesrv_if_list *iface;
2753                 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
2754                          address, port_str));
2755                 for (iface = e->interface_list; iface; iface = iface->next) {
2756                         DEBUGADD(4, ("%s ", iface->iface.name));
2757                 }
2758                 DEBUGADD(4, ("\n"));
2759         }
2760
2761         return NT_STATUS_OK;
2762 }
2763
2764 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2765
2766 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 
2767                                   struct loadparm_context *lp_ctx,
2768                                   struct dcesrv_endpoint *e,
2769                                   struct tevent_context *event_ctx, const struct model_ops *model_ops)
2770 {
2771         NTSTATUS status;
2772
2773         /* Add TCP/IP sockets */
2774         if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2775                 int num_interfaces;
2776                 int i;
2777                 struct interface *ifaces;
2778
2779                 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2780
2781                 num_interfaces = iface_list_count(ifaces);
2782                 for(i = 0; i < num_interfaces; i++) {
2783                         const char *address = iface_list_n_ip(ifaces, i);
2784                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2785                         NT_STATUS_NOT_OK_RETURN(status);
2786                 }
2787         } else {
2788                 char **wcard;
2789                 int i;
2790                 int num_binds = 0;
2791                 wcard = iface_list_wildcard(dce_ctx);
2792                 NT_STATUS_HAVE_NO_MEMORY(wcard);
2793                 for (i=0; wcard[i]; i++) {
2794                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2795                         if (NT_STATUS_IS_OK(status)) {
2796                                 num_binds++;
2797                         }
2798                 }
2799                 talloc_free(wcard);
2800                 if (num_binds == 0) {
2801                         return NT_STATUS_INVALID_PARAMETER_MIX;
2802                 }
2803         }
2804
2805         return NT_STATUS_OK;
2806 }
2807
2808 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2809                        struct loadparm_context *lp_ctx,
2810                        struct dcesrv_endpoint *e,
2811                        struct tevent_context *event_ctx,
2812                        const struct model_ops *model_ops)
2813 {
2814         enum dcerpc_transport_t transport =
2815                 dcerpc_binding_get_transport(e->ep_description);
2816
2817         switch (transport) {
2818         case NCACN_UNIX_STREAM:
2819                 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2820
2821         case NCALRPC:
2822                 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2823
2824         case NCACN_IP_TCP:
2825                 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2826
2827         case NCACN_NP:
2828                 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2829
2830         default:
2831                 return NT_STATUS_NOT_SUPPORTED;
2832         }
2833 }
2834
2835
2836 /**
2837  * retrieve credentials from a dce_call
2838  */
2839 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2840 {
2841         return dce_call->conn->auth_state.session_info->credentials;
2842 }
2843
2844 /**
2845  * returns true if this is an authenticated call
2846  */
2847 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2848 {
2849         enum security_user_level level;
2850         level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2851         return level >= SECURITY_USER;
2852 }
2853
2854 /**
2855  * retrieve account_name for a dce_call
2856  */
2857 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2858 {
2859         return dce_call->context->conn->auth_state.session_info->info->account_name;
2860 }