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