LCOV - code coverage report
Current view: top level - source3/rpc_server/svcctl - srv_svcctl_nt.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 287 485 59.2 %
Date: 2021-09-23 10:06:22 Functions: 25 55 45.5 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  RPC Pipe client / server routines
       4             :  *
       5             :  *  Copyright (C) Marcin Krzysztof Porwit           2005.
       6             :  *
       7             :  *  Largely Rewritten (Again) by:
       8             :  *  Copyright (C) Gerald (Jerry) Carter             2005.
       9             :  *  Copyright (C) Guenther Deschner                 2008,2009.
      10             :  *
      11             :  *  This program is free software; you can redistribute it and/or modify
      12             :  *  it under the terms of the GNU General Public License as published by
      13             :  *  the Free Software Foundation; either version 3 of the License, or
      14             :  *  (at your option) any later version.
      15             :  *
      16             :  *  This program is distributed in the hope that it will be useful,
      17             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :  *  GNU General Public License for more details.
      20             :  *
      21             :  *  You should have received a copy of the GNU General Public License
      22             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      23             :  */
      24             : 
      25             : #include "includes.h"
      26             : #include "system/passwd.h" /* uid_wrapper */
      27             : #include "ntdomain.h"
      28             : #include "../libcli/security/security.h"
      29             : #include "../librpc/gen_ndr/ndr_security.h"
      30             : #include "services/services.h"
      31             : #include "services/svc_winreg_glue.h"
      32             : #include "auth.h"
      33             : #include "rpc_server/svcctl/srv_svcctl_nt.h"
      34             : 
      35             : #include "rpc_server/rpc_server.h"
      36             : #include "librpc/rpc/dcesrv_core.h"
      37             : #include "librpc/gen_ndr/ndr_svcctl.h"
      38             : #include "librpc/gen_ndr/ndr_svcctl_scompat.h"
      39             : #include "srv_svcctl_reg.h"
      40             : #include "lib/global_contexts.h"
      41             : 
      42             : #undef DBGC_CLASS
      43             : #define DBGC_CLASS DBGC_RPC_SRV
      44             : 
      45             : struct service_control_op {
      46             :         const char *name;
      47             :         SERVICE_CONTROL_OPS *ops;
      48             : };
      49             : 
      50             : /* handle external services */
      51             : extern SERVICE_CONTROL_OPS rcinit_svc_ops;
      52             : 
      53             : /* builtin services (see service_db.c and services/svc_*.c */
      54             : extern SERVICE_CONTROL_OPS spoolss_svc_ops;
      55             : extern SERVICE_CONTROL_OPS netlogon_svc_ops;
      56             : extern SERVICE_CONTROL_OPS winreg_svc_ops;
      57             : extern SERVICE_CONTROL_OPS wins_svc_ops;
      58             : 
      59             : /* make sure this number patches the number of builtin
      60             :    SERVICE_CONTROL_OPS structure listed above */
      61             : 
      62             : #define SVCCTL_NUM_INTERNAL_SERVICES    4
      63             : 
      64             : struct service_control_op *svcctl_ops;
      65             : 
      66             : static const struct generic_mapping scm_generic_map =
      67             :         { SC_MANAGER_READ_ACCESS, SC_MANAGER_WRITE_ACCESS, SC_MANAGER_EXECUTE_ACCESS, SC_MANAGER_ALL_ACCESS };
      68             : static const struct generic_mapping svc_generic_map =
      69             :         { SERVICE_READ_ACCESS, SERVICE_WRITE_ACCESS, SERVICE_EXECUTE_ACCESS, SERVICE_ALL_ACCESS };
      70             : 
      71             : 
      72             : /********************************************************************
      73             : ********************************************************************/
      74             : 
      75          60 : bool init_service_op_table( void )
      76             : {
      77          60 :         const char **service_list = lp_svcctl_list();
      78          60 :         int num_services = SVCCTL_NUM_INTERNAL_SERVICES + str_list_length( service_list );
      79             :         int i;
      80             : 
      81          60 :         if ( !(svcctl_ops = talloc_array( NULL, struct service_control_op, num_services+1)) ) {
      82           0 :                 DEBUG(0,("init_service_op_table: talloc() failed!\n"));
      83           0 :                 return False;
      84             :         }
      85             : 
      86             :         /* services listed in smb.conf get the rc.init interface */
      87             : 
      88          58 :         for ( i=0; service_list && service_list[i]; i++ ) {
      89           0 :                 svcctl_ops[i].name = talloc_strdup( svcctl_ops, service_list[i] );
      90           0 :                 svcctl_ops[i].ops  = &rcinit_svc_ops;
      91             :         }
      92             : 
      93             :         /* add builtin services */
      94             : 
      95          60 :         svcctl_ops[i].name = talloc_strdup( svcctl_ops, "Spooler" );
      96          60 :         svcctl_ops[i].ops  = &spoolss_svc_ops;
      97          60 :         i++;
      98             : 
      99          60 :         svcctl_ops[i].name = talloc_strdup( svcctl_ops, "NETLOGON" );
     100          60 :         svcctl_ops[i].ops  = &netlogon_svc_ops;
     101          60 :         i++;
     102             : 
     103          60 :         svcctl_ops[i].name = talloc_strdup( svcctl_ops, "RemoteRegistry" );
     104          60 :         svcctl_ops[i].ops  = &winreg_svc_ops;
     105          60 :         i++;
     106             : 
     107          60 :         svcctl_ops[i].name = talloc_strdup( svcctl_ops, "WINS" );
     108          60 :         svcctl_ops[i].ops  = &wins_svc_ops;
     109          60 :         i++;
     110             : 
     111             :         /* NULL terminate the array */
     112             : 
     113          60 :         svcctl_ops[i].name = NULL;
     114          60 :         svcctl_ops[i].ops  = NULL;
     115             : 
     116          60 :         return True;
     117             : }
     118             : 
     119          19 : bool shutdown_service_op_table(void)
     120             : {
     121          19 :         TALLOC_FREE(svcctl_ops);
     122             : 
     123          19 :         return true;
     124             : }
     125             : 
     126             : /********************************************************************
     127             : ********************************************************************/
     128             : 
     129          40 : static struct service_control_op* find_service_by_name( const char *name )
     130             : {
     131             :         int i;
     132             : 
     133          40 :         for ( i=0; svcctl_ops[i].name; i++ ) {
     134          40 :                 if ( strequal( name, svcctl_ops[i].name ) )
     135          40 :                         return &svcctl_ops[i];
     136             :         }
     137             : 
     138           0 :         return NULL;
     139             : }
     140             : /********************************************************************
     141             : ********************************************************************/
     142             : 
     143          88 : static NTSTATUS svcctl_access_check( struct security_descriptor *sec_desc, struct security_token *token,
     144             :                                      uint32_t access_desired, uint32_t *access_granted )
     145             : {
     146             :         NTSTATUS status;
     147          88 :         if ( geteuid() == sec_initial_uid() ) {
     148          88 :                 DEBUG(5,("svcctl_access_check: using root's token\n"));
     149          88 :                 status = get_root_nt_token(&token);
     150          88 :                 if(!NT_STATUS_IS_OK(status)) {
     151           0 :                         return status;
     152             :                 }
     153             :         }
     154             : 
     155          88 :         return se_access_check( sec_desc, token, access_desired, access_granted);
     156             : }
     157             : 
     158             : /********************************************************************
     159             : ********************************************************************/
     160             : 
     161          48 : static struct security_descriptor* construct_scm_sd( TALLOC_CTX *ctx )
     162             : {
     163             :         struct security_ace ace[2];
     164          48 :         size_t i = 0;
     165             :         struct security_descriptor *sd;
     166             :         struct security_acl *theacl;
     167             :         size_t sd_size;
     168             : 
     169             :         /* basic access for Everyone */
     170             : 
     171          48 :         init_sec_ace(&ace[i++], &global_sid_World,
     172             :                 SEC_ACE_TYPE_ACCESS_ALLOWED, SC_MANAGER_READ_ACCESS, 0);
     173             : 
     174             :         /* Full Access 'BUILTIN\Administrators' */
     175             : 
     176          48 :         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
     177             :                 SEC_ACE_TYPE_ACCESS_ALLOWED, SC_MANAGER_ALL_ACCESS, 0);
     178             : 
     179             : 
     180             :         /* create the security descriptor */
     181             : 
     182          48 :         if ( !(theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
     183           0 :                 return NULL;
     184             : 
     185          48 :         if ( !(sd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
     186             :                                   SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
     187             :                                   theacl, &sd_size)) )
     188           0 :                 return NULL;
     189             : 
     190          48 :         return sd;
     191             : }
     192             : 
     193             : /******************************************************************
     194             :  Find a registry key handle and return a SERVICE_INFO
     195             :  *****************************************************************/
     196             : 
     197         140 : static SERVICE_INFO *find_service_info_by_hnd(struct pipes_struct *p,
     198             :                                               struct policy_handle *hnd)
     199             : {
     200         140 :         SERVICE_INFO *service_info = NULL;
     201             :         NTSTATUS status;
     202             : 
     203         140 :         service_info = find_policy_by_hnd(p,
     204             :                                           hnd,
     205             :                                           DCESRV_HANDLE_ANY,
     206             :                                           SERVICE_INFO,
     207             :                                           &status);
     208         140 :         if (!NT_STATUS_IS_OK(status)) {
     209           0 :                 DEBUG(2,("find_service_info_by_hnd: handle not found\n"));
     210           0 :                 return NULL;
     211             :         }
     212             : 
     213         140 :         return service_info;
     214             : }
     215             : 
     216             : /******************************************************************
     217             :  *****************************************************************/
     218             : 
     219          88 : static WERROR create_open_service_handle(struct pipes_struct *p,
     220             :                                          struct policy_handle *handle,
     221             :                                          uint32_t type,
     222             :                                          const char *service,
     223             :                                          uint32_t access_granted)
     224             : {
     225          88 :         SERVICE_INFO *info = NULL;
     226          88 :         WERROR result = WERR_OK;
     227             :         struct service_control_op *s_op;
     228             : 
     229          88 :         if ( !(info = talloc_zero( NULL, SERVICE_INFO )) )
     230           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     231             : 
     232             :         /* the Service Manager has a NULL name */
     233             : 
     234          88 :         info->type = SVC_HANDLE_IS_SCM;
     235             : 
     236          88 :         switch ( type ) {
     237          48 :         case SVC_HANDLE_IS_SCM:
     238          48 :                 info->type = SVC_HANDLE_IS_SCM;
     239          48 :                 break;
     240             : 
     241           0 :         case SVC_HANDLE_IS_DBLOCK:
     242           0 :                 info->type = SVC_HANDLE_IS_DBLOCK;
     243           0 :                 break;
     244             : 
     245          40 :         case SVC_HANDLE_IS_SERVICE:
     246          40 :                 info->type = SVC_HANDLE_IS_SERVICE;
     247             : 
     248             :                 /* lookup the SERVICE_CONTROL_OPS */
     249             : 
     250          40 :                 if ( !(s_op = find_service_by_name( service )) ) {
     251           0 :                         result = WERR_SERVICE_DOES_NOT_EXIST;
     252           0 :                         goto done;
     253             :                 }
     254             : 
     255          40 :                 info->ops = s_op->ops;
     256             : 
     257          40 :                 if ( !(info->name  = talloc_strdup( info, s_op->name )) ) {
     258           0 :                         result = WERR_NOT_ENOUGH_MEMORY;
     259           0 :                         goto done;
     260             :                 }
     261          40 :                 break;
     262             : 
     263           0 :         default:
     264           0 :                 result = WERR_SERVICE_DOES_NOT_EXIST;
     265           0 :                 goto done;
     266             :         }
     267             : 
     268          88 :         info->access_granted = access_granted;
     269             : 
     270             :         /* store the SERVICE_INFO and create an open handle */
     271             : 
     272          88 :         if ( !create_policy_hnd( p, handle, 0, info ) ) {
     273           0 :                 result = WERR_ACCESS_DENIED;
     274           0 :                 goto done;
     275             :         }
     276             : 
     277         154 : done:
     278          88 :         if ( !W_ERROR_IS_OK(result) )
     279           0 :                 TALLOC_FREE(info);
     280             : 
     281          88 :         return result;
     282             : }
     283             : 
     284             : /********************************************************************
     285             :  _svcctl_OpenSCManagerW
     286             : ********************************************************************/
     287             : 
     288          48 : WERROR _svcctl_OpenSCManagerW(struct pipes_struct *p,
     289             :                               struct svcctl_OpenSCManagerW *r)
     290             : {
     291             :         struct security_descriptor *sec_desc;
     292          48 :         uint32_t access_granted = 0;
     293             :         NTSTATUS status;
     294             : 
     295             :         /* perform access checks */
     296             : 
     297          48 :         if ( !(sec_desc = construct_scm_sd( p->mem_ctx )) )
     298           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     299             : 
     300          48 :         se_map_generic( &r->in.access_mask, &scm_generic_map );
     301          48 :         status = svcctl_access_check( sec_desc, p->session_info->security_token,
     302             :                                       r->in.access_mask, &access_granted );
     303          48 :         if ( !NT_STATUS_IS_OK(status) )
     304           0 :                 return ntstatus_to_werror( status );
     305             : 
     306          48 :         return create_open_service_handle( p, r->out.handle, SVC_HANDLE_IS_SCM, NULL, access_granted );
     307             : }
     308             : 
     309             : /********************************************************************
     310             :  _svcctl_OpenServiceW
     311             : ********************************************************************/
     312             : 
     313          40 : WERROR _svcctl_OpenServiceW(struct pipes_struct *p,
     314             :                             struct svcctl_OpenServiceW *r)
     315             : {
     316             :         struct security_descriptor *sec_desc;
     317          40 :         uint32_t access_granted = 0;
     318             :         NTSTATUS status;
     319          40 :         const char *service = NULL;
     320             :         WERROR err;
     321             : 
     322          40 :         service = r->in.ServiceName;
     323          40 :         if (!service) {
     324           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     325             :         }
     326          40 :         DEBUG(5, ("_svcctl_OpenServiceW: Attempting to open Service [%s], \n", service));
     327             : 
     328             :         /* based on my tests you can open a service if you have a valid scm handle */
     329             : 
     330          40 :         if ( !find_service_info_by_hnd( p, r->in.scmanager_handle) )
     331           0 :                 return WERR_INVALID_HANDLE;
     332             : 
     333             :         /*
     334             :          * Perform access checks. Use the system session_info in order to ensure
     335             :          * that we retrieve the security descriptor
     336             :          */
     337          40 :         err = svcctl_get_secdesc(p->msg_ctx,
     338             :                                  get_session_info_system(),
     339             :                                  service,
     340             :                                  p->mem_ctx,
     341             :                                  &sec_desc);
     342          40 :         if (W_ERROR_EQUAL(err, WERR_FILE_NOT_FOUND)) {
     343           0 :                 DBG_NOTICE("service %s does not exist\n", service);
     344           0 :                 return WERR_SERVICE_DOES_NOT_EXIST;
     345             :         }
     346          40 :         if (!W_ERROR_IS_OK(err)) {
     347           0 :                 DBG_NOTICE("Failed to get a valid secdesc for %s: %s\n",
     348             :                            service, win_errstr(err));
     349           0 :                 return err;
     350             :         }
     351             : 
     352          40 :         se_map_generic( &r->in.access_mask, &svc_generic_map );
     353          40 :         status = svcctl_access_check( sec_desc, p->session_info->security_token,
     354             :                                       r->in.access_mask, &access_granted );
     355          40 :         if ( !NT_STATUS_IS_OK(status) )
     356           0 :                 return ntstatus_to_werror( status );
     357             : 
     358          40 :         return create_open_service_handle( p, r->out.handle, SVC_HANDLE_IS_SERVICE, service, access_granted );
     359             : }
     360             : 
     361             : /********************************************************************
     362             :  _svcctl_CloseServiceHandle
     363             : ********************************************************************/
     364             : 
     365          80 : WERROR _svcctl_CloseServiceHandle(struct pipes_struct *p,
     366             :                                   struct svcctl_CloseServiceHandle *r)
     367             : {
     368          80 :         if ( !close_policy_hnd( p, r->in.handle ) )
     369           0 :                 return  WERR_INVALID_HANDLE;
     370             : 
     371          80 :         ZERO_STRUCTP(r->out.handle);
     372             : 
     373          80 :         return WERR_OK;
     374             : }
     375             : 
     376             : /********************************************************************
     377             :  _svcctl_GetServiceDisplayNameW
     378             : ********************************************************************/
     379             : 
     380           0 : WERROR _svcctl_GetServiceDisplayNameW(struct pipes_struct *p,
     381             :                                       struct svcctl_GetServiceDisplayNameW *r)
     382             : {
     383             :         const char *service;
     384             :         const char *display_name;
     385           0 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     386             : 
     387             :         /* can only use an SCM handle here */
     388             : 
     389           0 :         if ( !info || (info->type != SVC_HANDLE_IS_SCM) )
     390           0 :                 return WERR_INVALID_HANDLE;
     391             : 
     392           0 :         service = r->in.service_name;
     393             : 
     394           0 :         display_name = svcctl_lookup_dispname(p->mem_ctx,
     395             :                                               p->msg_ctx,
     396           0 :                                               p->session_info,
     397             :                                               service);
     398           0 :         if (!display_name) {
     399           0 :                 display_name = "";
     400             :         }
     401             : 
     402           0 :         *r->out.display_name = display_name;
     403           0 :         *r->out.display_name_length = strlen(display_name);
     404             : 
     405           0 :         return WERR_OK;
     406             : }
     407             : 
     408             : /********************************************************************
     409             :  _svcctl_QueryServiceStatus
     410             : ********************************************************************/
     411             : 
     412           4 : WERROR _svcctl_QueryServiceStatus(struct pipes_struct *p,
     413             :                                   struct svcctl_QueryServiceStatus *r)
     414             : {
     415           4 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     416             : 
     417             :         /* perform access checks */
     418             : 
     419           4 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     420           0 :                 return WERR_INVALID_HANDLE;
     421             : 
     422           4 :         if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) )
     423           0 :                 return WERR_ACCESS_DENIED;
     424             : 
     425             :         /* try the service specific status call */
     426             : 
     427           4 :         return info->ops->service_status( info->name, r->out.service_status );
     428             : }
     429             : 
     430             : /********************************************************************
     431             : ********************************************************************/
     432             : 
     433           8 : static int enumerate_status(TALLOC_CTX *ctx,
     434             :                             struct messaging_context *msg_ctx,
     435             :                             struct auth_session_info *session_info,
     436             :                             struct ENUM_SERVICE_STATUSW **status)
     437             : {
     438           8 :         int num_services = 0;
     439             :         int i;
     440             :         struct ENUM_SERVICE_STATUSW *st;
     441             :         const char *display_name;
     442             : 
     443             :         /* just count */
     444          46 :         while ( svcctl_ops[num_services].name )
     445          32 :                 num_services++;
     446             : 
     447           8 :         if ( !(st = talloc_array( ctx, struct ENUM_SERVICE_STATUSW, num_services )) ) {
     448           0 :                 DEBUG(0,("enumerate_status: talloc() failed!\n"));
     449           0 :                 return -1;
     450             :         }
     451             : 
     452          40 :         for ( i=0; i<num_services; i++ ) {
     453          32 :                 st[i].service_name = talloc_strdup(st, svcctl_ops[i].name );
     454             : 
     455          32 :                 display_name = svcctl_lookup_dispname(ctx,
     456             :                                                       msg_ctx,
     457             :                                                       session_info,
     458          32 :                                                       svcctl_ops[i].name);
     459          32 :                 st[i].display_name = talloc_strdup(st, display_name ? display_name : "");
     460             : 
     461          32 :                 svcctl_ops[i].ops->service_status( svcctl_ops[i].name, &st[i].status );
     462             :         }
     463             : 
     464           8 :         *status = st;
     465             : 
     466           8 :         return num_services;
     467             : }
     468             : 
     469             : /********************************************************************
     470             :  _svcctl_EnumServicesStatusW
     471             : ********************************************************************/
     472             : 
     473           8 : WERROR _svcctl_EnumServicesStatusW(struct pipes_struct *p,
     474             :                                    struct svcctl_EnumServicesStatusW *r)
     475             : {
     476           8 :         struct ENUM_SERVICE_STATUSW *services = NULL;
     477             :         int num_services;
     478           8 :         int i = 0;
     479           8 :         size_t buffer_size = 0;
     480           8 :         WERROR result = WERR_OK;
     481           8 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     482           8 :         DATA_BLOB blob = data_blob_null;
     483             : 
     484             :         /* perform access checks */
     485             : 
     486           8 :         if ( !info || (info->type != SVC_HANDLE_IS_SCM) )
     487           0 :                 return WERR_INVALID_HANDLE;
     488             : 
     489           8 :         if ( !(info->access_granted & SC_RIGHT_MGR_ENUMERATE_SERVICE) ) {
     490           0 :                 return WERR_ACCESS_DENIED;
     491             :         }
     492             : 
     493           8 :         num_services = enumerate_status(p->mem_ctx,
     494             :                                         p->msg_ctx,
     495             :                                         p->session_info,
     496             :                                         &services);
     497           8 :         if (num_services == -1 ) {
     498           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     499             :         }
     500             : 
     501          40 :         for ( i=0; i<num_services; i++ ) {
     502          32 :                 buffer_size += ndr_size_ENUM_SERVICE_STATUSW(&services[i], 0);
     503             :         }
     504             : 
     505           8 :         buffer_size += buffer_size % 4;
     506             : 
     507           8 :         if (buffer_size > r->in.offered) {
     508           4 :                 num_services = 0;
     509           4 :                 result = WERR_MORE_DATA;
     510             :         }
     511             : 
     512           8 :         if ( W_ERROR_IS_OK(result) ) {
     513             : 
     514             :                 enum ndr_err_code ndr_err;
     515             :                 struct ndr_push *ndr;
     516             : 
     517           4 :                 ndr = ndr_push_init_ctx(p->mem_ctx);
     518           4 :                 if (ndr == NULL) {
     519           0 :                         return WERR_INVALID_PARAMETER;
     520             :                 }
     521             : 
     522           4 :                 ndr_err = ndr_push_ENUM_SERVICE_STATUSW_array(
     523             :                         ndr, num_services, services);
     524           4 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     525           0 :                         return ntstatus_to_werror(ndr_map_error2ntstatus(ndr_err));
     526             :                 }
     527           4 :                 blob = ndr_push_blob(ndr);
     528           4 :                 memcpy(r->out.service, blob.data, MIN(blob.length, r->in.offered));
     529             :         }
     530             : 
     531           8 :         *r->out.needed                       = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
     532           8 :         *r->out.services_returned    = (uint32_t)num_services;
     533           8 :         if (r->out.resume_handle) {
     534           8 :                 *r->out.resume_handle        = 0;
     535             :         }
     536             : 
     537           8 :         return result;
     538             : }
     539             : 
     540             : /********************************************************************
     541             :  _svcctl_StartServiceW
     542             : ********************************************************************/
     543             : 
     544           4 : WERROR _svcctl_StartServiceW(struct pipes_struct *p,
     545             :                              struct svcctl_StartServiceW *r)
     546             : {
     547           4 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     548             : 
     549             :         /* perform access checks */
     550             : 
     551           4 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     552           0 :                 return WERR_INVALID_HANDLE;
     553             : 
     554           4 :         if ( !(info->access_granted & SC_RIGHT_SVC_START) )
     555           0 :                 return WERR_ACCESS_DENIED;
     556             : 
     557           4 :         return info->ops->start_service( info->name );
     558             : }
     559             : 
     560             : /********************************************************************
     561             :  _svcctl_ControlService
     562             : ********************************************************************/
     563             : 
     564           4 : WERROR _svcctl_ControlService(struct pipes_struct *p,
     565             :                               struct svcctl_ControlService *r)
     566             : {
     567           4 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     568             : 
     569             :         /* perform access checks */
     570             : 
     571           4 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     572           0 :                 return WERR_INVALID_HANDLE;
     573             : 
     574           4 :         switch ( r->in.control ) {
     575           0 :         case SVCCTL_CONTROL_STOP:
     576           0 :                 if ( !(info->access_granted & SC_RIGHT_SVC_STOP) )
     577           0 :                         return WERR_ACCESS_DENIED;
     578             : 
     579           0 :                 return info->ops->stop_service( info->name,
     580             :                                                 r->out.service_status );
     581             : 
     582           0 :         case SVCCTL_CONTROL_INTERROGATE:
     583           0 :                 if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) )
     584           0 :                         return WERR_ACCESS_DENIED;
     585             : 
     586           0 :                 return info->ops->service_status( info->name,
     587             :                                                   r->out.service_status );
     588           4 :         default:
     589           4 :                 return WERR_INVALID_PARAMETER;
     590             :         }
     591             : }
     592             : 
     593             : /********************************************************************
     594             :  _svcctl_EnumDependentServicesW
     595             : ********************************************************************/
     596             : 
     597          16 : WERROR _svcctl_EnumDependentServicesW(struct pipes_struct *p,
     598             :                                       struct svcctl_EnumDependentServicesW *r)
     599             : {
     600          16 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.service );
     601             : 
     602             :         /* perform access checks */
     603             : 
     604          16 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     605           0 :                 return WERR_INVALID_HANDLE;
     606             : 
     607          16 :         if ( !(info->access_granted & SC_RIGHT_SVC_ENUMERATE_DEPENDENTS) )
     608           0 :                 return WERR_ACCESS_DENIED;
     609             : 
     610          16 :         switch (r->in.state) {
     611          12 :         case SERVICE_STATE_ACTIVE:
     612             :         case SERVICE_STATE_INACTIVE:
     613             :         case SERVICE_STATE_ALL:
     614          12 :                 break;
     615           4 :         default:
     616           4 :                 return WERR_INVALID_PARAMETER;
     617             :         }
     618             : 
     619             :         /* we have to set the outgoing buffer size to the same as the
     620             :            incoming buffer size (even in the case of failure */
     621             :         /* this is done in the autogenerated server already - gd */
     622             : 
     623          12 :         *r->out.needed = r->in.offered;
     624             : 
     625             :         /* no dependent services...basically a stub function */
     626          12 :         *r->out.services_returned = 0;
     627             : 
     628          12 :         return WERR_OK;
     629             : }
     630             : 
     631             : /********************************************************************
     632             :  _svcctl_QueryServiceStatusEx
     633             : ********************************************************************/
     634             : 
     635           8 : WERROR _svcctl_QueryServiceStatusEx(struct pipes_struct *p,
     636             :                                     struct svcctl_QueryServiceStatusEx *r)
     637             : {
     638           8 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     639             :         uint32_t buffer_size;
     640             : 
     641             :         /* perform access checks */
     642             : 
     643           8 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     644           0 :                 return WERR_INVALID_HANDLE;
     645             : 
     646           8 :         if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) )
     647           0 :                 return WERR_ACCESS_DENIED;
     648             : 
     649             :         /* we have to set the outgoing buffer size to the same as the
     650             :            incoming buffer size (even in the case of failure) */
     651           8 :         *r->out.needed = r->in.offered;
     652             : 
     653           8 :         switch ( r->in.info_level ) {
     654           8 :                 case SVC_STATUS_PROCESS_INFO:
     655             :                 {
     656             :                         struct SERVICE_STATUS_PROCESS svc_stat_proc;
     657             :                         enum ndr_err_code ndr_err;
     658             :                         DATA_BLOB blob;
     659             : 
     660             :                         /* Get the status of the service.. */
     661           8 :                         info->ops->service_status( info->name, &svc_stat_proc.status );
     662           8 :                         svc_stat_proc.process_id     = getpid();
     663           8 :                         svc_stat_proc.service_flags  = 0x0;
     664             : 
     665           8 :                         ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &svc_stat_proc,
     666             :                                                        (ndr_push_flags_fn_t)ndr_push_SERVICE_STATUS_PROCESS);
     667           8 :                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     668           0 :                                 return WERR_INVALID_PARAMETER;
     669             :                         }
     670             : 
     671           8 :                         r->out.buffer = blob.data;
     672           8 :                         buffer_size = sizeof(struct SERVICE_STATUS_PROCESS);
     673           8 :                         break;
     674             :                 }
     675             : 
     676           0 :                 default:
     677           0 :                         return WERR_INVALID_LEVEL;
     678             :         }
     679             : 
     680             : 
     681           8 :         buffer_size += buffer_size % 4;
     682           8 :         *r->out.needed = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
     683             : 
     684           8 :         if (buffer_size > r->in.offered ) {
     685           4 :                 return WERR_INSUFFICIENT_BUFFER;
     686             :         }
     687             : 
     688           4 :         return WERR_OK;
     689             : }
     690             : 
     691             : /********************************************************************
     692             : ********************************************************************/
     693             : 
     694          16 : static WERROR fill_svc_config(TALLOC_CTX *mem_ctx,
     695             :                               struct messaging_context *msg_ctx,
     696             :                               struct auth_session_info *session_info,
     697             :                               const char *name,
     698             :                               struct QUERY_SERVICE_CONFIG *config)
     699             : {
     700          16 :         const char *result = NULL;
     701             : 
     702             :         /* now fill in the individual values */
     703             : 
     704          16 :         ZERO_STRUCTP(config);
     705             : 
     706          16 :         config->displayname = svcctl_lookup_dispname(mem_ctx,
     707             :                                                      msg_ctx,
     708             :                                                      session_info,
     709             :                                                      name);
     710             : 
     711          16 :         result = svcctl_get_string_value(mem_ctx,
     712             :                                          msg_ctx,
     713             :                                          session_info,
     714             :                                          name,
     715             :                                          "ObjectName");
     716          16 :         if (result != NULL) {
     717          16 :                 config->startname = result;
     718             :         }
     719             : 
     720          16 :         result = svcctl_get_string_value(mem_ctx,
     721             :                                          msg_ctx,
     722             :                                          session_info,
     723             :                                          name,
     724             :                                          "ImagePath");
     725          16 :         if (result != NULL) {
     726          16 :                 config->executablepath = result;
     727             :         }
     728             : 
     729             :         /* a few hard coded values */
     730             :         /* loadordergroup and dependencies are empty */
     731             : 
     732          16 :         config->tag_id           = 0x00000000;                       /* unassigned loadorder group */
     733          16 :         config->service_type     = SERVICE_TYPE_WIN32_OWN_PROCESS;
     734          16 :         config->error_control    = SVCCTL_SVC_ERROR_NORMAL;
     735             : 
     736             :         /* set the start type.  NetLogon and WINS are disabled to prevent
     737             :            the client from showing the "Start" button (if of course the services
     738             :            are not running */
     739             : 
     740          16 :         if ( strequal( name, "NETLOGON" ) && ( lp_servicenumber(name) == -1 ) )
     741           0 :                 config->start_type = SVCCTL_DISABLED;
     742          16 :         else if ( strequal( name, "WINS" ) && ( !lp_we_are_a_wins_server() ))
     743           0 :                 config->start_type = SVCCTL_DISABLED;
     744             :         else
     745          16 :                 config->start_type = SVCCTL_DEMAND_START;
     746             : 
     747          16 :         return WERR_OK;
     748             : }
     749             : 
     750             : /********************************************************************
     751             :  _svcctl_QueryServiceConfigW
     752             : ********************************************************************/
     753             : 
     754          16 : WERROR _svcctl_QueryServiceConfigW(struct pipes_struct *p,
     755             :                                    struct svcctl_QueryServiceConfigW *r)
     756             : {
     757          16 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     758             :         uint32_t buffer_size;
     759             :         WERROR wresult;
     760             : 
     761             :         /* perform access checks */
     762             : 
     763          16 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     764           0 :                 return WERR_INVALID_HANDLE;
     765             : 
     766          16 :         if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_CONFIG) )
     767           0 :                 return WERR_ACCESS_DENIED;
     768             : 
     769             :         /* we have to set the outgoing buffer size to the same as the
     770             :            incoming buffer size (even in the case of failure */
     771             : 
     772          16 :         *r->out.needed = r->in.offered;
     773             : 
     774          28 :         wresult = fill_svc_config(p->mem_ctx,
     775             :                                   p->msg_ctx,
     776             :                                   p->session_info,
     777          16 :                                   info->name,
     778             :                                   r->out.query);
     779          16 :         if ( !W_ERROR_IS_OK(wresult) )
     780           0 :                 return wresult;
     781             : 
     782          16 :         buffer_size = ndr_size_QUERY_SERVICE_CONFIG(r->out.query, 0);
     783          16 :         *r->out.needed = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
     784             : 
     785          16 :         if (buffer_size > r->in.offered ) {
     786           8 :                 ZERO_STRUCTP(r->out.query);
     787           8 :                 return WERR_INSUFFICIENT_BUFFER;
     788             :         }
     789             : 
     790           8 :         return WERR_OK;
     791             : }
     792             : 
     793             : /********************************************************************
     794             :  _svcctl_QueryServiceConfig2W
     795             : ********************************************************************/
     796             : 
     797          16 : WERROR _svcctl_QueryServiceConfig2W(struct pipes_struct *p,
     798             :                                     struct svcctl_QueryServiceConfig2W *r)
     799             : {
     800          16 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     801             :         uint32_t buffer_size;
     802          16 :         DATA_BLOB blob = data_blob_null;
     803             : 
     804             :         /* perform access checks */
     805             : 
     806          16 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     807           0 :                 return WERR_INVALID_HANDLE;
     808             : 
     809          16 :         if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_CONFIG) )
     810           0 :                 return WERR_ACCESS_DENIED;
     811             : 
     812             :         /* we have to set the outgoing buffer size to the same as the
     813             :            incoming buffer size (even in the case of failure */
     814          16 :         *r->out.needed = r->in.offered;
     815             : 
     816          16 :         switch ( r->in.info_level ) {
     817           8 :         case SERVICE_CONFIG_DESCRIPTION:
     818             :                 {
     819             :                         struct SERVICE_DESCRIPTION desc_buf;
     820             :                         const char *description;
     821             :                         enum ndr_err_code ndr_err;
     822             : 
     823           8 :                         description = svcctl_lookup_description(p->mem_ctx,
     824             :                                                                 p->msg_ctx,
     825           8 :                                                                 p->session_info,
     826           8 :                                                                 info->name);
     827             : 
     828           8 :                         desc_buf.description = description;
     829             : 
     830           8 :                         ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &desc_buf,
     831             :                                                        (ndr_push_flags_fn_t)ndr_push_SERVICE_DESCRIPTION);
     832           8 :                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     833           0 :                                 return WERR_INVALID_PARAMETER;
     834             :                         }
     835             : 
     836           8 :                         break;
     837             :                 }
     838             :                 break;
     839           8 :         case SERVICE_CONFIG_FAILURE_ACTIONS:
     840             :                 {
     841             :                         struct SERVICE_FAILURE_ACTIONS actions;
     842             :                         enum ndr_err_code ndr_err;
     843             : 
     844             :                         /* nothing to say...just service the request */
     845             : 
     846           8 :                         ZERO_STRUCT( actions );
     847             : 
     848           8 :                         ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &actions,
     849             :                                                        (ndr_push_flags_fn_t)ndr_push_SERVICE_FAILURE_ACTIONS);
     850           8 :                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     851           0 :                                 return WERR_INVALID_PARAMETER;
     852             :                         }
     853             : 
     854           8 :                         break;
     855             :                 }
     856             :                 break;
     857             : 
     858           0 :         default:
     859           0 :                 return WERR_INVALID_LEVEL;
     860             :         }
     861             : 
     862          16 :         buffer_size = blob.length;
     863          16 :         buffer_size += buffer_size % 4;
     864          16 :         *r->out.needed = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
     865             : 
     866          16 :         if (buffer_size > r->in.offered)
     867           8 :                 return WERR_INSUFFICIENT_BUFFER;
     868             : 
     869           8 :         memcpy(r->out.buffer, blob.data, blob.length);
     870             : 
     871           8 :         return WERR_OK;
     872             : }
     873             : 
     874             : /********************************************************************
     875             :  _svcctl_LockServiceDatabase
     876             : ********************************************************************/
     877             : 
     878           0 : WERROR _svcctl_LockServiceDatabase(struct pipes_struct *p,
     879             :                                    struct svcctl_LockServiceDatabase *r)
     880             : {
     881           0 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     882             : 
     883             :         /* perform access checks */
     884             : 
     885           0 :         if ( !info || (info->type != SVC_HANDLE_IS_SCM) )
     886           0 :                 return WERR_INVALID_HANDLE;
     887             : 
     888           0 :         if ( !(info->access_granted & SC_RIGHT_MGR_LOCK) )
     889           0 :                 return WERR_ACCESS_DENIED;
     890             : 
     891             :         /* Just open a handle.  Doesn't actually lock anything */
     892             : 
     893           0 :         return create_open_service_handle( p, r->out.lock, SVC_HANDLE_IS_DBLOCK, NULL, 0 );
     894             : }
     895             : 
     896             : /********************************************************************
     897             :  _svcctl_UnlockServiceDatabase
     898             : ********************************************************************/
     899             : 
     900           0 : WERROR _svcctl_UnlockServiceDatabase(struct pipes_struct *p,
     901             :                                      struct svcctl_UnlockServiceDatabase *r)
     902             : {
     903           0 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.lock );
     904             : 
     905             : 
     906           0 :         if ( !info || (info->type != SVC_HANDLE_IS_DBLOCK) )
     907           0 :                 return WERR_INVALID_HANDLE;
     908             : 
     909           0 :         return close_policy_hnd( p, r->out.lock) ? WERR_OK : WERR_INVALID_HANDLE;
     910             : }
     911             : 
     912             : /********************************************************************
     913             :  _svcctl_QueryServiceObjectSecurity
     914             : ********************************************************************/
     915             : 
     916          20 : WERROR _svcctl_QueryServiceObjectSecurity(struct pipes_struct *p,
     917             :                                           struct svcctl_QueryServiceObjectSecurity *r)
     918             : {
     919          20 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     920             :         struct security_descriptor *sec_desc;
     921             :         NTSTATUS status;
     922          20 :         uint8_t *buffer = NULL;
     923          20 :         size_t len = 0;
     924             :         WERROR err;
     925             : 
     926             : 
     927             :         /* only support the SCM and individual services */
     928             : 
     929          20 :         if ( !info || !(info->type & (SVC_HANDLE_IS_SERVICE|SVC_HANDLE_IS_SCM)) )
     930           0 :                 return WERR_INVALID_HANDLE;
     931             : 
     932             :         /* check access reights (according to MSDN) */
     933             : 
     934          20 :         if ( !(info->access_granted & SEC_STD_READ_CONTROL) )
     935           0 :                 return WERR_ACCESS_DENIED;
     936             : 
     937             :         /* TODO: handle something besides SECINFO_DACL */
     938             : 
     939          20 :         if ( (r->in.security_flags & SECINFO_DACL) != SECINFO_DACL )
     940           4 :                 return WERR_INVALID_PARAMETER;
     941             : 
     942             :         /* Lookup the security descriptor and marshall it up for a reply */
     943          28 :         err = svcctl_get_secdesc(p->msg_ctx,
     944             :                                  get_session_info_system(),
     945          16 :                                  info->name,
     946             :                                  p->mem_ctx,
     947             :                                  &sec_desc);
     948          16 :         if (W_ERROR_EQUAL(err, WERR_FILE_NOT_FOUND)) {
     949           0 :                 DBG_NOTICE("service %s does not exist\n", info->name);
     950           0 :                 return WERR_SERVICE_DOES_NOT_EXIST;
     951             :         }
     952          16 :         if (!W_ERROR_IS_OK(err)) {
     953           0 :                 DBG_NOTICE("Failed to get a valid secdesc for %s: %s\n",
     954             :                            info->name, win_errstr(err));
     955           0 :                 return err;
     956             :         }
     957             : 
     958          16 :         *r->out.needed = ndr_size_security_descriptor(sec_desc, 0);
     959             : 
     960          16 :         if ( *r->out.needed > r->in.offered) {
     961           8 :                 return WERR_INSUFFICIENT_BUFFER;
     962             :         }
     963             : 
     964           8 :         status = marshall_sec_desc(p->mem_ctx, sec_desc, &buffer, &len);
     965           8 :         if (!NT_STATUS_IS_OK(status)) {
     966           0 :                 return ntstatus_to_werror(status);
     967             :         }
     968             : 
     969           8 :         *r->out.needed = len;
     970           8 :         memcpy(r->out.buffer, buffer, len);
     971             : 
     972           8 :         return WERR_OK;
     973             : }
     974             : 
     975             : /********************************************************************
     976             :  _svcctl_SetServiceObjectSecurity
     977             : ********************************************************************/
     978             : 
     979           4 : WERROR _svcctl_SetServiceObjectSecurity(struct pipes_struct *p,
     980             :                                         struct svcctl_SetServiceObjectSecurity *r)
     981             : {
     982           4 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     983           4 :         struct security_descriptor *sec_desc = NULL;
     984             :         uint32_t required_access;
     985             :         NTSTATUS status;
     986             : 
     987           4 :         if ( !info || !(info->type & (SVC_HANDLE_IS_SERVICE|SVC_HANDLE_IS_SCM))  )
     988           0 :                 return WERR_INVALID_HANDLE;
     989             : 
     990             :         /* can't set the security de4scriptor on the ServiceControlManager */
     991             : 
     992           4 :         if ( info->type == SVC_HANDLE_IS_SCM )
     993           0 :                 return WERR_ACCESS_DENIED;
     994             : 
     995             :         /* check the access on the open handle */
     996             : 
     997           4 :         switch ( r->in.security_flags ) {
     998           4 :                 case SECINFO_DACL:
     999           4 :                         required_access = SEC_STD_WRITE_DAC;
    1000           4 :                         break;
    1001             : 
    1002           0 :                 case SECINFO_OWNER:
    1003             :                 case SECINFO_GROUP:
    1004           0 :                         required_access = SEC_STD_WRITE_OWNER;
    1005           0 :                         break;
    1006             : 
    1007           0 :                 case SECINFO_SACL:
    1008           0 :                         return WERR_INVALID_PARAMETER;
    1009           0 :                 default:
    1010           0 :                         return WERR_INVALID_PARAMETER;
    1011             :         }
    1012             : 
    1013           4 :         if ( !(info->access_granted & required_access) )
    1014           0 :                 return WERR_ACCESS_DENIED;
    1015             : 
    1016             :         /* read the security descfriptor */
    1017             : 
    1018           4 :         status = unmarshall_sec_desc(p->mem_ctx,
    1019             :                                      r->in.buffer,
    1020           4 :                                      r->in.offered,
    1021             :                                      &sec_desc);
    1022           4 :         if (!NT_STATUS_IS_OK(status)) {
    1023           0 :                 return ntstatus_to_werror(status);
    1024             :         }
    1025             : 
    1026             :         /* store the new SD */
    1027             : 
    1028           4 :         if (!svcctl_set_secdesc(p->msg_ctx, p->session_info, info->name, sec_desc))
    1029           0 :                 return WERR_ACCESS_DENIED;
    1030             : 
    1031           4 :         return WERR_OK;
    1032             : }
    1033             : 
    1034             : 
    1035           0 : WERROR _svcctl_DeleteService(struct pipes_struct *p,
    1036             :                              struct svcctl_DeleteService *r)
    1037             : {
    1038           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1039           0 :         return WERR_NOT_SUPPORTED;
    1040             : }
    1041             : 
    1042           0 : WERROR _svcctl_SetServiceStatus(struct pipes_struct *p,
    1043             :                                 struct svcctl_SetServiceStatus *r)
    1044             : {
    1045           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1046           0 :         return WERR_NOT_SUPPORTED;
    1047             : }
    1048             : 
    1049           0 : WERROR _svcctl_NotifyBootConfigStatus(struct pipes_struct *p,
    1050             :                                       struct svcctl_NotifyBootConfigStatus *r)
    1051             : {
    1052           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1053           0 :         return WERR_NOT_SUPPORTED;
    1054             : }
    1055             : 
    1056           0 : WERROR _svcctl_SCSetServiceBitsW(struct pipes_struct *p,
    1057             :                                  struct svcctl_SCSetServiceBitsW *r)
    1058             : {
    1059           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1060           0 :         return WERR_NOT_SUPPORTED;
    1061             : }
    1062             : 
    1063           4 : WERROR _svcctl_ChangeServiceConfigW(struct pipes_struct *p,
    1064             :                                     struct svcctl_ChangeServiceConfigW *r)
    1065             : {
    1066           4 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1067           4 :         return WERR_NOT_SUPPORTED;
    1068             : }
    1069             : 
    1070           0 : WERROR _svcctl_CreateServiceW(struct pipes_struct *p,
    1071             :                               struct svcctl_CreateServiceW *r)
    1072             : {
    1073           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1074           0 :         return WERR_NOT_SUPPORTED;
    1075             : }
    1076             : 
    1077           0 : WERROR _svcctl_QueryServiceLockStatusW(struct pipes_struct *p,
    1078             :                                        struct svcctl_QueryServiceLockStatusW *r)
    1079             : {
    1080           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1081           0 :         return WERR_NOT_SUPPORTED;
    1082             : }
    1083             : 
    1084           0 : WERROR _svcctl_GetServiceKeyNameW(struct pipes_struct *p,
    1085             :                                   struct svcctl_GetServiceKeyNameW *r)
    1086             : {
    1087           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1088           0 :         return WERR_NOT_SUPPORTED;
    1089             : }
    1090             : 
    1091           0 : WERROR _svcctl_SCSetServiceBitsA(struct pipes_struct *p,
    1092             :                                  struct svcctl_SCSetServiceBitsA *r)
    1093             : {
    1094           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1095           0 :         return WERR_NOT_SUPPORTED;
    1096             : }
    1097             : 
    1098           0 : WERROR _svcctl_ChangeServiceConfigA(struct pipes_struct *p,
    1099             :                                     struct svcctl_ChangeServiceConfigA *r)
    1100             : {
    1101           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1102           0 :         return WERR_NOT_SUPPORTED;
    1103             : }
    1104             : 
    1105           0 : WERROR _svcctl_CreateServiceA(struct pipes_struct *p,
    1106             :                               struct svcctl_CreateServiceA *r)
    1107             : {
    1108           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1109           0 :         return WERR_NOT_SUPPORTED;
    1110             : }
    1111             : 
    1112           0 : WERROR _svcctl_EnumDependentServicesA(struct pipes_struct *p,
    1113             :                                       struct svcctl_EnumDependentServicesA *r)
    1114             : {
    1115           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1116           0 :         return WERR_NOT_SUPPORTED;
    1117             : }
    1118             : 
    1119           0 : WERROR _svcctl_EnumServicesStatusA(struct pipes_struct *p,
    1120             :                                    struct svcctl_EnumServicesStatusA *r)
    1121             : {
    1122           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1123           0 :         return WERR_NOT_SUPPORTED;
    1124             : }
    1125             : 
    1126           0 : WERROR _svcctl_OpenSCManagerA(struct pipes_struct *p,
    1127             :                               struct svcctl_OpenSCManagerA *r)
    1128             : {
    1129           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1130           0 :         return WERR_NOT_SUPPORTED;
    1131             : }
    1132             : 
    1133           0 : WERROR _svcctl_OpenServiceA(struct pipes_struct *p,
    1134             :                             struct svcctl_OpenServiceA *r)
    1135             : {
    1136           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1137           0 :         return WERR_NOT_SUPPORTED;
    1138             : }
    1139             : 
    1140           0 : WERROR _svcctl_QueryServiceConfigA(struct pipes_struct *p,
    1141             :                                    struct svcctl_QueryServiceConfigA *r)
    1142             : {
    1143           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1144           0 :         return WERR_NOT_SUPPORTED;
    1145             : }
    1146             : 
    1147           0 : WERROR _svcctl_QueryServiceLockStatusA(struct pipes_struct *p,
    1148             :                                        struct svcctl_QueryServiceLockStatusA *r)
    1149             : {
    1150           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1151           0 :         return WERR_NOT_SUPPORTED;
    1152             : }
    1153             : 
    1154           0 : WERROR _svcctl_StartServiceA(struct pipes_struct *p,
    1155             :                              struct svcctl_StartServiceA *r)
    1156             : {
    1157           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1158           0 :         return WERR_NOT_SUPPORTED;
    1159             : }
    1160             : 
    1161           0 : WERROR _svcctl_GetServiceDisplayNameA(struct pipes_struct *p,
    1162             :                                       struct svcctl_GetServiceDisplayNameA *r)
    1163             : {
    1164           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1165           0 :         return WERR_NOT_SUPPORTED;
    1166             : }
    1167             : 
    1168           0 : WERROR _svcctl_GetServiceKeyNameA(struct pipes_struct *p,
    1169             :                                   struct svcctl_GetServiceKeyNameA *r)
    1170             : {
    1171           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1172           0 :         return WERR_NOT_SUPPORTED;
    1173             : }
    1174             : 
    1175           0 : WERROR _svcctl_GetCurrentGroupeStateW(struct pipes_struct *p,
    1176             :                                       struct svcctl_GetCurrentGroupeStateW *r)
    1177             : {
    1178           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1179           0 :         return WERR_NOT_SUPPORTED;
    1180             : }
    1181             : 
    1182           0 : WERROR _svcctl_EnumServiceGroupW(struct pipes_struct *p,
    1183             :                                  struct svcctl_EnumServiceGroupW *r)
    1184             : {
    1185           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1186           0 :         return WERR_NOT_SUPPORTED;
    1187             : }
    1188             : 
    1189           0 : WERROR _svcctl_ChangeServiceConfig2A(struct pipes_struct *p,
    1190             :                                      struct svcctl_ChangeServiceConfig2A *r)
    1191             : {
    1192           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1193           0 :         return WERR_NOT_SUPPORTED;
    1194             : }
    1195             : 
    1196           0 : WERROR _svcctl_ChangeServiceConfig2W(struct pipes_struct *p,
    1197             :                                      struct svcctl_ChangeServiceConfig2W *r)
    1198             : {
    1199           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1200           0 :         return WERR_NOT_SUPPORTED;
    1201             : }
    1202             : 
    1203           0 : WERROR _svcctl_QueryServiceConfig2A(struct pipes_struct *p,
    1204             :                                     struct svcctl_QueryServiceConfig2A *r)
    1205             : {
    1206           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1207           0 :         return WERR_NOT_SUPPORTED;
    1208             : }
    1209             : 
    1210           0 : WERROR _EnumServicesStatusExA(struct pipes_struct *p,
    1211             :                               struct EnumServicesStatusExA *r)
    1212             : {
    1213           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1214           0 :         return WERR_NOT_SUPPORTED;
    1215             : }
    1216             : 
    1217           0 : WERROR _EnumServicesStatusExW(struct pipes_struct *p,
    1218             :                               struct EnumServicesStatusExW *r)
    1219             : {
    1220           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1221           0 :         return WERR_NOT_SUPPORTED;
    1222             : }
    1223             : 
    1224           0 : WERROR _svcctl_SCSendTSMessage(struct pipes_struct *p,
    1225             :                                struct svcctl_SCSendTSMessage *r)
    1226             : {
    1227           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1228           0 :         return WERR_NOT_SUPPORTED;
    1229             : }
    1230             : 
    1231             : static NTSTATUS svcctl__op_init_server(struct dcesrv_context *dce_ctx,
    1232             :                 const struct dcesrv_endpoint_server *ep_server);
    1233             : 
    1234             : static NTSTATUS svcctl__op_shutdown_server(struct dcesrv_context *dce_ctx,
    1235             :                 const struct dcesrv_endpoint_server *ep_server);
    1236             : 
    1237             : #define DCESRV_INTERFACE_SVCCTL_INIT_SERVER \
    1238             :         svcctl_init_server
    1239             : 
    1240             : #define DCESRV_INTERFACE_SVCCTL_SHUTDOWN_SERVER \
    1241             :         svcctl_shutdown_server
    1242             : 
    1243          60 : static NTSTATUS svcctl_init_server(struct dcesrv_context *dce_ctx,
    1244             :                 const struct dcesrv_endpoint_server *ep_server)
    1245             : {
    1246          60 :         struct messaging_context *msg_ctx = global_messaging_context();
    1247             :         NTSTATUS status;
    1248             :         bool ok;
    1249             : 
    1250          60 :         status = dcesrv_init_ep_server(dce_ctx, "winreg");
    1251          60 :         if (!NT_STATUS_IS_OK(status)) {
    1252           0 :                 return status;
    1253             :         }
    1254             : 
    1255             :         /* initialize the control hooks */
    1256          60 :         init_service_op_table();
    1257             : 
    1258          60 :         ok = svcctl_init_winreg(msg_ctx);
    1259          60 :         if (!ok) {
    1260           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1261             :         }
    1262             : 
    1263          60 :         return svcctl__op_init_server(dce_ctx, ep_server);
    1264             : }
    1265             : 
    1266          19 : static NTSTATUS svcctl_shutdown_server(struct dcesrv_context *dce_ctx,
    1267             :                 const struct dcesrv_endpoint_server *ep_server)
    1268             : {
    1269          19 :         shutdown_service_op_table();
    1270             : 
    1271          19 :         return svcctl__op_shutdown_server(dce_ctx, ep_server);
    1272             : }
    1273             : 
    1274             : /* include the generated boilerplate */
    1275             : #include "librpc/gen_ndr/ndr_svcctl_scompat.c"

Generated by: LCOV version 1.13