LCOV - code coverage report
Current view: top level - bin/default/librpc/gen_ndr - ndr_initshutdown_scompat.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 32 177 18.1 %
Date: 2021-09-23 10:06:22 Functions: 6 14 42.9 %

          Line data    Source code
       1             : /* s3 compat server functions auto-generated by pidl */
       2             : #include "bin/default/librpc/gen_ndr/ndr_initshutdown.h"
       3             : #include "bin/default/librpc/gen_ndr/ndr_initshutdown_scompat.h"
       4             : #include <librpc/rpc/dcesrv_core.h>
       5             : #include <rpc_server/rpc_config.h>
       6             : #include <rpc_server/rpc_server.h>
       7             : #include <util/debug.h>
       8             : 
       9             : enum s3compat_rpc_dispatch {
      10             :         S3COMPAT_RPC_DISPATCH_EXTERNAL = 0x00000001,
      11             :         S3COMPAT_RPC_DISPATCH_INTERNAL = 0x00000002,
      12             : };
      13             : 
      14             : /* initshutdown - dcerpc server boilerplate generated by pidl */
      15           2 : static NTSTATUS initshutdown__op_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
      16             : {
      17           2 :         struct pipes_struct *p = NULL;
      18             : 
      19             :         /* Retrieve pipes struct */
      20           2 :         p = dcesrv_get_pipes_struct(context->conn);
      21           2 :         p->pipe_bound = true;
      22             : #ifdef DCESRV_INTERFACE_INITSHUTDOWN_BIND
      23             :         return DCESRV_INTERFACE_INITSHUTDOWN_BIND(context,iface);
      24             : #else
      25           2 :         return NT_STATUS_OK;
      26             : #endif
      27             : }
      28             : 
      29           2 : static void initshutdown__op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
      30             : {
      31             : #ifdef DCESRV_INTERFACE_INITSHUTDOWN_UNBIND
      32             :         DCESRV_INTERFACE_INITSHUTDOWN_UNBIND(context, iface);
      33             : #else
      34           2 :         return;
      35             : #endif
      36             : }
      37             : 
      38           0 : NTSTATUS initshutdown__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r)
      39             : {
      40             :         enum ndr_err_code ndr_err;
      41           0 :         uint16_t opnum = dce_call->pkt.u.request.opnum;
      42             : 
      43           0 :         dce_call->fault_code = 0;
      44             : 
      45           0 :         if (opnum >= ndr_table_initshutdown.num_calls) {
      46           0 :                 dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
      47           0 :                 return NT_STATUS_NET_WRITE_FAULT;
      48             :         }
      49             : 
      50           0 :         *r = talloc_named(mem_ctx, ndr_table_initshutdown.calls[opnum].struct_size, "struct %s", ndr_table_initshutdown.calls[opnum].name);
      51           0 :         NT_STATUS_HAVE_NO_MEMORY(*r);
      52             : 
      53             :         /* unravel the NDR for the packet */
      54           0 :         ndr_err = ndr_table_initshutdown.calls[opnum].ndr_pull(pull, NDR_IN, *r);
      55           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
      56           0 :                 dce_call->fault_code = DCERPC_FAULT_NDR;
      57           0 :                 return NT_STATUS_NET_WRITE_FAULT;
      58             :         }
      59             : 
      60           0 :         return NT_STATUS_OK;
      61             : }
      62             : 
      63           0 : static NTSTATUS initshutdown__op_dispatch_internal(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, enum s3compat_rpc_dispatch dispatch)
      64             : {
      65           0 :         uint16_t opnum = dce_call->pkt.u.request.opnum;
      66           0 :         struct pipes_struct *p = NULL;
      67           0 :         struct auth_session_info *pipe_session_info = NULL;
      68           0 :         NTSTATUS status = NT_STATUS_OK;
      69           0 :         bool impersonated = false;
      70             : 
      71             :         /* Retrieve pipes struct */
      72           0 :         p = dcesrv_get_pipes_struct(dce_call->conn);
      73             :         /* Update pipes struct opnum */
      74           0 :         p->opnum = opnum;
      75           0 :         p->dce_call = dce_call;
      76           0 :         p->mem_ctx = mem_ctx;
      77             :         /* Update pipes struct session info */
      78           0 :         pipe_session_info = p->session_info;
      79           0 :         p->session_info = dce_call->auth_state->session_info;
      80           0 :         p->auth.auth_type = dce_call->auth_state->auth_type;
      81           0 :         p->auth.auth_level = dce_call->auth_state->auth_level;
      82           0 :         p->auth.auth_context_id = dce_call->auth_state->auth_context_id;
      83             :         /* Reset pipes struct fault state */
      84           0 :         p->fault_state = 0;
      85             : 
      86             :         /* Impersonate */
      87           0 :         if (dispatch == S3COMPAT_RPC_DISPATCH_EXTERNAL) {
      88           0 :                 impersonated = become_authenticated_pipe_user(p->session_info);
      89           0 :                 if (!impersonated) {
      90           0 :                         dce_call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
      91           0 :                         status = NT_STATUS_NET_WRITE_FAULT;
      92           0 :                         goto fail;
      93             :                 }
      94             :         }
      95             : 
      96           0 :         switch (opnum) {
      97           0 :         case 0: { /* initshutdown_Init */
      98           0 :                 struct initshutdown_Init *r2 = (struct initshutdown_Init *)r;
      99           0 :                 if (DEBUGLEVEL >= 10) {
     100           0 :                         NDR_PRINT_FUNCTION_DEBUG(initshutdown_Init, NDR_IN, r2);
     101             :                 }
     102           0 :                 r2->out.result = _initshutdown_Init(p, r2);
     103           0 :                 break;
     104             :         }
     105           0 :         case 1: { /* initshutdown_Abort */
     106           0 :                 struct initshutdown_Abort *r2 = (struct initshutdown_Abort *)r;
     107           0 :                 if (DEBUGLEVEL >= 10) {
     108           0 :                         NDR_PRINT_FUNCTION_DEBUG(initshutdown_Abort, NDR_IN, r2);
     109             :                 }
     110           0 :                 r2->out.result = _initshutdown_Abort(p, r2);
     111           0 :                 break;
     112             :         }
     113           0 :         case 2: { /* initshutdown_InitEx */
     114           0 :                 struct initshutdown_InitEx *r2 = (struct initshutdown_InitEx *)r;
     115           0 :                 if (DEBUGLEVEL >= 10) {
     116           0 :                         NDR_PRINT_FUNCTION_DEBUG(initshutdown_InitEx, NDR_IN, r2);
     117             :                 }
     118           0 :                 r2->out.result = _initshutdown_InitEx(p, r2);
     119           0 :                 break;
     120             :         }
     121           0 :         default:
     122           0 :                 dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
     123           0 :                 break;
     124             :         }
     125             : 
     126           0 : fail:
     127             :         /* Unimpersonate */
     128           0 :         if (impersonated) {
     129           0 :                 unbecome_authenticated_pipe_user();
     130             :         }
     131             : 
     132           0 :         p->dce_call = NULL;
     133           0 :         p->mem_ctx = NULL;
     134             :         /* Restore session info */
     135           0 :         p->session_info = pipe_session_info;
     136           0 :         p->auth.auth_type = 0;
     137           0 :         p->auth.auth_level = 0;
     138           0 :         p->auth.auth_context_id = 0;
     139             :         /* Check pipes struct fault state */
     140           0 :         if (p->fault_state != 0) {
     141           0 :                 dce_call->fault_code = p->fault_state;
     142             :         }
     143           0 :         if (dce_call->fault_code != 0) {
     144           0 :                 status = NT_STATUS_NET_WRITE_FAULT;
     145             :         }
     146             : 
     147           0 :         return status;
     148             : }
     149             : 
     150           0 : NTSTATUS initshutdown__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
     151             : {
     152           0 :         return initshutdown__op_dispatch_internal(dce_call, mem_ctx, r, S3COMPAT_RPC_DISPATCH_EXTERNAL);
     153             : }
     154             : 
     155           0 : NTSTATUS initshutdown__op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
     156             : {
     157           0 :         uint16_t opnum = dce_call->pkt.u.request.opnum;
     158             : 
     159           0 :         switch (opnum) {
     160           0 :         case 0: { /* initshutdown_Init */
     161           0 :                 struct initshutdown_Init *r2 = (struct initshutdown_Init *)r;
     162           0 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     163           0 :                         DEBUG(5,("function initshutdown_Init replied async\n"));
     164             :                 }
     165           0 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     166           0 :                         NDR_PRINT_FUNCTION_DEBUG(initshutdown_Init, NDR_OUT | NDR_SET_VALUES, r2);
     167             :                 }
     168           0 :                 if (dce_call->fault_code != 0) {
     169           0 :                         DBG_WARNING("dcerpc_fault %s in initshutdown_Init\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     170             :                 }
     171           0 :                 break;
     172             :         }
     173           0 :         case 1: { /* initshutdown_Abort */
     174           0 :                 struct initshutdown_Abort *r2 = (struct initshutdown_Abort *)r;
     175           0 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     176           0 :                         DEBUG(5,("function initshutdown_Abort replied async\n"));
     177             :                 }
     178           0 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     179           0 :                         NDR_PRINT_FUNCTION_DEBUG(initshutdown_Abort, NDR_OUT | NDR_SET_VALUES, r2);
     180             :                 }
     181           0 :                 if (dce_call->fault_code != 0) {
     182           0 :                         DBG_WARNING("dcerpc_fault %s in initshutdown_Abort\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     183             :                 }
     184           0 :                 break;
     185             :         }
     186           0 :         case 2: { /* initshutdown_InitEx */
     187           0 :                 struct initshutdown_InitEx *r2 = (struct initshutdown_InitEx *)r;
     188           0 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     189           0 :                         DEBUG(5,("function initshutdown_InitEx replied async\n"));
     190             :                 }
     191           0 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     192           0 :                         NDR_PRINT_FUNCTION_DEBUG(initshutdown_InitEx, NDR_OUT | NDR_SET_VALUES, r2);
     193             :                 }
     194           0 :                 if (dce_call->fault_code != 0) {
     195           0 :                         DBG_WARNING("dcerpc_fault %s in initshutdown_InitEx\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     196             :                 }
     197           0 :                 break;
     198             :         }
     199           0 :         default:
     200           0 :                 dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
     201           0 :                 break;
     202             :         }
     203             : 
     204           0 :         if (dce_call->fault_code != 0) {
     205           0 :                 return NT_STATUS_NET_WRITE_FAULT;
     206             :         }
     207             : 
     208           0 :         return NT_STATUS_OK;
     209             : }
     210             : 
     211           0 : NTSTATUS initshutdown__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, const void *r)
     212             : {
     213             :         enum ndr_err_code ndr_err;
     214           0 :         uint16_t opnum = dce_call->pkt.u.request.opnum;
     215             : 
     216           0 :         ndr_err = ndr_table_initshutdown.calls[opnum].ndr_push(push, NDR_OUT, r);
     217           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     218           0 :                 dce_call->fault_code = DCERPC_FAULT_NDR;
     219           0 :                 return NT_STATUS_NET_WRITE_FAULT;
     220             :         }
     221             : 
     222           0 :         return NT_STATUS_OK;
     223             : }
     224             : 
     225           0 : NTSTATUS initshutdown__op_local(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
     226             : {
     227           0 :         return initshutdown__op_dispatch_internal(dce_call, mem_ctx, r, S3COMPAT_RPC_DISPATCH_INTERNAL);
     228             : }
     229             : 
     230             : static const struct dcesrv_interface dcesrv_initshutdown_interface = {
     231             :         .name      = "initshutdown",
     232             :         .syntax_id = {{0x894de0c0,0x0d55,0x11d3,{0xa3,0x22},{0x00,0xc0,0x4f,0xa3,0x21,0xa1}},1.0},
     233             :         .bind      = initshutdown__op_bind,
     234             :         .unbind    = initshutdown__op_unbind,
     235             :         .ndr_pull  = initshutdown__op_ndr_pull,
     236             :         .dispatch  = initshutdown__op_dispatch,
     237             :         .reply     = initshutdown__op_reply,
     238             :         .ndr_push  = initshutdown__op_ndr_push,
     239             :         .local     = initshutdown__op_local,
     240             : #ifdef DCESRV_INTERFACE_INITSHUTDOWN_FLAGS
     241             :         .flags     = DCESRV_INTERFACE_INITSHUTDOWN_FLAGS
     242             : #else
     243             :         .flags     = 0
     244             : #endif
     245             : };
     246             : 
     247          28 : static NTSTATUS initshutdown__check_register_in_endpoint(const char *name, struct dcerpc_binding *binding) {
     248          28 :         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(binding);
     249             :         NTSTATUS status;
     250             : 
     251             :         /* If service is disabled, do not register */
     252          28 :         if (rpc_service_mode(name) == RPC_SERVICE_MODE_DISABLED) {
     253           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
     254             :         }
     255             : 
     256             :         /* If service is embedded, register only for ncacn_np
     257             :          * see 8466b3c85e4b835e57e41776853093f4a0edc8b8
     258             :          */
     259          28 :         if (rpc_service_mode(name) == RPC_SERVICE_MODE_EMBEDDED && (transport != NCACN_NP && transport != NCALRPC)) {
     260           0 :                 DBG_INFO("Interface 'initshutdown' not registered in endpoint '%s' as service is embedded\n", name);
     261           0 :                 return NT_STATUS_NOT_SUPPORTED;
     262             :         }
     263             : 
     264             :         /*
     265             :          * If rpc service is external then change the default ncalrpc endpoint,
     266             :          * otherwise if the rpc daemon running this service is configured in
     267             :          * fork mode the forked process will race with main smbd to accept the
     268             :          * connections in the default ncalrpc socket, and the forked process
     269             :          * may not have the requested interface registered.
     270             :          * For example, in the ad_member test environment:
     271             :          *
     272             :          *   rpc_server:lsarpc = external
     273             :          *   rpc_server:samr = external
     274             :          *   rpc_server:netlogon = disabled
     275             :          *   rpc_daemon:lsasd = fork
     276             :          *
     277             :          * With these settings both, the main smbd and all the preforked lsasd
     278             :          * processes would be listening in the default ncalrpc socket if it is
     279             :          * not changed. If a client connection is accepted by one of the lsasd
     280             :          * worker processes and the client asks for an interface not registered
     281             :          * in these processes (winreg for example) it will get an error.
     282             :          */
     283          28 :         if (rpc_service_mode(name) == RPC_SERVICE_MODE_EXTERNAL && transport == NCALRPC) {
     284           0 :                 status = dcerpc_binding_set_string_option(binding, "endpoint", "INITSHUTDOWN");
     285           0 :                 if (!NT_STATUS_IS_OK(status)) {
     286           0 :                         return status;
     287             :                 }
     288             :         }
     289             : 
     290          28 :         return NT_STATUS_OK;
     291             : }
     292             : 
     293          28 : static NTSTATUS initshutdown__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
     294             : {
     295             :         uint32_t i;
     296             :         NTSTATUS ret;
     297             :         struct dcerpc_binding *binding;
     298          28 :         struct dcerpc_binding *binding2 = NULL;
     299             : 
     300             : #ifdef DCESRV_INTERFACE_INITSHUTDOWN_NCACN_NP_SECONDARY_ENDPOINT
     301             :         const char *ncacn_np_secondary_endpoint = DCESRV_INTERFACE_INITSHUTDOWN_NCACN_NP_SECONDARY_ENDPOINT;
     302             : #else
     303          28 :         const char *ncacn_np_secondary_endpoint = NULL;
     304             : #endif
     305             : 
     306          56 :         for (i=0;i<ndr_table_initshutdown.endpoints->count;i++) {
     307          28 :                 const char *name = ndr_table_initshutdown.endpoints->names[i];
     308             : 
     309          28 :                 ret = dcerpc_parse_binding(dce_ctx, name, &binding);
     310          28 :                 if (NT_STATUS_IS_ERR(ret)) {
     311           0 :                         DBG_ERR("Failed to parse binding string '%s'\n", name);
     312           0 :                         return ret;
     313             :                 }
     314             : 
     315          28 :                 ret = initshutdown__check_register_in_endpoint("initshutdown", binding);
     316          28 :                 if (NT_STATUS_IS_ERR(ret)) {
     317           0 :                         talloc_free(binding);
     318           0 :                         continue;
     319             :                 }
     320             : 
     321          28 :                 if (ncacn_np_secondary_endpoint != NULL) {
     322           0 :                         ret = dcerpc_parse_binding(dce_ctx, ncacn_np_secondary_endpoint, &binding2);
     323           0 :                         if (NT_STATUS_IS_ERR(ret)) {
     324           0 :                                 DBG_ERR("Failed to parse 2nd binding string '%s'\n", ncacn_np_secondary_endpoint);
     325           0 :                                 TALLOC_FREE(binding);
     326           0 :                                 return ret;
     327             :                         }
     328             :                 }
     329             : 
     330          28 :                 ret = dcesrv_interface_register_b(dce_ctx, binding, binding2, &dcesrv_initshutdown_interface, NULL);
     331          28 :                 TALLOC_FREE(binding);
     332          28 :                 TALLOC_FREE(binding2);
     333          28 :                 if (!NT_STATUS_IS_OK(ret)) {
     334           0 :                         DBG_ERR("Failed to register endpoint '%s'\n",name);
     335           0 :                         return ret;
     336             :                 }
     337             :         }
     338             : 
     339          28 :         return NT_STATUS_OK;
     340             : }
     341             : 
     342          19 : static NTSTATUS initshutdown__op_shutdown_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
     343             : {
     344          19 :         return NT_STATUS_OK;
     345             : }
     346             : 
     347           0 : static bool initshutdown__op_interface_by_uuid(struct dcesrv_interface *iface, const struct GUID *uuid, uint32_t if_version)
     348             : {
     349           0 :         if (dcesrv_initshutdown_interface.syntax_id.if_version == if_version && GUID_equal(&dcesrv_initshutdown_interface.syntax_id.uuid, uuid)) {
     350           0 :                 memcpy(iface,&dcesrv_initshutdown_interface, sizeof(*iface));
     351           0 :                 return true;
     352             :         }
     353             : 
     354           0 :         return false;
     355             : }
     356             : 
     357           0 : static bool initshutdown__op_interface_by_name(struct dcesrv_interface *iface, const char *name)
     358             : {
     359           0 :         if (strcmp(dcesrv_initshutdown_interface.name, name)==0) {
     360           0 :                 memcpy(iface, &dcesrv_initshutdown_interface, sizeof(*iface));
     361           0 :                 return true;
     362             :         }
     363             : 
     364           0 :         return false;
     365             : }
     366             : 
     367             : static const struct dcesrv_endpoint_server initshutdown_ep_server = {
     368             :         /* fill in our name */
     369             :         .name = "initshutdown",
     370             : 
     371             :         /* Initialization flag */
     372             :         .initialized = false,
     373             : 
     374             :         /* fill in all the operations */
     375             : #ifdef DCESRV_INTERFACE_INITSHUTDOWN_INIT_SERVER
     376             :         .init_server = DCESRV_INTERFACE_INITSHUTDOWN_INIT_SERVER,
     377             : #else
     378             :         .init_server = initshutdown__op_init_server,
     379             : #endif
     380             : #ifdef DCESRV_INTERFACE_INITSHUTDOWN_SHUTDOWN_SERVER
     381             :         .shutdown_server = DCESRV_INTERFACE_INITSHUTDOWN_SHUTDOWN_SERVER,
     382             : #else
     383             :         .shutdown_server = initshutdown__op_shutdown_server,
     384             : #endif
     385             :         .interface_by_uuid = initshutdown__op_interface_by_uuid,
     386             :         .interface_by_name = initshutdown__op_interface_by_name
     387             : };
     388             : 
     389          60 : const struct dcesrv_endpoint_server *initshutdown_get_ep_server(void)
     390             : {
     391          60 :         return &initshutdown_ep_server;
     392             : }

Generated by: LCOV version 1.13