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