root/source3/rpc_server/srv_svcctl_nt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. init_service_op_table
  2. find_service_by_name
  3. svcctl_access_check
  4. construct_scm_sd
  5. find_service_info_by_hnd
  6. create_open_service_handle
  7. _svcctl_OpenSCManagerW
  8. _svcctl_OpenServiceW
  9. _svcctl_CloseServiceHandle
  10. _svcctl_GetServiceDisplayNameW
  11. _svcctl_QueryServiceStatus
  12. enumerate_status
  13. _svcctl_EnumServicesStatusW
  14. _svcctl_StartServiceW
  15. _svcctl_ControlService
  16. _svcctl_EnumDependentServicesW
  17. _svcctl_QueryServiceStatusEx
  18. fill_svc_config
  19. _svcctl_QueryServiceConfigW
  20. _svcctl_QueryServiceConfig2W
  21. _svcctl_LockServiceDatabase
  22. _svcctl_UnlockServiceDatabase
  23. _svcctl_QueryServiceObjectSecurity
  24. _svcctl_SetServiceObjectSecurity
  25. _svcctl_DeleteService
  26. _svcctl_SetServiceStatus
  27. _svcctl_NotifyBootConfigStatus
  28. _svcctl_SCSetServiceBitsW
  29. _svcctl_ChangeServiceConfigW
  30. _svcctl_CreateServiceW
  31. _svcctl_QueryServiceLockStatusW
  32. _svcctl_GetServiceKeyNameW
  33. _svcctl_SCSetServiceBitsA
  34. _svcctl_ChangeServiceConfigA
  35. _svcctl_CreateServiceA
  36. _svcctl_EnumDependentServicesA
  37. _svcctl_EnumServicesStatusA
  38. _svcctl_OpenSCManagerA
  39. _svcctl_OpenServiceA
  40. _svcctl_QueryServiceConfigA
  41. _svcctl_QueryServiceLockStatusA
  42. _svcctl_StartServiceA
  43. _svcctl_GetServiceDisplayNameA
  44. _svcctl_GetServiceKeyNameA
  45. _svcctl_GetCurrentGroupeStateW
  46. _svcctl_EnumServiceGroupW
  47. _svcctl_ChangeServiceConfig2A
  48. _svcctl_ChangeServiceConfig2W
  49. _svcctl_QueryServiceConfig2A
  50. _EnumServicesStatusExA
  51. _EnumServicesStatusExW
  52. _svcctl_SCSendTSMessage

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

/* [<][>][^][v][top][bottom][index][help] */