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 master 2b515b7d Lines: 302 596 50.7 %
Date: 2024-02-28 12:06:22 Functions: 27 73 37.0 %

          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         128 : bool init_service_op_table( void )
      76             : {
      77         128 :         const char **service_list = lp_svcctl_list();
      78         128 :         int num_services = SVCCTL_NUM_INTERNAL_SERVICES + str_list_length( service_list );
      79           0 :         int i;
      80             : 
      81         128 :         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         128 :         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         128 :         svcctl_ops[i].name = talloc_strdup( svcctl_ops, "Spooler" );
      96         128 :         svcctl_ops[i].ops  = &spoolss_svc_ops;
      97         128 :         i++;
      98             : 
      99         128 :         svcctl_ops[i].name = talloc_strdup( svcctl_ops, "NETLOGON" );
     100         128 :         svcctl_ops[i].ops  = &netlogon_svc_ops;
     101         128 :         i++;
     102             : 
     103         128 :         svcctl_ops[i].name = talloc_strdup( svcctl_ops, "RemoteRegistry" );
     104         128 :         svcctl_ops[i].ops  = &winreg_svc_ops;
     105         128 :         i++;
     106             : 
     107         128 :         svcctl_ops[i].name = talloc_strdup( svcctl_ops, "WINS" );
     108         128 :         svcctl_ops[i].ops  = &wins_svc_ops;
     109         128 :         i++;
     110             : 
     111             :         /* NULL terminate the array */
     112             : 
     113         128 :         svcctl_ops[i].name = NULL;
     114         128 :         svcctl_ops[i].ops  = NULL;
     115             : 
     116         128 :         return True;
     117             : }
     118             : 
     119         128 : bool shutdown_service_op_table(void)
     120             : {
     121         128 :         TALLOC_FREE(svcctl_ops);
     122             : 
     123         128 :         return true;
     124             : }
     125             : 
     126             : /********************************************************************
     127             : ********************************************************************/
     128             : 
     129          48 : static struct service_control_op* find_service_by_name( const char *name )
     130             : {
     131           0 :         int i;
     132             : 
     133          48 :         for ( i=0; svcctl_ops[i].name; i++ ) {
     134          48 :                 if ( strequal( name, svcctl_ops[i].name ) )
     135          48 :                         return &svcctl_ops[i];
     136             :         }
     137             : 
     138           0 :         return NULL;
     139             : }
     140             : /********************************************************************
     141             : ********************************************************************/
     142             : 
     143         104 : 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           0 :         NTSTATUS status;
     147         104 :         if ( geteuid() == sec_initial_uid() ) {
     148         104 :                 DEBUG(5,("svcctl_access_check: using root's token\n"));
     149         104 :                 status = get_root_nt_token(&token);
     150         104 :                 if(!NT_STATUS_IS_OK(status)) {
     151           0 :                         return status;
     152             :                 }
     153             :         }
     154             : 
     155         104 :         return se_access_check( sec_desc, token, access_desired, access_granted);
     156             : }
     157             : 
     158             : /********************************************************************
     159             : ********************************************************************/
     160             : 
     161          56 : static struct security_descriptor* construct_scm_sd( TALLOC_CTX *ctx )
     162             : {
     163           0 :         struct security_ace ace[2];
     164          56 :         size_t i = 0;
     165           0 :         struct security_descriptor *sd;
     166           0 :         struct security_acl *theacl;
     167           0 :         size_t sd_size;
     168             : 
     169             :         /* basic access for Everyone */
     170             : 
     171          56 :         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          56 :         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          56 :         if ( !(theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
     183           0 :                 return NULL;
     184             : 
     185          56 :         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          56 :         return sd;
     191             : }
     192             : 
     193             : /******************************************************************
     194             :  Find a registry key handle and return a SERVICE_INFO
     195             :  *****************************************************************/
     196             : 
     197         148 : static SERVICE_INFO *find_service_info_by_hnd(struct pipes_struct *p,
     198             :                                               struct policy_handle *hnd)
     199             : {
     200         148 :         SERVICE_INFO *service_info = NULL;
     201           0 :         NTSTATUS status;
     202             : 
     203         148 :         service_info = find_policy_by_hnd(p,
     204             :                                           hnd,
     205             :                                           DCESRV_HANDLE_ANY,
     206             :                                           SERVICE_INFO,
     207           0 :                                           &status);
     208         148 :         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         148 :         return service_info;
     214             : }
     215             : 
     216             : /******************************************************************
     217             :  *****************************************************************/
     218             : 
     219         104 : 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         104 :         SERVICE_INFO *info = NULL;
     226         104 :         WERROR result = WERR_OK;
     227           0 :         struct service_control_op *s_op;
     228             : 
     229         104 :         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         104 :         info->type = SVC_HANDLE_IS_SCM;
     235             : 
     236         104 :         switch ( type ) {
     237          56 :         case SVC_HANDLE_IS_SCM:
     238          56 :                 info->type = SVC_HANDLE_IS_SCM;
     239          56 :                 break;
     240             : 
     241           0 :         case SVC_HANDLE_IS_DBLOCK:
     242           0 :                 info->type = SVC_HANDLE_IS_DBLOCK;
     243           0 :                 break;
     244             : 
     245          48 :         case SVC_HANDLE_IS_SERVICE:
     246          48 :                 info->type = SVC_HANDLE_IS_SERVICE;
     247             : 
     248             :                 /* lookup the SERVICE_CONTROL_OPS */
     249             : 
     250          48 :                 if ( !(s_op = find_service_by_name( service )) ) {
     251           0 :                         result = WERR_SERVICE_DOES_NOT_EXIST;
     252           0 :                         goto done;
     253             :                 }
     254             : 
     255          48 :                 info->ops = s_op->ops;
     256             : 
     257          48 :                 if ( !(info->name  = talloc_strdup( info, s_op->name )) ) {
     258           0 :                         result = WERR_NOT_ENOUGH_MEMORY;
     259           0 :                         goto done;
     260             :                 }
     261          48 :                 break;
     262             : 
     263           0 :         default:
     264           0 :                 result = WERR_SERVICE_DOES_NOT_EXIST;
     265           0 :                 goto done;
     266             :         }
     267             : 
     268         104 :         info->access_granted = access_granted;
     269             : 
     270             :         /* store the SERVICE_INFO and create an open handle */
     271             : 
     272         104 :         if ( !create_policy_hnd( p, handle, 0, info ) ) {
     273           0 :                 result = WERR_ACCESS_DENIED;
     274           0 :                 goto done;
     275             :         }
     276             : 
     277         104 : done:
     278         104 :         if ( !W_ERROR_IS_OK(result) )
     279           0 :                 TALLOC_FREE(info);
     280             : 
     281         104 :         return result;
     282             : }
     283             : 
     284             : /********************************************************************
     285             :  _svcctl_OpenSCManagerW
     286             : ********************************************************************/
     287             : 
     288          56 : WERROR _svcctl_OpenSCManagerW(struct pipes_struct *p,
     289             :                               struct svcctl_OpenSCManagerW *r)
     290             : {
     291          56 :         struct dcesrv_call_state *dce_call = p->dce_call;
     292           0 :         struct auth_session_info *session_info =
     293          56 :                 dcesrv_call_session_info(dce_call);
     294           0 :         struct security_descriptor *sec_desc;
     295          56 :         uint32_t access_granted = 0;
     296           0 :         NTSTATUS status;
     297             : 
     298             :         /* perform access checks */
     299             : 
     300          56 :         if ( !(sec_desc = construct_scm_sd( p->mem_ctx )) )
     301           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     302             : 
     303          56 :         se_map_generic( &r->in.access_mask, &scm_generic_map );
     304          56 :         status = svcctl_access_check( sec_desc, session_info->security_token,
     305             :                                       r->in.access_mask, &access_granted );
     306          56 :         if ( !NT_STATUS_IS_OK(status) )
     307           0 :                 return ntstatus_to_werror( status );
     308             : 
     309          56 :         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          48 : WERROR _svcctl_OpenServiceW(struct pipes_struct *p,
     317             :                             struct svcctl_OpenServiceW *r)
     318             : {
     319          48 :         struct dcesrv_call_state *dce_call = p->dce_call;
     320           0 :         struct auth_session_info *session_info =
     321          48 :                 dcesrv_call_session_info(dce_call);
     322           0 :         struct security_descriptor *sec_desc;
     323          48 :         uint32_t access_granted = 0;
     324           0 :         NTSTATUS status;
     325          48 :         const char *service = NULL;
     326           0 :         WERROR err;
     327             : 
     328          48 :         service = r->in.ServiceName;
     329          48 :         if (!service) {
     330           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     331             :         }
     332          48 :         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          48 :         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          48 :         err = svcctl_get_secdesc(p->msg_ctx,
     344             :                                  get_session_info_system(),
     345             :                                  service,
     346             :                                  p->mem_ctx,
     347             :                                  &sec_desc);
     348          48 :         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          48 :         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          48 :         se_map_generic( &r->in.access_mask, &svc_generic_map );
     359          48 :         status = svcctl_access_check( sec_desc, session_info->security_token,
     360             :                                       r->in.access_mask, &access_granted );
     361          48 :         if ( !NT_STATUS_IS_OK(status) )
     362           0 :                 return ntstatus_to_werror( status );
     363             : 
     364          48 :         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          80 : WERROR _svcctl_CloseServiceHandle(struct pipes_struct *p,
     372             :                                   struct svcctl_CloseServiceHandle *r)
     373             : {
     374          80 :         if ( !close_policy_hnd( p, r->in.handle ) )
     375           0 :                 return  WERR_INVALID_HANDLE;
     376             : 
     377          80 :         ZERO_STRUCTP(r->out.handle);
     378             : 
     379          80 :         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           0 :         const char *service;
     393           0 :         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           4 : WERROR _svcctl_QueryServiceStatus(struct pipes_struct *p,
     422             :                                   struct svcctl_QueryServiceStatus *r)
     423             : {
     424           4 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     425             : 
     426             :         /* perform access checks */
     427             : 
     428           4 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     429           0 :                 return WERR_INVALID_HANDLE;
     430             : 
     431           4 :         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           4 :         return info->ops->service_status( info->name, r->out.service_status );
     437             : }
     438             : 
     439             : /********************************************************************
     440             : ********************************************************************/
     441             : 
     442           8 : 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           8 :         int num_services = 0;
     448           0 :         int i;
     449           0 :         struct ENUM_SERVICE_STATUSW *st;
     450           0 :         const char *display_name;
     451             : 
     452             :         /* just count */
     453          40 :         while ( svcctl_ops[num_services].name )
     454          32 :                 num_services++;
     455             : 
     456           8 :         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          40 :         for ( i=0; i<num_services; i++ ) {
     462          32 :                 st[i].service_name = talloc_strdup(st, svcctl_ops[i].name );
     463             : 
     464          32 :                 display_name = svcctl_lookup_dispname(ctx,
     465             :                                                       msg_ctx,
     466             :                                                       session_info,
     467          32 :                                                       svcctl_ops[i].name);
     468          32 :                 st[i].display_name = talloc_strdup(st, display_name ? display_name : "");
     469             : 
     470          32 :                 svcctl_ops[i].ops->service_status( svcctl_ops[i].name, &st[i].status );
     471             :         }
     472             : 
     473           8 :         *status = st;
     474             : 
     475           8 :         return num_services;
     476             : }
     477             : 
     478             : /********************************************************************
     479             :  _svcctl_EnumServicesStatusW
     480             : ********************************************************************/
     481             : 
     482           8 : WERROR _svcctl_EnumServicesStatusW(struct pipes_struct *p,
     483             :                                    struct svcctl_EnumServicesStatusW *r)
     484             : {
     485           8 :         struct dcesrv_call_state *dce_call = p->dce_call;
     486           0 :         struct auth_session_info *session_info =
     487           8 :                 dcesrv_call_session_info(dce_call);
     488           8 :         struct ENUM_SERVICE_STATUSW *services = NULL;
     489           0 :         int num_services;
     490           8 :         int i = 0;
     491           8 :         size_t buffer_size = 0;
     492           8 :         WERROR result = WERR_OK;
     493           8 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     494           8 :         DATA_BLOB blob = data_blob_null;
     495             : 
     496             :         /* perform access checks */
     497             : 
     498           8 :         if ( !info || (info->type != SVC_HANDLE_IS_SCM) )
     499           0 :                 return WERR_INVALID_HANDLE;
     500             : 
     501           8 :         if ( !(info->access_granted & SC_RIGHT_MGR_ENUMERATE_SERVICE) ) {
     502           0 :                 return WERR_ACCESS_DENIED;
     503             :         }
     504             : 
     505           8 :         num_services = enumerate_status(p->mem_ctx,
     506             :                                         p->msg_ctx,
     507             :                                         session_info,
     508             :                                         &services);
     509           8 :         if (num_services == -1 ) {
     510           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     511             :         }
     512             : 
     513          40 :         for ( i=0; i<num_services; i++ ) {
     514          32 :                 buffer_size += ndr_size_ENUM_SERVICE_STATUSW(&services[i], 0);
     515             :         }
     516             : 
     517           8 :         buffer_size += buffer_size % 4;
     518             : 
     519           8 :         if (buffer_size > r->in.offered) {
     520           4 :                 num_services = 0;
     521           4 :                 result = WERR_MORE_DATA;
     522             :         }
     523             : 
     524           8 :         if ( W_ERROR_IS_OK(result) ) {
     525             : 
     526           0 :                 enum ndr_err_code ndr_err;
     527           0 :                 struct ndr_push *ndr;
     528             : 
     529           4 :                 ndr = ndr_push_init_ctx(p->mem_ctx);
     530           4 :                 if (ndr == NULL) {
     531           0 :                         return WERR_INVALID_PARAMETER;
     532             :                 }
     533             : 
     534           4 :                 ndr_err = ndr_push_ENUM_SERVICE_STATUSW_array(
     535             :                         ndr, num_services, services);
     536           4 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     537           0 :                         return ntstatus_to_werror(ndr_map_error2ntstatus(ndr_err));
     538             :                 }
     539           4 :                 blob = ndr_push_blob(ndr);
     540           4 :                 memcpy(r->out.service, blob.data, MIN(blob.length, r->in.offered));
     541             :         }
     542             : 
     543           8 :         *r->out.needed                       = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
     544           8 :         *r->out.services_returned    = (uint32_t)num_services;
     545           8 :         if (r->out.resume_handle) {
     546           8 :                 *r->out.resume_handle        = 0;
     547             :         }
     548             : 
     549           8 :         return result;
     550             : }
     551             : 
     552             : /********************************************************************
     553             :  _svcctl_StartServiceW
     554             : ********************************************************************/
     555             : 
     556           4 : WERROR _svcctl_StartServiceW(struct pipes_struct *p,
     557             :                              struct svcctl_StartServiceW *r)
     558             : {
     559           4 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     560             : 
     561             :         /* perform access checks */
     562             : 
     563           4 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     564           0 :                 return WERR_INVALID_HANDLE;
     565             : 
     566           4 :         if ( !(info->access_granted & SC_RIGHT_SVC_START) )
     567           0 :                 return WERR_ACCESS_DENIED;
     568             : 
     569           4 :         return info->ops->start_service( info->name );
     570             : }
     571             : 
     572             : /********************************************************************
     573             :  _svcctl_ControlService
     574             : ********************************************************************/
     575             : 
     576           4 : WERROR _svcctl_ControlService(struct pipes_struct *p,
     577             :                               struct svcctl_ControlService *r)
     578             : {
     579           4 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     580             : 
     581             :         /* perform access checks */
     582             : 
     583           4 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     584           0 :                 return WERR_INVALID_HANDLE;
     585             : 
     586           4 :         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           4 :         default:
     601           4 :                 return WERR_INVALID_PARAMETER;
     602             :         }
     603             : }
     604             : 
     605             : /********************************************************************
     606             :  _svcctl_EnumDependentServicesW
     607             : ********************************************************************/
     608             : 
     609          16 : WERROR _svcctl_EnumDependentServicesW(struct pipes_struct *p,
     610             :                                       struct svcctl_EnumDependentServicesW *r)
     611             : {
     612          16 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.service );
     613             : 
     614             :         /* perform access checks */
     615             : 
     616          16 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     617           0 :                 return WERR_INVALID_HANDLE;
     618             : 
     619          16 :         if ( !(info->access_granted & SC_RIGHT_SVC_ENUMERATE_DEPENDENTS) )
     620           0 :                 return WERR_ACCESS_DENIED;
     621             : 
     622          16 :         switch (r->in.state) {
     623          12 :         case SERVICE_STATE_ACTIVE:
     624             :         case SERVICE_STATE_INACTIVE:
     625             :         case SERVICE_STATE_ALL:
     626          12 :                 break;
     627           4 :         default:
     628           4 :                 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          12 :         *r->out.needed = r->in.offered;
     636             : 
     637             :         /* no dependent services...basically a stub function */
     638          12 :         *r->out.services_returned = 0;
     639             : 
     640          12 :         return WERR_OK;
     641             : }
     642             : 
     643             : /********************************************************************
     644             :  _svcctl_QueryServiceStatusEx
     645             : ********************************************************************/
     646             : 
     647           8 : WERROR _svcctl_QueryServiceStatusEx(struct pipes_struct *p,
     648             :                                     struct svcctl_QueryServiceStatusEx *r)
     649             : {
     650           8 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     651           0 :         uint32_t buffer_size;
     652             : 
     653             :         /* perform access checks */
     654             : 
     655           8 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     656           0 :                 return WERR_INVALID_HANDLE;
     657             : 
     658           8 :         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           8 :         *r->out.needed = r->in.offered;
     664             : 
     665           8 :         switch ( r->in.info_level ) {
     666           8 :                 case SVC_STATUS_PROCESS_INFO:
     667             :                 {
     668           0 :                         struct SERVICE_STATUS_PROCESS svc_stat_proc;
     669           0 :                         enum ndr_err_code ndr_err;
     670           0 :                         DATA_BLOB blob;
     671             : 
     672             :                         /* Get the status of the service.. */
     673           8 :                         info->ops->service_status( info->name, &svc_stat_proc.status );
     674           8 :                         svc_stat_proc.process_id     = getpid();
     675           8 :                         svc_stat_proc.service_flags  = 0x0;
     676             : 
     677           8 :                         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           8 :                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     680           0 :                                 return WERR_INVALID_PARAMETER;
     681             :                         }
     682             : 
     683           8 :                         r->out.buffer = blob.data;
     684           8 :                         buffer_size = sizeof(struct SERVICE_STATUS_PROCESS);
     685           8 :                         break;
     686             :                 }
     687             : 
     688           0 :                 default:
     689           0 :                         return WERR_INVALID_LEVEL;
     690             :         }
     691             : 
     692             : 
     693           8 :         buffer_size += buffer_size % 4;
     694           8 :         *r->out.needed = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
     695             : 
     696           8 :         if (buffer_size > r->in.offered ) {
     697           4 :                 return WERR_INSUFFICIENT_BUFFER;
     698             :         }
     699             : 
     700           4 :         return WERR_OK;
     701             : }
     702             : 
     703             : /********************************************************************
     704             : ********************************************************************/
     705             : 
     706          16 : 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          16 :         const char *result = NULL;
     713             : 
     714             :         /* now fill in the individual values */
     715             : 
     716          16 :         ZERO_STRUCTP(config);
     717             : 
     718          16 :         config->displayname = svcctl_lookup_dispname(mem_ctx,
     719             :                                                      msg_ctx,
     720             :                                                      session_info,
     721             :                                                      name);
     722             : 
     723          16 :         result = svcctl_get_string_value(mem_ctx,
     724             :                                          msg_ctx,
     725             :                                          session_info,
     726             :                                          name,
     727             :                                          "ObjectName");
     728          16 :         if (result != NULL) {
     729          16 :                 config->startname = result;
     730             :         }
     731             : 
     732          16 :         result = svcctl_get_string_value(mem_ctx,
     733             :                                          msg_ctx,
     734             :                                          session_info,
     735             :                                          name,
     736             :                                          "ImagePath");
     737          16 :         if (result != NULL) {
     738          16 :                 config->executablepath = result;
     739             :         }
     740             : 
     741             :         /* a few hard coded values */
     742             :         /* loadordergroup and dependencies are empty */
     743             : 
     744          16 :         config->tag_id           = 0x00000000;                       /* unassigned loadorder group */
     745          16 :         config->service_type     = SERVICE_TYPE_WIN32_OWN_PROCESS;
     746          16 :         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          16 :         if ( strequal( name, "NETLOGON" ) && ( lp_servicenumber(name) == -1 ) )
     753           0 :                 config->start_type = SVCCTL_DISABLED;
     754          16 :         else if ( strequal( name, "WINS" ) && ( !lp_we_are_a_wins_server() ))
     755           0 :                 config->start_type = SVCCTL_DISABLED;
     756             :         else
     757          16 :                 config->start_type = SVCCTL_DEMAND_START;
     758             : 
     759          16 :         return WERR_OK;
     760             : }
     761             : 
     762             : /********************************************************************
     763             :  _svcctl_QueryServiceConfigW
     764             : ********************************************************************/
     765             : 
     766          16 : WERROR _svcctl_QueryServiceConfigW(struct pipes_struct *p,
     767             :                                    struct svcctl_QueryServiceConfigW *r)
     768             : {
     769          16 :         struct dcesrv_call_state *dce_call = p->dce_call;
     770           0 :         struct auth_session_info *session_info =
     771          16 :                 dcesrv_call_session_info(dce_call);
     772          16 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     773           0 :         uint32_t buffer_size;
     774           0 :         WERROR wresult;
     775             : 
     776             :         /* perform access checks */
     777             : 
     778          16 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     779           0 :                 return WERR_INVALID_HANDLE;
     780             : 
     781          16 :         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          16 :         *r->out.needed = r->in.offered;
     788             : 
     789          16 :         wresult = fill_svc_config(p->mem_ctx,
     790             :                                   p->msg_ctx,
     791             :                                   session_info,
     792          16 :                                   info->name,
     793             :                                   r->out.query);
     794          16 :         if ( !W_ERROR_IS_OK(wresult) )
     795           0 :                 return wresult;
     796             : 
     797          16 :         buffer_size = ndr_size_QUERY_SERVICE_CONFIG(r->out.query, 0);
     798          16 :         *r->out.needed = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
     799             : 
     800          16 :         if (buffer_size > r->in.offered ) {
     801           8 :                 ZERO_STRUCTP(r->out.query);
     802           8 :                 return WERR_INSUFFICIENT_BUFFER;
     803             :         }
     804             : 
     805           8 :         return WERR_OK;
     806             : }
     807             : 
     808             : /********************************************************************
     809             :  _svcctl_QueryServiceConfig2W
     810             : ********************************************************************/
     811             : 
     812          16 : WERROR _svcctl_QueryServiceConfig2W(struct pipes_struct *p,
     813             :                                     struct svcctl_QueryServiceConfig2W *r)
     814             : {
     815          16 :         struct dcesrv_call_state *dce_call = p->dce_call;
     816           0 :         struct auth_session_info *session_info =
     817          16 :                 dcesrv_call_session_info(dce_call);
     818          16 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     819           0 :         uint32_t buffer_size;
     820          16 :         DATA_BLOB blob = data_blob_null;
     821             : 
     822             :         /* perform access checks */
     823             : 
     824          16 :         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
     825           0 :                 return WERR_INVALID_HANDLE;
     826             : 
     827          16 :         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          16 :         *r->out.needed = r->in.offered;
     833             : 
     834          16 :         switch ( r->in.info_level ) {
     835           8 :         case SERVICE_CONFIG_DESCRIPTION:
     836             :                 {
     837           0 :                         struct SERVICE_DESCRIPTION desc_buf;
     838           0 :                         const char *description;
     839           0 :                         enum ndr_err_code ndr_err;
     840             : 
     841           8 :                         description = svcctl_lookup_description(p->mem_ctx,
     842             :                                                                 p->msg_ctx,
     843             :                                                                 session_info,
     844           8 :                                                                 info->name);
     845             : 
     846           8 :                         desc_buf.description = description;
     847             : 
     848           8 :                         ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &desc_buf,
     849             :                                                        (ndr_push_flags_fn_t)ndr_push_SERVICE_DESCRIPTION);
     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           8 :         case SERVICE_CONFIG_FAILURE_ACTIONS:
     858             :                 {
     859           0 :                         struct SERVICE_FAILURE_ACTIONSW actions;
     860           0 :                         enum ndr_err_code ndr_err;
     861             : 
     862             :                         /* nothing to say...just service the request */
     863             : 
     864           8 :                         ZERO_STRUCT( actions );
     865             : 
     866           8 :                         ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &actions,
     867             :                                                        (ndr_push_flags_fn_t)ndr_push_SERVICE_FAILURE_ACTIONSW);
     868           8 :                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     869           0 :                                 return WERR_INVALID_PARAMETER;
     870             :                         }
     871             : 
     872           8 :                         break;
     873             :                 }
     874             :                 break;
     875             : 
     876           0 :         default:
     877           0 :                 return WERR_INVALID_LEVEL;
     878             :         }
     879             : 
     880          16 :         buffer_size = blob.length;
     881          16 :         buffer_size += buffer_size % 4;
     882          16 :         *r->out.needed = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
     883             : 
     884          16 :         if (buffer_size > r->in.offered)
     885           8 :                 return WERR_INSUFFICIENT_BUFFER;
     886             : 
     887           8 :         memcpy(r->out.buffer, blob.data, blob.length);
     888             : 
     889           8 :         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          20 : WERROR _svcctl_QueryServiceObjectSecurity(struct pipes_struct *p,
     935             :                                           struct svcctl_QueryServiceObjectSecurity *r)
     936             : {
     937          20 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
     938           0 :         struct security_descriptor *sec_desc;
     939           0 :         NTSTATUS status;
     940          20 :         uint8_t *buffer = NULL;
     941          20 :         size_t len = 0;
     942           0 :         WERROR err;
     943             : 
     944             : 
     945             :         /* only support the SCM and individual services */
     946             : 
     947          20 :         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          20 :         if ( !(info->access_granted & SEC_STD_READ_CONTROL) )
     953           0 :                 return WERR_ACCESS_DENIED;
     954             : 
     955             :         /* TODO: handle something besides SECINFO_DACL */
     956             : 
     957          20 :         if ( (r->in.security_flags & SECINFO_DACL) != SECINFO_DACL )
     958           4 :                 return WERR_INVALID_PARAMETER;
     959             : 
     960             :         /* Lookup the security descriptor and marshall it up for a reply */
     961          16 :         err = svcctl_get_secdesc(p->msg_ctx,
     962             :                                  get_session_info_system(),
     963          16 :                                  info->name,
     964             :                                  p->mem_ctx,
     965             :                                  &sec_desc);
     966          16 :         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          16 :         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          16 :         *r->out.needed = ndr_size_security_descriptor(sec_desc, 0);
     977             : 
     978          16 :         if ( *r->out.needed > r->in.offered) {
     979           8 :                 return WERR_INSUFFICIENT_BUFFER;
     980             :         }
     981             : 
     982           8 :         status = marshall_sec_desc(p->mem_ctx, sec_desc, &buffer, &len);
     983           8 :         if (!NT_STATUS_IS_OK(status)) {
     984           0 :                 return ntstatus_to_werror(status);
     985             :         }
     986             : 
     987           8 :         *r->out.needed = len;
     988           8 :         memcpy(r->out.buffer, buffer, len);
     989             : 
     990           8 :         return WERR_OK;
     991             : }
     992             : 
     993             : /********************************************************************
     994             :  _svcctl_SetServiceObjectSecurity
     995             : ********************************************************************/
     996             : 
     997           4 : WERROR _svcctl_SetServiceObjectSecurity(struct pipes_struct *p,
     998             :                                         struct svcctl_SetServiceObjectSecurity *r)
     999             : {
    1000           4 :         struct dcesrv_call_state *dce_call = p->dce_call;
    1001           0 :         struct auth_session_info *session_info =
    1002           4 :                 dcesrv_call_session_info(dce_call);
    1003           4 :         SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
    1004           4 :         struct security_descriptor *sec_desc = NULL;
    1005           0 :         uint32_t required_access;
    1006           0 :         NTSTATUS status;
    1007             : 
    1008           4 :         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           4 :         if ( info->type == SVC_HANDLE_IS_SCM )
    1014           0 :                 return WERR_ACCESS_DENIED;
    1015             : 
    1016             :         /* check the access on the open handle */
    1017             : 
    1018           4 :         switch ( r->in.security_flags ) {
    1019           4 :                 case SECINFO_DACL:
    1020           4 :                         required_access = SEC_STD_WRITE_DAC;
    1021           4 :                         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           4 :         if ( !(info->access_granted & required_access) )
    1035           0 :                 return WERR_ACCESS_DENIED;
    1036             : 
    1037             :         /* read the security descfriptor */
    1038             : 
    1039           4 :         status = unmarshall_sec_desc(p->mem_ctx,
    1040             :                                      r->in.buffer,
    1041           4 :                                      r->in.offered,
    1042             :                                      &sec_desc);
    1043           4 :         if (!NT_STATUS_IS_OK(status)) {
    1044           0 :                 return ntstatus_to_werror(status);
    1045             :         }
    1046             : 
    1047             :         /* store the new SD */
    1048             : 
    1049           4 :         if (!svcctl_set_secdesc(p->msg_ctx, session_info, info->name, sec_desc))
    1050           0 :                 return WERR_ACCESS_DENIED;
    1051             : 
    1052           4 :         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           4 : WERROR _svcctl_ChangeServiceConfigW(struct pipes_struct *p,
    1085             :                                     struct svcctl_ChangeServiceConfigW *r)
    1086             : {
    1087           4 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1088           4 :         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 _svcctl_EnumServicesStatusExA(struct pipes_struct *p,
    1232             :                                      struct svcctl_EnumServicesStatusExA *r)
    1233             : {
    1234           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1235           0 :         return WERR_NOT_SUPPORTED;
    1236             : }
    1237             : 
    1238           0 : WERROR _svcctl_EnumServicesStatusExW(struct pipes_struct *p,
    1239             :                                      struct svcctl_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             : /****************************************************************
    1253             :  _svcctl_CreateServiceWOW64A
    1254             : ****************************************************************/
    1255             : 
    1256           0 : WERROR _svcctl_CreateServiceWOW64A(struct pipes_struct *p,
    1257             :                                    struct svcctl_CreateServiceWOW64A *r)
    1258             : {
    1259           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1260           0 :         return WERR_NOT_SUPPORTED;
    1261             : }
    1262             : 
    1263             : 
    1264             : /****************************************************************
    1265             :  _svcctl_CreateServiceWOW64W
    1266             : ****************************************************************/
    1267             : 
    1268           0 : WERROR _svcctl_CreateServiceWOW64W(struct pipes_struct *p,
    1269             :                                    struct svcctl_CreateServiceWOW64W *r)
    1270             : {
    1271           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1272           0 :         return WERR_NOT_SUPPORTED;
    1273             : }
    1274             : 
    1275             : 
    1276             : /****************************************************************
    1277             :  _Opnum46NotUsedOnWire
    1278             : ****************************************************************/
    1279             : 
    1280           0 : void _Opnum46NotUsedOnWire(struct pipes_struct *p,
    1281             :                            struct Opnum46NotUsedOnWire *r)
    1282             : {
    1283           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1284           0 : }
    1285             : 
    1286             : 
    1287             : /****************************************************************
    1288             :  _svcctl_NotifyServiceStatusChange
    1289             : ****************************************************************/
    1290             : 
    1291           0 : WERROR _svcctl_NotifyServiceStatusChange(struct pipes_struct *p,
    1292             :                                          struct svcctl_NotifyServiceStatusChange *r)
    1293             : {
    1294           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1295           0 :         return WERR_NOT_SUPPORTED;
    1296             : }
    1297             : 
    1298             : 
    1299             : /****************************************************************
    1300             :  _svcctl_GetNotifyResults
    1301             : ****************************************************************/
    1302             : 
    1303           0 : WERROR _svcctl_GetNotifyResults(struct pipes_struct *p,
    1304             :                                 struct svcctl_GetNotifyResults *r)
    1305             : {
    1306           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1307           0 :         return WERR_NOT_SUPPORTED;
    1308             : }
    1309             : 
    1310             : 
    1311             : /****************************************************************
    1312             :  _svcctl_CloseNotifyHandle
    1313             : ****************************************************************/
    1314             : 
    1315           0 : WERROR _svcctl_CloseNotifyHandle(struct pipes_struct *p,
    1316             :                                  struct svcctl_CloseNotifyHandle *r)
    1317             : {
    1318           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1319           0 :         return WERR_NOT_SUPPORTED;
    1320             : }
    1321             : 
    1322             : 
    1323             : /****************************************************************
    1324             :  _svcctl_ControlServiceExA
    1325             : ****************************************************************/
    1326             : 
    1327           0 : WERROR _svcctl_ControlServiceExA(struct pipes_struct *p,
    1328             :                                  struct svcctl_ControlServiceExA *r)
    1329             : {
    1330           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1331           0 :         return WERR_NOT_SUPPORTED;
    1332             : }
    1333             : 
    1334             : 
    1335             : /****************************************************************
    1336             :  _svcctl_ControlServiceExW
    1337             : ****************************************************************/
    1338             : 
    1339           4 : WERROR _svcctl_ControlServiceExW(struct pipes_struct *p,
    1340             :                                  struct svcctl_ControlServiceExW *r)
    1341             : {
    1342           4 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1343           4 :         return WERR_NOT_SUPPORTED;
    1344             : }
    1345             : 
    1346             : 
    1347             : /****************************************************************
    1348             :  _Opnum52NotUsedOnWire
    1349             : ****************************************************************/
    1350             : 
    1351           0 : void _Opnum52NotUsedOnWire(struct pipes_struct *p,
    1352             :                            struct Opnum52NotUsedOnWire *r)
    1353             : {
    1354           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1355           0 : }
    1356             : 
    1357             : 
    1358             : /****************************************************************
    1359             :  _Opnum53NotUsedOnWire
    1360             : ****************************************************************/
    1361             : 
    1362           0 : void _Opnum53NotUsedOnWire(struct pipes_struct *p,
    1363             :                            struct Opnum53NotUsedOnWire *r)
    1364             : {
    1365           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1366           0 : }
    1367             : 
    1368             : 
    1369             : /****************************************************************
    1370             :  _Opnum54NotUsedOnWire
    1371             : ****************************************************************/
    1372             : 
    1373           0 : void _Opnum54NotUsedOnWire(struct pipes_struct *p,
    1374             :                            struct Opnum54NotUsedOnWire *r)
    1375             : {
    1376           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1377           0 : }
    1378             : 
    1379             : 
    1380             : /****************************************************************
    1381             :  _Opnum55NotUsedOnWire
    1382             : ****************************************************************/
    1383             : 
    1384           0 : void _Opnum55NotUsedOnWire(struct pipes_struct *p,
    1385             :                            struct Opnum55NotUsedOnWire *r)
    1386             : {
    1387           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1388           0 : }
    1389             : 
    1390             : 
    1391             : /****************************************************************
    1392             :  _svcctl_QueryServiceConfigEx
    1393             : ****************************************************************/
    1394             : 
    1395           4 : WERROR _svcctl_QueryServiceConfigEx(struct pipes_struct *p,
    1396             :                                     struct svcctl_QueryServiceConfigEx *r)
    1397             : {
    1398           4 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1399           4 :         return WERR_NOT_SUPPORTED;
    1400             : }
    1401             : 
    1402             : 
    1403             : /****************************************************************
    1404             :  _Opnum57NotUsedOnWire
    1405             : ****************************************************************/
    1406             : 
    1407           0 : void _Opnum57NotUsedOnWire(struct pipes_struct *p,
    1408             :                            struct Opnum57NotUsedOnWire *r)
    1409             : {
    1410           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1411           0 : }
    1412             : 
    1413             : 
    1414             : /****************************************************************
    1415             :  _Opnum58NotUsedOnWire
    1416             : ****************************************************************/
    1417             : 
    1418           0 : void _Opnum58NotUsedOnWire(struct pipes_struct *p,
    1419             :                            struct Opnum58NotUsedOnWire *r)
    1420             : {
    1421           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1422           0 : }
    1423             : 
    1424             : 
    1425             : /****************************************************************
    1426             :  _Opnum59NotUsedOnWire
    1427             : ****************************************************************/
    1428             : 
    1429           0 : void _Opnum59NotUsedOnWire(struct pipes_struct *p,
    1430             :                            struct Opnum59NotUsedOnWire *r)
    1431             : {
    1432           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1433           0 : }
    1434             : 
    1435             : 
    1436             : /****************************************************************
    1437             :  _svcctl_CreateWowService
    1438             : ****************************************************************/
    1439             : 
    1440           0 : WERROR _svcctl_CreateWowService(struct pipes_struct *p,
    1441             :                                 struct svcctl_CreateWowService *r)
    1442             : {
    1443           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1444           0 :         return WERR_NOT_SUPPORTED;
    1445             : }
    1446             : 
    1447             : 
    1448             : /****************************************************************
    1449             :  _svcctl_OpenSCManager2
    1450             : ****************************************************************/
    1451             : 
    1452           0 : WERROR _svcctl_OpenSCManager2(struct pipes_struct *p,
    1453             :                               struct svcctl_OpenSCManager2 *r)
    1454             : {
    1455           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1456           0 :         return WERR_NOT_SUPPORTED;
    1457             : }
    1458             : 
    1459             : static NTSTATUS svcctl__op_init_server(struct dcesrv_context *dce_ctx,
    1460             :                 const struct dcesrv_endpoint_server *ep_server);
    1461             : 
    1462             : static NTSTATUS svcctl__op_shutdown_server(struct dcesrv_context *dce_ctx,
    1463             :                 const struct dcesrv_endpoint_server *ep_server);
    1464             : 
    1465             : #define DCESRV_INTERFACE_SVCCTL_INIT_SERVER \
    1466             :         svcctl_init_server
    1467             : 
    1468             : #define DCESRV_INTERFACE_SVCCTL_SHUTDOWN_SERVER \
    1469             :         svcctl_shutdown_server
    1470             : 
    1471         128 : static NTSTATUS svcctl_init_server(struct dcesrv_context *dce_ctx,
    1472             :                 const struct dcesrv_endpoint_server *ep_server)
    1473             : {
    1474         128 :         struct messaging_context *msg_ctx = global_messaging_context();
    1475           0 :         bool ok;
    1476             : 
    1477             :         /* initialize the control hooks */
    1478         128 :         init_service_op_table();
    1479             : 
    1480         128 :         ok = svcctl_init_winreg(msg_ctx);
    1481         128 :         if (!ok) {
    1482           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1483             :         }
    1484             : 
    1485         128 :         return svcctl__op_init_server(dce_ctx, ep_server);
    1486             : }
    1487             : 
    1488         128 : static NTSTATUS svcctl_shutdown_server(struct dcesrv_context *dce_ctx,
    1489             :                 const struct dcesrv_endpoint_server *ep_server)
    1490             : {
    1491         128 :         shutdown_service_op_table();
    1492             : 
    1493         128 :         return svcctl__op_shutdown_server(dce_ctx, ep_server);
    1494             : }
    1495             : 
    1496             : /* include the generated boilerplate */
    1497             : #include "librpc/gen_ndr/ndr_svcctl_scompat.c"

Generated by: LCOV version 1.14