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