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