LCOV - code coverage report
Current view: top level - bin/default/librpc/gen_ndr - ndr_echo_scompat.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 181 318 56.9 %
Date: 2021-09-23 10:06:22 Functions: 11 14 78.6 %

          Line data    Source code
       1             : /* s3 compat server functions auto-generated by pidl */
       2             : #include "bin/default/librpc/gen_ndr/ndr_echo.h"
       3             : #include "bin/default/librpc/gen_ndr/ndr_echo_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             : /* rpcecho - dcerpc server boilerplate generated by pidl */
      15           2 : static NTSTATUS rpcecho__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_RPCECHO_BIND
      23             :         return DCESRV_INTERFACE_RPCECHO_BIND(context,iface);
      24             : #else
      25           2 :         return NT_STATUS_OK;
      26             : #endif
      27             : }
      28             : 
      29           2 : static void rpcecho__op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
      30             : {
      31             : #ifdef DCESRV_INTERFACE_RPCECHO_UNBIND
      32             :         DCESRV_INTERFACE_RPCECHO_UNBIND(context, iface);
      33             : #else
      34           2 :         return;
      35             : #endif
      36             : }
      37             : 
      38          44 : NTSTATUS rpcecho__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          44 :         uint16_t opnum = dce_call->pkt.u.request.opnum;
      42             : 
      43          44 :         dce_call->fault_code = 0;
      44             : 
      45          44 :         if (opnum >= ndr_table_rpcecho.num_calls) {
      46           0 :                 dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
      47           0 :                 return NT_STATUS_NET_WRITE_FAULT;
      48             :         }
      49             : 
      50          44 :         *r = talloc_named(mem_ctx, ndr_table_rpcecho.calls[opnum].struct_size, "struct %s", ndr_table_rpcecho.calls[opnum].name);
      51          44 :         NT_STATUS_HAVE_NO_MEMORY(*r);
      52             : 
      53             :         /* unravel the NDR for the packet */
      54          44 :         ndr_err = ndr_table_rpcecho.calls[opnum].ndr_pull(pull, NDR_IN, *r);
      55          44 :         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          44 :         return NT_STATUS_OK;
      61             : }
      62             : 
      63          44 : static NTSTATUS rpcecho__op_dispatch_internal(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, enum s3compat_rpc_dispatch dispatch)
      64             : {
      65          44 :         uint16_t opnum = dce_call->pkt.u.request.opnum;
      66          44 :         struct pipes_struct *p = NULL;
      67          44 :         struct auth_session_info *pipe_session_info = NULL;
      68          44 :         NTSTATUS status = NT_STATUS_OK;
      69          44 :         bool impersonated = false;
      70             : 
      71             :         /* Retrieve pipes struct */
      72          44 :         p = dcesrv_get_pipes_struct(dce_call->conn);
      73             :         /* Update pipes struct opnum */
      74          44 :         p->opnum = opnum;
      75          44 :         p->dce_call = dce_call;
      76          44 :         p->mem_ctx = mem_ctx;
      77             :         /* Update pipes struct session info */
      78          44 :         pipe_session_info = p->session_info;
      79          44 :         p->session_info = dce_call->auth_state->session_info;
      80          44 :         p->auth.auth_type = dce_call->auth_state->auth_type;
      81          44 :         p->auth.auth_level = dce_call->auth_state->auth_level;
      82          44 :         p->auth.auth_context_id = dce_call->auth_state->auth_context_id;
      83             :         /* Reset pipes struct fault state */
      84          44 :         p->fault_state = 0;
      85             : 
      86             :         /* Impersonate */
      87          44 :         if (dispatch == S3COMPAT_RPC_DISPATCH_EXTERNAL) {
      88          44 :                 impersonated = become_authenticated_pipe_user(p->session_info);
      89          44 :                 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          44 :         switch (opnum) {
      97          28 :         case 0: { /* echo_AddOne */
      98          28 :                 struct echo_AddOne *r2 = (struct echo_AddOne *)r;
      99          28 :                 if (DEBUGLEVEL >= 10) {
     100           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_AddOne, NDR_IN, r2);
     101             :                 }
     102          28 :                 NDR_ZERO_STRUCT(r2->out);
     103          28 :                 r2->out.out_data = talloc_zero(r2, uint32_t);
     104          28 :                 if (r2->out.out_data == NULL) {
     105           0 :                         status = NT_STATUS_NO_MEMORY;
     106           0 :                         p->fault_state = DCERPC_FAULT_CANT_PERFORM;
     107           0 :                         goto fail;
     108             :                 }
     109             : 
     110          28 :                 _echo_AddOne(p, r2);
     111          28 :                 break;
     112             :         }
     113           2 :         case 1: { /* echo_EchoData */
     114           2 :                 struct echo_EchoData *r2 = (struct echo_EchoData *)r;
     115           2 :                 if (DEBUGLEVEL >= 10) {
     116           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_EchoData, NDR_IN, r2);
     117             :                 }
     118           2 :                 NDR_ZERO_STRUCT(r2->out);
     119           2 :                 r2->out.out_data = talloc_zero_array(r2, uint8_t, r2->in.len);
     120           2 :                 if (r2->out.out_data == NULL) {
     121           0 :                         status = NT_STATUS_NO_MEMORY;
     122           0 :                         p->fault_state = DCERPC_FAULT_CANT_PERFORM;
     123           0 :                         goto fail;
     124             :                 }
     125             : 
     126           2 :                 _echo_EchoData(p, r2);
     127           2 :                 break;
     128             :         }
     129           2 :         case 2: { /* echo_SinkData */
     130           2 :                 struct echo_SinkData *r2 = (struct echo_SinkData *)r;
     131           2 :                 if (DEBUGLEVEL >= 10) {
     132           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_SinkData, NDR_IN, r2);
     133             :                 }
     134           2 :                 _echo_SinkData(p, r2);
     135           2 :                 break;
     136             :         }
     137           2 :         case 3: { /* echo_SourceData */
     138           2 :                 struct echo_SourceData *r2 = (struct echo_SourceData *)r;
     139           2 :                 if (DEBUGLEVEL >= 10) {
     140           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_SourceData, NDR_IN, r2);
     141             :                 }
     142           2 :                 NDR_ZERO_STRUCT(r2->out);
     143           2 :                 r2->out.data = talloc_zero_array(r2, uint8_t, r2->in.len);
     144           2 :                 if (r2->out.data == NULL) {
     145           0 :                         status = NT_STATUS_NO_MEMORY;
     146           0 :                         p->fault_state = DCERPC_FAULT_CANT_PERFORM;
     147           0 :                         goto fail;
     148             :                 }
     149             : 
     150           2 :                 _echo_SourceData(p, r2);
     151           2 :                 break;
     152             :         }
     153           2 :         case 4: { /* echo_TestCall */
     154           2 :                 struct echo_TestCall *r2 = (struct echo_TestCall *)r;
     155           2 :                 if (DEBUGLEVEL >= 10) {
     156           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_TestCall, NDR_IN, r2);
     157             :                 }
     158           2 :                 NDR_ZERO_STRUCT(r2->out);
     159           2 :                 r2->out.s2 = talloc_zero(r2, const char *);
     160           2 :                 if (r2->out.s2 == NULL) {
     161           0 :                         status = NT_STATUS_NO_MEMORY;
     162           0 :                         p->fault_state = DCERPC_FAULT_CANT_PERFORM;
     163           0 :                         goto fail;
     164             :                 }
     165             : 
     166           2 :                 _echo_TestCall(p, r2);
     167           2 :                 break;
     168             :         }
     169           2 :         case 5: { /* echo_TestCall2 */
     170           2 :                 struct echo_TestCall2 *r2 = (struct echo_TestCall2 *)r;
     171           2 :                 if (DEBUGLEVEL >= 10) {
     172           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_TestCall2, NDR_IN, r2);
     173             :                 }
     174           2 :                 NDR_ZERO_STRUCT(r2->out);
     175           2 :                 r2->out.info = talloc_zero(r2, union echo_Info);
     176           2 :                 if (r2->out.info == NULL) {
     177           0 :                         status = NT_STATUS_NO_MEMORY;
     178           0 :                         p->fault_state = DCERPC_FAULT_CANT_PERFORM;
     179           0 :                         goto fail;
     180             :                 }
     181             : 
     182           2 :                 r2->out.result = _echo_TestCall2(p, r2);
     183           2 :                 break;
     184             :         }
     185           0 :         case 6: { /* echo_TestSleep */
     186           0 :                 struct echo_TestSleep *r2 = (struct echo_TestSleep *)r;
     187           0 :                 if (DEBUGLEVEL >= 10) {
     188           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_TestSleep, NDR_IN, r2);
     189             :                 }
     190           0 :                 r2->out.result = _echo_TestSleep(p, r2);
     191           0 :                 break;
     192             :         }
     193           2 :         case 7: { /* echo_TestEnum */
     194           2 :                 struct echo_TestEnum *r2 = (struct echo_TestEnum *)r;
     195           2 :                 if (DEBUGLEVEL >= 10) {
     196           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_TestEnum, NDR_IN, r2);
     197             :                 }
     198           2 :                 NDR_ZERO_STRUCT(r2->out);
     199           2 :                 r2->out.foo1 = r2->in.foo1;
     200           2 :                 r2->out.foo2 = r2->in.foo2;
     201           2 :                 r2->out.foo3 = r2->in.foo3;
     202           2 :                 _echo_TestEnum(p, r2);
     203           2 :                 break;
     204             :         }
     205           2 :         case 8: { /* echo_TestSurrounding */
     206           2 :                 struct echo_TestSurrounding *r2 = (struct echo_TestSurrounding *)r;
     207           2 :                 if (DEBUGLEVEL >= 10) {
     208           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_TestSurrounding, NDR_IN, r2);
     209             :                 }
     210           2 :                 NDR_ZERO_STRUCT(r2->out);
     211           2 :                 r2->out.data = r2->in.data;
     212           2 :                 _echo_TestSurrounding(p, r2);
     213           2 :                 break;
     214             :         }
     215           2 :         case 9: { /* echo_TestDoublePointer */
     216           2 :                 struct echo_TestDoublePointer *r2 = (struct echo_TestDoublePointer *)r;
     217           2 :                 if (DEBUGLEVEL >= 10) {
     218           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_TestDoublePointer, NDR_IN, r2);
     219             :                 }
     220           2 :                 r2->out.result = _echo_TestDoublePointer(p, r2);
     221           2 :                 break;
     222             :         }
     223           0 :         default:
     224           0 :                 dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
     225           0 :                 break;
     226             :         }
     227             : 
     228          44 : fail:
     229             :         /* Unimpersonate */
     230          44 :         if (impersonated) {
     231          44 :                 unbecome_authenticated_pipe_user();
     232             :         }
     233             : 
     234          44 :         p->dce_call = NULL;
     235          44 :         p->mem_ctx = NULL;
     236             :         /* Restore session info */
     237          44 :         p->session_info = pipe_session_info;
     238          44 :         p->auth.auth_type = 0;
     239          44 :         p->auth.auth_level = 0;
     240          44 :         p->auth.auth_context_id = 0;
     241             :         /* Check pipes struct fault state */
     242          44 :         if (p->fault_state != 0) {
     243          10 :                 dce_call->fault_code = p->fault_state;
     244             :         }
     245          44 :         if (dce_call->fault_code != 0) {
     246          10 :                 status = NT_STATUS_NET_WRITE_FAULT;
     247             :         }
     248             : 
     249          44 :         return status;
     250             : }
     251             : 
     252          44 : NTSTATUS rpcecho__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
     253             : {
     254          44 :         return rpcecho__op_dispatch_internal(dce_call, mem_ctx, r, S3COMPAT_RPC_DISPATCH_EXTERNAL);
     255             : }
     256             : 
     257          34 : NTSTATUS rpcecho__op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
     258             : {
     259          34 :         uint16_t opnum = dce_call->pkt.u.request.opnum;
     260             : 
     261          34 :         switch (opnum) {
     262          28 :         case 0: { /* echo_AddOne */
     263          28 :                 struct echo_AddOne *r2 = (struct echo_AddOne *)r;
     264          28 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     265           0 :                         DEBUG(5,("function echo_AddOne replied async\n"));
     266             :                 }
     267          28 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     268           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_AddOne, NDR_OUT | NDR_SET_VALUES, r2);
     269             :                 }
     270          28 :                 if (dce_call->fault_code != 0) {
     271           0 :                         DBG_WARNING("dcerpc_fault %s in echo_AddOne\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     272             :                 }
     273          28 :                 break;
     274             :         }
     275           2 :         case 1: { /* echo_EchoData */
     276           2 :                 struct echo_EchoData *r2 = (struct echo_EchoData *)r;
     277           2 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     278           0 :                         DEBUG(5,("function echo_EchoData replied async\n"));
     279             :                 }
     280           2 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     281           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_EchoData, NDR_OUT | NDR_SET_VALUES, r2);
     282             :                 }
     283           2 :                 if (dce_call->fault_code != 0) {
     284           0 :                         DBG_WARNING("dcerpc_fault %s in echo_EchoData\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     285             :                 }
     286           2 :                 break;
     287             :         }
     288           2 :         case 2: { /* echo_SinkData */
     289           2 :                 struct echo_SinkData *r2 = (struct echo_SinkData *)r;
     290           2 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     291           0 :                         DEBUG(5,("function echo_SinkData replied async\n"));
     292             :                 }
     293           2 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     294           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_SinkData, NDR_OUT | NDR_SET_VALUES, r2);
     295             :                 }
     296           2 :                 if (dce_call->fault_code != 0) {
     297           0 :                         DBG_WARNING("dcerpc_fault %s in echo_SinkData\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     298             :                 }
     299           2 :                 break;
     300             :         }
     301           2 :         case 3: { /* echo_SourceData */
     302           2 :                 struct echo_SourceData *r2 = (struct echo_SourceData *)r;
     303           2 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     304           0 :                         DEBUG(5,("function echo_SourceData replied async\n"));
     305             :                 }
     306           2 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     307           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_SourceData, NDR_OUT | NDR_SET_VALUES, r2);
     308             :                 }
     309           2 :                 if (dce_call->fault_code != 0) {
     310           0 :                         DBG_WARNING("dcerpc_fault %s in echo_SourceData\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     311             :                 }
     312           2 :                 break;
     313             :         }
     314           0 :         case 4: { /* echo_TestCall */
     315           0 :                 struct echo_TestCall *r2 = (struct echo_TestCall *)r;
     316           0 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     317           0 :                         DEBUG(5,("function echo_TestCall replied async\n"));
     318             :                 }
     319           0 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     320           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_TestCall, NDR_OUT | NDR_SET_VALUES, r2);
     321             :                 }
     322           0 :                 if (dce_call->fault_code != 0) {
     323           0 :                         DBG_WARNING("dcerpc_fault %s in echo_TestCall\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     324             :                 }
     325           0 :                 break;
     326             :         }
     327           0 :         case 5: { /* echo_TestCall2 */
     328           0 :                 struct echo_TestCall2 *r2 = (struct echo_TestCall2 *)r;
     329           0 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     330           0 :                         DEBUG(5,("function echo_TestCall2 replied async\n"));
     331             :                 }
     332           0 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     333           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_TestCall2, NDR_OUT | NDR_SET_VALUES, r2);
     334             :                 }
     335           0 :                 if (dce_call->fault_code != 0) {
     336           0 :                         DBG_WARNING("dcerpc_fault %s in echo_TestCall2\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     337             :                 }
     338           0 :                 break;
     339             :         }
     340           0 :         case 6: { /* echo_TestSleep */
     341           0 :                 struct echo_TestSleep *r2 = (struct echo_TestSleep *)r;
     342           0 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     343           0 :                         DEBUG(5,("function echo_TestSleep replied async\n"));
     344             :                 }
     345           0 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     346           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_TestSleep, NDR_OUT | NDR_SET_VALUES, r2);
     347             :                 }
     348           0 :                 if (dce_call->fault_code != 0) {
     349           0 :                         DBG_WARNING("dcerpc_fault %s in echo_TestSleep\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     350             :                 }
     351           0 :                 break;
     352             :         }
     353           0 :         case 7: { /* echo_TestEnum */
     354           0 :                 struct echo_TestEnum *r2 = (struct echo_TestEnum *)r;
     355           0 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     356           0 :                         DEBUG(5,("function echo_TestEnum replied async\n"));
     357             :                 }
     358           0 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     359           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_TestEnum, NDR_OUT | NDR_SET_VALUES, r2);
     360             :                 }
     361           0 :                 if (dce_call->fault_code != 0) {
     362           0 :                         DBG_WARNING("dcerpc_fault %s in echo_TestEnum\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     363             :                 }
     364           0 :                 break;
     365             :         }
     366           0 :         case 8: { /* echo_TestSurrounding */
     367           0 :                 struct echo_TestSurrounding *r2 = (struct echo_TestSurrounding *)r;
     368           0 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     369           0 :                         DEBUG(5,("function echo_TestSurrounding replied async\n"));
     370             :                 }
     371           0 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     372           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_TestSurrounding, NDR_OUT | NDR_SET_VALUES, r2);
     373             :                 }
     374           0 :                 if (dce_call->fault_code != 0) {
     375           0 :                         DBG_WARNING("dcerpc_fault %s in echo_TestSurrounding\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     376             :                 }
     377           0 :                 break;
     378             :         }
     379           0 :         case 9: { /* echo_TestDoublePointer */
     380           0 :                 struct echo_TestDoublePointer *r2 = (struct echo_TestDoublePointer *)r;
     381           0 :                 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     382           0 :                         DEBUG(5,("function echo_TestDoublePointer replied async\n"));
     383             :                 }
     384           0 :                 if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
     385           0 :                         NDR_PRINT_FUNCTION_DEBUG(echo_TestDoublePointer, NDR_OUT | NDR_SET_VALUES, r2);
     386             :                 }
     387           0 :                 if (dce_call->fault_code != 0) {
     388           0 :                         DBG_WARNING("dcerpc_fault %s in echo_TestDoublePointer\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
     389             :                 }
     390           0 :                 break;
     391             :         }
     392           0 :         default:
     393           0 :                 dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
     394           0 :                 break;
     395             :         }
     396             : 
     397          34 :         if (dce_call->fault_code != 0) {
     398           0 :                 return NT_STATUS_NET_WRITE_FAULT;
     399             :         }
     400             : 
     401          34 :         return NT_STATUS_OK;
     402             : }
     403             : 
     404          34 : NTSTATUS rpcecho__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, const void *r)
     405             : {
     406             :         enum ndr_err_code ndr_err;
     407          34 :         uint16_t opnum = dce_call->pkt.u.request.opnum;
     408             : 
     409          34 :         ndr_err = ndr_table_rpcecho.calls[opnum].ndr_push(push, NDR_OUT, r);
     410          34 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     411           0 :                 dce_call->fault_code = DCERPC_FAULT_NDR;
     412           0 :                 return NT_STATUS_NET_WRITE_FAULT;
     413             :         }
     414             : 
     415          34 :         return NT_STATUS_OK;
     416             : }
     417             : 
     418           0 : NTSTATUS rpcecho__op_local(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
     419             : {
     420           0 :         return rpcecho__op_dispatch_internal(dce_call, mem_ctx, r, S3COMPAT_RPC_DISPATCH_INTERNAL);
     421             : }
     422             : 
     423             : static const struct dcesrv_interface dcesrv_rpcecho_interface = {
     424             :         .name      = "rpcecho",
     425             :         .syntax_id = {{0x60a15ec5,0x4de8,0x11d7,{0xa6,0x37},{0x00,0x50,0x56,0xa2,0x01,0x82}},1.0},
     426             :         .bind      = rpcecho__op_bind,
     427             :         .unbind    = rpcecho__op_unbind,
     428             :         .ndr_pull  = rpcecho__op_ndr_pull,
     429             :         .dispatch  = rpcecho__op_dispatch,
     430             :         .reply     = rpcecho__op_reply,
     431             :         .ndr_push  = rpcecho__op_ndr_push,
     432             :         .local     = rpcecho__op_local,
     433             : #ifdef DCESRV_INTERFACE_RPCECHO_FLAGS
     434             :         .flags     = DCESRV_INTERFACE_RPCECHO_FLAGS
     435             : #else
     436             :         .flags     = 0
     437             : #endif
     438             : };
     439             : 
     440          84 : static NTSTATUS rpcecho__check_register_in_endpoint(const char *name, struct dcerpc_binding *binding) {
     441          84 :         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(binding);
     442             :         NTSTATUS status;
     443             : 
     444             :         /* If service is disabled, do not register */
     445          84 :         if (rpc_service_mode(name) == RPC_SERVICE_MODE_DISABLED) {
     446           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
     447             :         }
     448             : 
     449             :         /* If service is embedded, register only for ncacn_np
     450             :          * see 8466b3c85e4b835e57e41776853093f4a0edc8b8
     451             :          */
     452          84 :         if (rpc_service_mode(name) == RPC_SERVICE_MODE_EMBEDDED && (transport != NCACN_NP && transport != NCALRPC)) {
     453          28 :                 DBG_INFO("Interface 'rpcecho' not registered in endpoint '%s' as service is embedded\n", name);
     454          28 :                 return NT_STATUS_NOT_SUPPORTED;
     455             :         }
     456             : 
     457             :         /*
     458             :          * If rpc service is external then change the default ncalrpc endpoint,
     459             :          * otherwise if the rpc daemon running this service is configured in
     460             :          * fork mode the forked process will race with main smbd to accept the
     461             :          * connections in the default ncalrpc socket, and the forked process
     462             :          * may not have the requested interface registered.
     463             :          * For example, in the ad_member test environment:
     464             :          *
     465             :          *   rpc_server:lsarpc = external
     466             :          *   rpc_server:samr = external
     467             :          *   rpc_server:netlogon = disabled
     468             :          *   rpc_daemon:lsasd = fork
     469             :          *
     470             :          * With these settings both, the main smbd and all the preforked lsasd
     471             :          * processes would be listening in the default ncalrpc socket if it is
     472             :          * not changed. If a client connection is accepted by one of the lsasd
     473             :          * worker processes and the client asks for an interface not registered
     474             :          * in these processes (winreg for example) it will get an error.
     475             :          */
     476          56 :         if (rpc_service_mode(name) == RPC_SERVICE_MODE_EXTERNAL && transport == NCALRPC) {
     477           0 :                 status = dcerpc_binding_set_string_option(binding, "endpoint", "RPCECHO");
     478           0 :                 if (!NT_STATUS_IS_OK(status)) {
     479           0 :                         return status;
     480             :                 }
     481             :         }
     482             : 
     483          56 :         return NT_STATUS_OK;
     484             : }
     485             : 
     486          28 : static NTSTATUS rpcecho__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
     487             : {
     488             :         uint32_t i;
     489             :         NTSTATUS ret;
     490             :         struct dcerpc_binding *binding;
     491          28 :         struct dcerpc_binding *binding2 = NULL;
     492             : 
     493             : #ifdef DCESRV_INTERFACE_RPCECHO_NCACN_NP_SECONDARY_ENDPOINT
     494             :         const char *ncacn_np_secondary_endpoint = DCESRV_INTERFACE_RPCECHO_NCACN_NP_SECONDARY_ENDPOINT;
     495             : #else
     496          28 :         const char *ncacn_np_secondary_endpoint = NULL;
     497             : #endif
     498             : 
     499         112 :         for (i=0;i<ndr_table_rpcecho.endpoints->count;i++) {
     500          84 :                 const char *name = ndr_table_rpcecho.endpoints->names[i];
     501             : 
     502          84 :                 ret = dcerpc_parse_binding(dce_ctx, name, &binding);
     503          84 :                 if (NT_STATUS_IS_ERR(ret)) {
     504           0 :                         DBG_ERR("Failed to parse binding string '%s'\n", name);
     505           0 :                         return ret;
     506             :                 }
     507             : 
     508          84 :                 ret = rpcecho__check_register_in_endpoint("rpcecho", binding);
     509          84 :                 if (NT_STATUS_IS_ERR(ret)) {
     510          28 :                         talloc_free(binding);
     511          28 :                         continue;
     512             :                 }
     513             : 
     514          56 :                 if (ncacn_np_secondary_endpoint != NULL) {
     515           0 :                         ret = dcerpc_parse_binding(dce_ctx, ncacn_np_secondary_endpoint, &binding2);
     516           0 :                         if (NT_STATUS_IS_ERR(ret)) {
     517           0 :                                 DBG_ERR("Failed to parse 2nd binding string '%s'\n", ncacn_np_secondary_endpoint);
     518           0 :                                 TALLOC_FREE(binding);
     519           0 :                                 return ret;
     520             :                         }
     521             :                 }
     522             : 
     523          56 :                 ret = dcesrv_interface_register_b(dce_ctx, binding, binding2, &dcesrv_rpcecho_interface, NULL);
     524          56 :                 TALLOC_FREE(binding);
     525          56 :                 TALLOC_FREE(binding2);
     526          56 :                 if (!NT_STATUS_IS_OK(ret)) {
     527           0 :                         DBG_ERR("Failed to register endpoint '%s'\n",name);
     528           0 :                         return ret;
     529             :                 }
     530             :         }
     531             : 
     532          28 :         return NT_STATUS_OK;
     533             : }
     534             : 
     535          19 : static NTSTATUS rpcecho__op_shutdown_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
     536             : {
     537          19 :         return NT_STATUS_OK;
     538             : }
     539             : 
     540           0 : static bool rpcecho__op_interface_by_uuid(struct dcesrv_interface *iface, const struct GUID *uuid, uint32_t if_version)
     541             : {
     542           0 :         if (dcesrv_rpcecho_interface.syntax_id.if_version == if_version && GUID_equal(&dcesrv_rpcecho_interface.syntax_id.uuid, uuid)) {
     543           0 :                 memcpy(iface,&dcesrv_rpcecho_interface, sizeof(*iface));
     544           0 :                 return true;
     545             :         }
     546             : 
     547           0 :         return false;
     548             : }
     549             : 
     550           0 : static bool rpcecho__op_interface_by_name(struct dcesrv_interface *iface, const char *name)
     551             : {
     552           0 :         if (strcmp(dcesrv_rpcecho_interface.name, name)==0) {
     553           0 :                 memcpy(iface, &dcesrv_rpcecho_interface, sizeof(*iface));
     554           0 :                 return true;
     555             :         }
     556             : 
     557           0 :         return false;
     558             : }
     559             : 
     560             : static const struct dcesrv_endpoint_server rpcecho_ep_server = {
     561             :         /* fill in our name */
     562             :         .name = "rpcecho",
     563             : 
     564             :         /* Initialization flag */
     565             :         .initialized = false,
     566             : 
     567             :         /* fill in all the operations */
     568             : #ifdef DCESRV_INTERFACE_RPCECHO_INIT_SERVER
     569             :         .init_server = DCESRV_INTERFACE_RPCECHO_INIT_SERVER,
     570             : #else
     571             :         .init_server = rpcecho__op_init_server,
     572             : #endif
     573             : #ifdef DCESRV_INTERFACE_RPCECHO_SHUTDOWN_SERVER
     574             :         .shutdown_server = DCESRV_INTERFACE_RPCECHO_SHUTDOWN_SERVER,
     575             : #else
     576             :         .shutdown_server = rpcecho__op_shutdown_server,
     577             : #endif
     578             :         .interface_by_uuid = rpcecho__op_interface_by_uuid,
     579             :         .interface_by_name = rpcecho__op_interface_by_name
     580             : };
     581             : 
     582          60 : const struct dcesrv_endpoint_server *rpcecho_get_ep_server(void)
     583             : {
     584          60 :         return &rpcecho_ep_server;
     585             : }

Generated by: LCOV version 1.13