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 v4-17-test 1498b464 Lines: 32 501 6.4 %
Date: 2024-06-13 04:01:37 Functions: 4 55 7.3 %

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

Generated by: LCOV version 1.13