LCOV - code coverage report
Current view: top level - librpc/rpc - dcesrv_core.c (source / functions) Hit Total Coverage
Test: coverage report for vadcx-master-patch-75612 fe003de8 Lines: 1259 1559 80.8 %
Date: 2024-02-29 22:57:05 Functions: 73 77 94.8 %

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

Generated by: LCOV version 1.14