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