Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * RPC Pipe client / server routines
4 : *
5 : * Copyright (C) Marcin Krzysztof Porwit 2005.
6 : *
7 : * Largely Rewritten (Again) by:
8 : * Copyright (C) Gerald (Jerry) Carter 2005.
9 : * Copyright (C) Guenther Deschner 2008,2009.
10 : *
11 : * This program is free software; you can redistribute it and/or modify
12 : * it under the terms of the GNU General Public License as published by
13 : * the Free Software Foundation; either version 3 of the License, or
14 : * (at your option) any later version.
15 : *
16 : * This program is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU General Public License for more details.
20 : *
21 : * You should have received a copy of the GNU General Public License
22 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 : */
24 :
25 : #include "includes.h"
26 : #include "system/passwd.h" /* uid_wrapper */
27 : #include "ntdomain.h"
28 : #include "../libcli/security/security.h"
29 : #include "../librpc/gen_ndr/ndr_security.h"
30 : #include "services/services.h"
31 : #include "services/svc_winreg_glue.h"
32 : #include "auth.h"
33 : #include "rpc_server/svcctl/srv_svcctl_nt.h"
34 :
35 : #include "rpc_server/rpc_server.h"
36 : #include "librpc/rpc/dcesrv_core.h"
37 : #include "librpc/gen_ndr/ndr_svcctl.h"
38 : #include "librpc/gen_ndr/ndr_svcctl_scompat.h"
39 : #include "srv_svcctl_reg.h"
40 : #include "lib/global_contexts.h"
41 :
42 : #undef DBGC_CLASS
43 : #define DBGC_CLASS DBGC_RPC_SRV
44 :
45 : struct service_control_op {
46 : const char *name;
47 : SERVICE_CONTROL_OPS *ops;
48 : };
49 :
50 : /* handle external services */
51 : extern SERVICE_CONTROL_OPS rcinit_svc_ops;
52 :
53 : /* builtin services (see service_db.c and services/svc_*.c */
54 : extern SERVICE_CONTROL_OPS spoolss_svc_ops;
55 : extern SERVICE_CONTROL_OPS netlogon_svc_ops;
56 : extern SERVICE_CONTROL_OPS winreg_svc_ops;
57 : extern SERVICE_CONTROL_OPS wins_svc_ops;
58 :
59 : /* make sure this number patches the number of builtin
60 : SERVICE_CONTROL_OPS structure listed above */
61 :
62 : #define SVCCTL_NUM_INTERNAL_SERVICES 4
63 :
64 : struct service_control_op *svcctl_ops;
65 :
66 : static const struct generic_mapping scm_generic_map =
67 : { SC_MANAGER_READ_ACCESS, SC_MANAGER_WRITE_ACCESS, SC_MANAGER_EXECUTE_ACCESS, SC_MANAGER_ALL_ACCESS };
68 : static const struct generic_mapping svc_generic_map =
69 : { SERVICE_READ_ACCESS, SERVICE_WRITE_ACCESS, SERVICE_EXECUTE_ACCESS, SERVICE_ALL_ACCESS };
70 :
71 :
72 : /********************************************************************
73 : ********************************************************************/
74 :
75 126 : bool init_service_op_table( void )
76 : {
77 126 : const char **service_list = lp_svcctl_list();
78 126 : int num_services = SVCCTL_NUM_INTERNAL_SERVICES + str_list_length( service_list );
79 0 : int i;
80 :
81 126 : if ( !(svcctl_ops = talloc_array( NULL, struct service_control_op, num_services+1)) ) {
82 0 : DEBUG(0,("init_service_op_table: talloc() failed!\n"));
83 0 : return False;
84 : }
85 :
86 : /* services listed in smb.conf get the rc.init interface */
87 :
88 126 : for ( i=0; service_list && service_list[i]; i++ ) {
89 0 : svcctl_ops[i].name = talloc_strdup( svcctl_ops, service_list[i] );
90 0 : svcctl_ops[i].ops = &rcinit_svc_ops;
91 : }
92 :
93 : /* add builtin services */
94 :
95 126 : svcctl_ops[i].name = talloc_strdup( svcctl_ops, "Spooler" );
96 126 : svcctl_ops[i].ops = &spoolss_svc_ops;
97 126 : i++;
98 :
99 126 : svcctl_ops[i].name = talloc_strdup( svcctl_ops, "NETLOGON" );
100 126 : svcctl_ops[i].ops = &netlogon_svc_ops;
101 126 : i++;
102 :
103 126 : svcctl_ops[i].name = talloc_strdup( svcctl_ops, "RemoteRegistry" );
104 126 : svcctl_ops[i].ops = &winreg_svc_ops;
105 126 : i++;
106 :
107 126 : svcctl_ops[i].name = talloc_strdup( svcctl_ops, "WINS" );
108 126 : svcctl_ops[i].ops = &wins_svc_ops;
109 126 : i++;
110 :
111 : /* NULL terminate the array */
112 :
113 126 : svcctl_ops[i].name = NULL;
114 126 : svcctl_ops[i].ops = NULL;
115 :
116 126 : return True;
117 : }
118 :
119 126 : bool shutdown_service_op_table(void)
120 : {
121 126 : TALLOC_FREE(svcctl_ops);
122 :
123 126 : return true;
124 : }
125 :
126 : /********************************************************************
127 : ********************************************************************/
128 :
129 48 : static struct service_control_op* find_service_by_name( const char *name )
130 : {
131 0 : int i;
132 :
133 48 : for ( i=0; svcctl_ops[i].name; i++ ) {
134 48 : if ( strequal( name, svcctl_ops[i].name ) )
135 48 : return &svcctl_ops[i];
136 : }
137 :
138 0 : return NULL;
139 : }
140 : /********************************************************************
141 : ********************************************************************/
142 :
143 104 : static NTSTATUS svcctl_access_check( struct security_descriptor *sec_desc, struct security_token *token,
144 : uint32_t access_desired, uint32_t *access_granted )
145 : {
146 0 : NTSTATUS status;
147 104 : if ( geteuid() == sec_initial_uid() ) {
148 104 : DEBUG(5,("svcctl_access_check: using root's token\n"));
149 104 : status = get_root_nt_token(&token);
150 104 : if(!NT_STATUS_IS_OK(status)) {
151 0 : return status;
152 : }
153 : }
154 :
155 104 : return se_access_check( sec_desc, token, access_desired, access_granted);
156 : }
157 :
158 : /********************************************************************
159 : ********************************************************************/
160 :
161 56 : static struct security_descriptor* construct_scm_sd( TALLOC_CTX *ctx )
162 : {
163 0 : struct security_ace ace[2];
164 56 : size_t i = 0;
165 0 : struct security_descriptor *sd;
166 0 : struct security_acl *theacl;
167 0 : size_t sd_size;
168 :
169 : /* basic access for Everyone */
170 :
171 56 : init_sec_ace(&ace[i++], &global_sid_World,
172 : SEC_ACE_TYPE_ACCESS_ALLOWED, SC_MANAGER_READ_ACCESS, 0);
173 :
174 : /* Full Access 'BUILTIN\Administrators' */
175 :
176 56 : init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
177 : SEC_ACE_TYPE_ACCESS_ALLOWED, SC_MANAGER_ALL_ACCESS, 0);
178 :
179 :
180 : /* create the security descriptor */
181 :
182 56 : if ( !(theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
183 0 : return NULL;
184 :
185 56 : if ( !(sd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
186 : SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
187 : theacl, &sd_size)) )
188 0 : return NULL;
189 :
190 56 : return sd;
191 : }
192 :
193 : /******************************************************************
194 : Find a registry key handle and return a SERVICE_INFO
195 : *****************************************************************/
196 :
197 148 : static SERVICE_INFO *find_service_info_by_hnd(struct pipes_struct *p,
198 : struct policy_handle *hnd)
199 : {
200 148 : SERVICE_INFO *service_info = NULL;
201 0 : NTSTATUS status;
202 :
203 148 : service_info = find_policy_by_hnd(p,
204 : hnd,
205 : DCESRV_HANDLE_ANY,
206 : SERVICE_INFO,
207 0 : &status);
208 148 : if (!NT_STATUS_IS_OK(status)) {
209 0 : DEBUG(2,("find_service_info_by_hnd: handle not found\n"));
210 0 : return NULL;
211 : }
212 :
213 148 : return service_info;
214 : }
215 :
216 : /******************************************************************
217 : *****************************************************************/
218 :
219 104 : static WERROR create_open_service_handle(struct pipes_struct *p,
220 : struct policy_handle *handle,
221 : uint32_t type,
222 : const char *service,
223 : uint32_t access_granted)
224 : {
225 104 : SERVICE_INFO *info = NULL;
226 104 : WERROR result = WERR_OK;
227 0 : struct service_control_op *s_op;
228 :
229 104 : if ( !(info = talloc_zero( NULL, SERVICE_INFO )) )
230 0 : return WERR_NOT_ENOUGH_MEMORY;
231 :
232 : /* the Service Manager has a NULL name */
233 :
234 104 : info->type = SVC_HANDLE_IS_SCM;
235 :
236 104 : switch ( type ) {
237 56 : case SVC_HANDLE_IS_SCM:
238 56 : info->type = SVC_HANDLE_IS_SCM;
239 56 : break;
240 :
241 0 : case SVC_HANDLE_IS_DBLOCK:
242 0 : info->type = SVC_HANDLE_IS_DBLOCK;
243 0 : break;
244 :
245 48 : case SVC_HANDLE_IS_SERVICE:
246 48 : info->type = SVC_HANDLE_IS_SERVICE;
247 :
248 : /* lookup the SERVICE_CONTROL_OPS */
249 :
250 48 : if ( !(s_op = find_service_by_name( service )) ) {
251 0 : result = WERR_SERVICE_DOES_NOT_EXIST;
252 0 : goto done;
253 : }
254 :
255 48 : info->ops = s_op->ops;
256 :
257 48 : if ( !(info->name = talloc_strdup( info, s_op->name )) ) {
258 0 : result = WERR_NOT_ENOUGH_MEMORY;
259 0 : goto done;
260 : }
261 48 : break;
262 :
263 0 : default:
264 0 : result = WERR_SERVICE_DOES_NOT_EXIST;
265 0 : goto done;
266 : }
267 :
268 104 : info->access_granted = access_granted;
269 :
270 : /* store the SERVICE_INFO and create an open handle */
271 :
272 104 : if ( !create_policy_hnd( p, handle, 0, info ) ) {
273 0 : result = WERR_ACCESS_DENIED;
274 0 : goto done;
275 : }
276 :
277 104 : done:
278 104 : if ( !W_ERROR_IS_OK(result) )
279 0 : TALLOC_FREE(info);
280 :
281 104 : return result;
282 : }
283 :
284 : /********************************************************************
285 : _svcctl_OpenSCManagerW
286 : ********************************************************************/
287 :
288 56 : WERROR _svcctl_OpenSCManagerW(struct pipes_struct *p,
289 : struct svcctl_OpenSCManagerW *r)
290 : {
291 56 : struct dcesrv_call_state *dce_call = p->dce_call;
292 0 : struct auth_session_info *session_info =
293 56 : dcesrv_call_session_info(dce_call);
294 0 : struct security_descriptor *sec_desc;
295 56 : uint32_t access_granted = 0;
296 0 : NTSTATUS status;
297 :
298 : /* perform access checks */
299 :
300 56 : if ( !(sec_desc = construct_scm_sd( p->mem_ctx )) )
301 0 : return WERR_NOT_ENOUGH_MEMORY;
302 :
303 56 : se_map_generic( &r->in.access_mask, &scm_generic_map );
304 56 : status = svcctl_access_check( sec_desc, session_info->security_token,
305 : r->in.access_mask, &access_granted );
306 56 : if ( !NT_STATUS_IS_OK(status) )
307 0 : return ntstatus_to_werror( status );
308 :
309 56 : return create_open_service_handle( p, r->out.handle, SVC_HANDLE_IS_SCM, NULL, access_granted );
310 : }
311 :
312 : /********************************************************************
313 : _svcctl_OpenServiceW
314 : ********************************************************************/
315 :
316 48 : WERROR _svcctl_OpenServiceW(struct pipes_struct *p,
317 : struct svcctl_OpenServiceW *r)
318 : {
319 48 : struct dcesrv_call_state *dce_call = p->dce_call;
320 0 : struct auth_session_info *session_info =
321 48 : dcesrv_call_session_info(dce_call);
322 0 : struct security_descriptor *sec_desc;
323 48 : uint32_t access_granted = 0;
324 0 : NTSTATUS status;
325 48 : const char *service = NULL;
326 0 : WERROR err;
327 :
328 48 : service = r->in.ServiceName;
329 48 : if (!service) {
330 0 : return WERR_NOT_ENOUGH_MEMORY;
331 : }
332 48 : DEBUG(5, ("_svcctl_OpenServiceW: Attempting to open Service [%s], \n", service));
333 :
334 : /* based on my tests you can open a service if you have a valid scm handle */
335 :
336 48 : if ( !find_service_info_by_hnd( p, r->in.scmanager_handle) )
337 0 : return WERR_INVALID_HANDLE;
338 :
339 : /*
340 : * Perform access checks. Use the system session_info in order to ensure
341 : * that we retrieve the security descriptor
342 : */
343 48 : err = svcctl_get_secdesc(p->msg_ctx,
344 : get_session_info_system(),
345 : service,
346 : p->mem_ctx,
347 : &sec_desc);
348 48 : if (W_ERROR_EQUAL(err, WERR_FILE_NOT_FOUND)) {
349 0 : DBG_NOTICE("service %s does not exist\n", service);
350 0 : return WERR_SERVICE_DOES_NOT_EXIST;
351 : }
352 48 : if (!W_ERROR_IS_OK(err)) {
353 0 : DBG_NOTICE("Failed to get a valid secdesc for %s: %s\n",
354 : service, win_errstr(err));
355 0 : return err;
356 : }
357 :
358 48 : se_map_generic( &r->in.access_mask, &svc_generic_map );
359 48 : status = svcctl_access_check( sec_desc, session_info->security_token,
360 : r->in.access_mask, &access_granted );
361 48 : if ( !NT_STATUS_IS_OK(status) )
362 0 : return ntstatus_to_werror( status );
363 :
364 48 : return create_open_service_handle( p, r->out.handle, SVC_HANDLE_IS_SERVICE, service, access_granted );
365 : }
366 :
367 : /********************************************************************
368 : _svcctl_CloseServiceHandle
369 : ********************************************************************/
370 :
371 80 : WERROR _svcctl_CloseServiceHandle(struct pipes_struct *p,
372 : struct svcctl_CloseServiceHandle *r)
373 : {
374 80 : if ( !close_policy_hnd( p, r->in.handle ) )
375 0 : return WERR_INVALID_HANDLE;
376 :
377 80 : ZERO_STRUCTP(r->out.handle);
378 :
379 80 : return WERR_OK;
380 : }
381 :
382 : /********************************************************************
383 : _svcctl_GetServiceDisplayNameW
384 : ********************************************************************/
385 :
386 0 : WERROR _svcctl_GetServiceDisplayNameW(struct pipes_struct *p,
387 : struct svcctl_GetServiceDisplayNameW *r)
388 : {
389 0 : struct dcesrv_call_state *dce_call = p->dce_call;
390 0 : struct auth_session_info *session_info =
391 0 : dcesrv_call_session_info(dce_call);
392 0 : const char *service;
393 0 : const char *display_name;
394 0 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
395 :
396 : /* can only use an SCM handle here */
397 :
398 0 : if ( !info || (info->type != SVC_HANDLE_IS_SCM) )
399 0 : return WERR_INVALID_HANDLE;
400 :
401 0 : service = r->in.service_name;
402 :
403 0 : display_name = svcctl_lookup_dispname(p->mem_ctx,
404 : p->msg_ctx,
405 : session_info,
406 : service);
407 0 : if (!display_name) {
408 0 : display_name = "";
409 : }
410 :
411 0 : *r->out.display_name = display_name;
412 0 : *r->out.display_name_length = strlen(display_name);
413 :
414 0 : return WERR_OK;
415 : }
416 :
417 : /********************************************************************
418 : _svcctl_QueryServiceStatus
419 : ********************************************************************/
420 :
421 4 : WERROR _svcctl_QueryServiceStatus(struct pipes_struct *p,
422 : struct svcctl_QueryServiceStatus *r)
423 : {
424 4 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
425 :
426 : /* perform access checks */
427 :
428 4 : if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
429 0 : return WERR_INVALID_HANDLE;
430 :
431 4 : if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) )
432 0 : return WERR_ACCESS_DENIED;
433 :
434 : /* try the service specific status call */
435 :
436 4 : return info->ops->service_status( info->name, r->out.service_status );
437 : }
438 :
439 : /********************************************************************
440 : ********************************************************************/
441 :
442 8 : static int enumerate_status(TALLOC_CTX *ctx,
443 : struct messaging_context *msg_ctx,
444 : struct auth_session_info *session_info,
445 : struct ENUM_SERVICE_STATUSW **status)
446 : {
447 8 : int num_services = 0;
448 0 : int i;
449 0 : struct ENUM_SERVICE_STATUSW *st;
450 0 : const char *display_name;
451 :
452 : /* just count */
453 40 : while ( svcctl_ops[num_services].name )
454 32 : num_services++;
455 :
456 8 : if ( !(st = talloc_array( ctx, struct ENUM_SERVICE_STATUSW, num_services )) ) {
457 0 : DEBUG(0,("enumerate_status: talloc() failed!\n"));
458 0 : return -1;
459 : }
460 :
461 40 : for ( i=0; i<num_services; i++ ) {
462 32 : st[i].service_name = talloc_strdup(st, svcctl_ops[i].name );
463 :
464 32 : display_name = svcctl_lookup_dispname(ctx,
465 : msg_ctx,
466 : session_info,
467 32 : svcctl_ops[i].name);
468 32 : st[i].display_name = talloc_strdup(st, display_name ? display_name : "");
469 :
470 32 : svcctl_ops[i].ops->service_status( svcctl_ops[i].name, &st[i].status );
471 : }
472 :
473 8 : *status = st;
474 :
475 8 : return num_services;
476 : }
477 :
478 : /********************************************************************
479 : _svcctl_EnumServicesStatusW
480 : ********************************************************************/
481 :
482 8 : WERROR _svcctl_EnumServicesStatusW(struct pipes_struct *p,
483 : struct svcctl_EnumServicesStatusW *r)
484 : {
485 8 : struct dcesrv_call_state *dce_call = p->dce_call;
486 0 : struct auth_session_info *session_info =
487 8 : dcesrv_call_session_info(dce_call);
488 8 : struct ENUM_SERVICE_STATUSW *services = NULL;
489 0 : int num_services;
490 8 : int i = 0;
491 8 : size_t buffer_size = 0;
492 8 : WERROR result = WERR_OK;
493 8 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
494 8 : DATA_BLOB blob = data_blob_null;
495 :
496 : /* perform access checks */
497 :
498 8 : if ( !info || (info->type != SVC_HANDLE_IS_SCM) )
499 0 : return WERR_INVALID_HANDLE;
500 :
501 8 : if ( !(info->access_granted & SC_RIGHT_MGR_ENUMERATE_SERVICE) ) {
502 0 : return WERR_ACCESS_DENIED;
503 : }
504 :
505 8 : num_services = enumerate_status(p->mem_ctx,
506 : p->msg_ctx,
507 : session_info,
508 : &services);
509 8 : if (num_services == -1 ) {
510 0 : return WERR_NOT_ENOUGH_MEMORY;
511 : }
512 :
513 40 : for ( i=0; i<num_services; i++ ) {
514 32 : buffer_size += ndr_size_ENUM_SERVICE_STATUSW(&services[i], 0);
515 : }
516 :
517 8 : buffer_size += buffer_size % 4;
518 :
519 8 : if (buffer_size > r->in.offered) {
520 4 : num_services = 0;
521 4 : result = WERR_MORE_DATA;
522 : }
523 :
524 8 : if ( W_ERROR_IS_OK(result) ) {
525 :
526 0 : enum ndr_err_code ndr_err;
527 0 : struct ndr_push *ndr;
528 :
529 4 : ndr = ndr_push_init_ctx(p->mem_ctx);
530 4 : if (ndr == NULL) {
531 0 : return WERR_INVALID_PARAMETER;
532 : }
533 :
534 4 : ndr_err = ndr_push_ENUM_SERVICE_STATUSW_array(
535 : ndr, num_services, services);
536 4 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
537 0 : return ntstatus_to_werror(ndr_map_error2ntstatus(ndr_err));
538 : }
539 4 : blob = ndr_push_blob(ndr);
540 4 : memcpy(r->out.service, blob.data, MIN(blob.length, r->in.offered));
541 : }
542 :
543 8 : *r->out.needed = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
544 8 : *r->out.services_returned = (uint32_t)num_services;
545 8 : if (r->out.resume_handle) {
546 8 : *r->out.resume_handle = 0;
547 : }
548 :
549 8 : return result;
550 : }
551 :
552 : /********************************************************************
553 : _svcctl_StartServiceW
554 : ********************************************************************/
555 :
556 4 : WERROR _svcctl_StartServiceW(struct pipes_struct *p,
557 : struct svcctl_StartServiceW *r)
558 : {
559 4 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
560 :
561 : /* perform access checks */
562 :
563 4 : if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
564 0 : return WERR_INVALID_HANDLE;
565 :
566 4 : if ( !(info->access_granted & SC_RIGHT_SVC_START) )
567 0 : return WERR_ACCESS_DENIED;
568 :
569 4 : return info->ops->start_service( info->name );
570 : }
571 :
572 : /********************************************************************
573 : _svcctl_ControlService
574 : ********************************************************************/
575 :
576 4 : WERROR _svcctl_ControlService(struct pipes_struct *p,
577 : struct svcctl_ControlService *r)
578 : {
579 4 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
580 :
581 : /* perform access checks */
582 :
583 4 : if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
584 0 : return WERR_INVALID_HANDLE;
585 :
586 4 : switch ( r->in.control ) {
587 0 : case SVCCTL_CONTROL_STOP:
588 0 : if ( !(info->access_granted & SC_RIGHT_SVC_STOP) )
589 0 : return WERR_ACCESS_DENIED;
590 :
591 0 : return info->ops->stop_service( info->name,
592 : r->out.service_status );
593 :
594 0 : case SVCCTL_CONTROL_INTERROGATE:
595 0 : if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) )
596 0 : return WERR_ACCESS_DENIED;
597 :
598 0 : return info->ops->service_status( info->name,
599 : r->out.service_status );
600 4 : default:
601 4 : return WERR_INVALID_PARAMETER;
602 : }
603 : }
604 :
605 : /********************************************************************
606 : _svcctl_EnumDependentServicesW
607 : ********************************************************************/
608 :
609 16 : WERROR _svcctl_EnumDependentServicesW(struct pipes_struct *p,
610 : struct svcctl_EnumDependentServicesW *r)
611 : {
612 16 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.service );
613 :
614 : /* perform access checks */
615 :
616 16 : if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
617 0 : return WERR_INVALID_HANDLE;
618 :
619 16 : if ( !(info->access_granted & SC_RIGHT_SVC_ENUMERATE_DEPENDENTS) )
620 0 : return WERR_ACCESS_DENIED;
621 :
622 16 : switch (r->in.state) {
623 12 : case SERVICE_STATE_ACTIVE:
624 : case SERVICE_STATE_INACTIVE:
625 : case SERVICE_STATE_ALL:
626 12 : break;
627 4 : default:
628 4 : return WERR_INVALID_PARAMETER;
629 : }
630 :
631 : /* we have to set the outgoing buffer size to the same as the
632 : incoming buffer size (even in the case of failure */
633 : /* this is done in the autogenerated server already - gd */
634 :
635 12 : *r->out.needed = r->in.offered;
636 :
637 : /* no dependent services...basically a stub function */
638 12 : *r->out.services_returned = 0;
639 :
640 12 : return WERR_OK;
641 : }
642 :
643 : /********************************************************************
644 : _svcctl_QueryServiceStatusEx
645 : ********************************************************************/
646 :
647 8 : WERROR _svcctl_QueryServiceStatusEx(struct pipes_struct *p,
648 : struct svcctl_QueryServiceStatusEx *r)
649 : {
650 8 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
651 0 : uint32_t buffer_size;
652 :
653 : /* perform access checks */
654 :
655 8 : if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
656 0 : return WERR_INVALID_HANDLE;
657 :
658 8 : if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) )
659 0 : return WERR_ACCESS_DENIED;
660 :
661 : /* we have to set the outgoing buffer size to the same as the
662 : incoming buffer size (even in the case of failure) */
663 8 : *r->out.needed = r->in.offered;
664 :
665 8 : switch ( r->in.info_level ) {
666 8 : case SVC_STATUS_PROCESS_INFO:
667 : {
668 0 : struct SERVICE_STATUS_PROCESS svc_stat_proc;
669 0 : enum ndr_err_code ndr_err;
670 0 : DATA_BLOB blob;
671 :
672 : /* Get the status of the service.. */
673 8 : info->ops->service_status( info->name, &svc_stat_proc.status );
674 8 : svc_stat_proc.process_id = getpid();
675 8 : svc_stat_proc.service_flags = 0x0;
676 :
677 8 : ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &svc_stat_proc,
678 : (ndr_push_flags_fn_t)ndr_push_SERVICE_STATUS_PROCESS);
679 8 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
680 0 : return WERR_INVALID_PARAMETER;
681 : }
682 :
683 8 : r->out.buffer = blob.data;
684 8 : buffer_size = sizeof(struct SERVICE_STATUS_PROCESS);
685 8 : break;
686 : }
687 :
688 0 : default:
689 0 : return WERR_INVALID_LEVEL;
690 : }
691 :
692 :
693 8 : buffer_size += buffer_size % 4;
694 8 : *r->out.needed = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
695 :
696 8 : if (buffer_size > r->in.offered ) {
697 4 : return WERR_INSUFFICIENT_BUFFER;
698 : }
699 :
700 4 : return WERR_OK;
701 : }
702 :
703 : /********************************************************************
704 : ********************************************************************/
705 :
706 16 : static WERROR fill_svc_config(TALLOC_CTX *mem_ctx,
707 : struct messaging_context *msg_ctx,
708 : struct auth_session_info *session_info,
709 : const char *name,
710 : struct QUERY_SERVICE_CONFIG *config)
711 : {
712 16 : const char *result = NULL;
713 :
714 : /* now fill in the individual values */
715 :
716 16 : ZERO_STRUCTP(config);
717 :
718 16 : config->displayname = svcctl_lookup_dispname(mem_ctx,
719 : msg_ctx,
720 : session_info,
721 : name);
722 :
723 16 : result = svcctl_get_string_value(mem_ctx,
724 : msg_ctx,
725 : session_info,
726 : name,
727 : "ObjectName");
728 16 : if (result != NULL) {
729 16 : config->startname = result;
730 : }
731 :
732 16 : result = svcctl_get_string_value(mem_ctx,
733 : msg_ctx,
734 : session_info,
735 : name,
736 : "ImagePath");
737 16 : if (result != NULL) {
738 16 : config->executablepath = result;
739 : }
740 :
741 : /* a few hard coded values */
742 : /* loadordergroup and dependencies are empty */
743 :
744 16 : config->tag_id = 0x00000000; /* unassigned loadorder group */
745 16 : config->service_type = SERVICE_TYPE_WIN32_OWN_PROCESS;
746 16 : config->error_control = SVCCTL_SVC_ERROR_NORMAL;
747 :
748 : /* set the start type. NetLogon and WINS are disabled to prevent
749 : the client from showing the "Start" button (if of course the services
750 : are not running */
751 :
752 16 : if ( strequal( name, "NETLOGON" ) && ( lp_servicenumber(name) == -1 ) )
753 0 : config->start_type = SVCCTL_DISABLED;
754 16 : else if ( strequal( name, "WINS" ) && ( !lp_we_are_a_wins_server() ))
755 0 : config->start_type = SVCCTL_DISABLED;
756 : else
757 16 : config->start_type = SVCCTL_DEMAND_START;
758 :
759 16 : return WERR_OK;
760 : }
761 :
762 : /********************************************************************
763 : _svcctl_QueryServiceConfigW
764 : ********************************************************************/
765 :
766 16 : WERROR _svcctl_QueryServiceConfigW(struct pipes_struct *p,
767 : struct svcctl_QueryServiceConfigW *r)
768 : {
769 16 : struct dcesrv_call_state *dce_call = p->dce_call;
770 0 : struct auth_session_info *session_info =
771 16 : dcesrv_call_session_info(dce_call);
772 16 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
773 0 : uint32_t buffer_size;
774 0 : WERROR wresult;
775 :
776 : /* perform access checks */
777 :
778 16 : if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
779 0 : return WERR_INVALID_HANDLE;
780 :
781 16 : if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_CONFIG) )
782 0 : return WERR_ACCESS_DENIED;
783 :
784 : /* we have to set the outgoing buffer size to the same as the
785 : incoming buffer size (even in the case of failure */
786 :
787 16 : *r->out.needed = r->in.offered;
788 :
789 16 : wresult = fill_svc_config(p->mem_ctx,
790 : p->msg_ctx,
791 : session_info,
792 16 : info->name,
793 : r->out.query);
794 16 : if ( !W_ERROR_IS_OK(wresult) )
795 0 : return wresult;
796 :
797 16 : buffer_size = ndr_size_QUERY_SERVICE_CONFIG(r->out.query, 0);
798 16 : *r->out.needed = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
799 :
800 16 : if (buffer_size > r->in.offered ) {
801 8 : ZERO_STRUCTP(r->out.query);
802 8 : return WERR_INSUFFICIENT_BUFFER;
803 : }
804 :
805 8 : return WERR_OK;
806 : }
807 :
808 : /********************************************************************
809 : _svcctl_QueryServiceConfig2W
810 : ********************************************************************/
811 :
812 16 : WERROR _svcctl_QueryServiceConfig2W(struct pipes_struct *p,
813 : struct svcctl_QueryServiceConfig2W *r)
814 : {
815 16 : struct dcesrv_call_state *dce_call = p->dce_call;
816 0 : struct auth_session_info *session_info =
817 16 : dcesrv_call_session_info(dce_call);
818 16 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
819 0 : uint32_t buffer_size;
820 16 : DATA_BLOB blob = data_blob_null;
821 :
822 : /* perform access checks */
823 :
824 16 : if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
825 0 : return WERR_INVALID_HANDLE;
826 :
827 16 : if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_CONFIG) )
828 0 : return WERR_ACCESS_DENIED;
829 :
830 : /* we have to set the outgoing buffer size to the same as the
831 : incoming buffer size (even in the case of failure */
832 16 : *r->out.needed = r->in.offered;
833 :
834 16 : switch ( r->in.info_level ) {
835 8 : case SERVICE_CONFIG_DESCRIPTION:
836 : {
837 0 : struct SERVICE_DESCRIPTION desc_buf;
838 0 : const char *description;
839 0 : enum ndr_err_code ndr_err;
840 :
841 8 : description = svcctl_lookup_description(p->mem_ctx,
842 : p->msg_ctx,
843 : session_info,
844 8 : info->name);
845 :
846 8 : desc_buf.description = description;
847 :
848 8 : ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &desc_buf,
849 : (ndr_push_flags_fn_t)ndr_push_SERVICE_DESCRIPTION);
850 8 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
851 0 : return WERR_INVALID_PARAMETER;
852 : }
853 :
854 8 : break;
855 : }
856 : break;
857 8 : case SERVICE_CONFIG_FAILURE_ACTIONS:
858 : {
859 0 : struct SERVICE_FAILURE_ACTIONSW actions;
860 0 : enum ndr_err_code ndr_err;
861 :
862 : /* nothing to say...just service the request */
863 :
864 8 : ZERO_STRUCT( actions );
865 :
866 8 : ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &actions,
867 : (ndr_push_flags_fn_t)ndr_push_SERVICE_FAILURE_ACTIONSW);
868 8 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
869 0 : return WERR_INVALID_PARAMETER;
870 : }
871 :
872 8 : break;
873 : }
874 : break;
875 :
876 0 : default:
877 0 : return WERR_INVALID_LEVEL;
878 : }
879 :
880 16 : buffer_size = blob.length;
881 16 : buffer_size += buffer_size % 4;
882 16 : *r->out.needed = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
883 :
884 16 : if (buffer_size > r->in.offered)
885 8 : return WERR_INSUFFICIENT_BUFFER;
886 :
887 8 : memcpy(r->out.buffer, blob.data, blob.length);
888 :
889 8 : return WERR_OK;
890 : }
891 :
892 : /********************************************************************
893 : _svcctl_LockServiceDatabase
894 : ********************************************************************/
895 :
896 0 : WERROR _svcctl_LockServiceDatabase(struct pipes_struct *p,
897 : struct svcctl_LockServiceDatabase *r)
898 : {
899 0 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
900 :
901 : /* perform access checks */
902 :
903 0 : if ( !info || (info->type != SVC_HANDLE_IS_SCM) )
904 0 : return WERR_INVALID_HANDLE;
905 :
906 0 : if ( !(info->access_granted & SC_RIGHT_MGR_LOCK) )
907 0 : return WERR_ACCESS_DENIED;
908 :
909 : /* Just open a handle. Doesn't actually lock anything */
910 :
911 0 : return create_open_service_handle( p, r->out.lock, SVC_HANDLE_IS_DBLOCK, NULL, 0 );
912 : }
913 :
914 : /********************************************************************
915 : _svcctl_UnlockServiceDatabase
916 : ********************************************************************/
917 :
918 0 : WERROR _svcctl_UnlockServiceDatabase(struct pipes_struct *p,
919 : struct svcctl_UnlockServiceDatabase *r)
920 : {
921 0 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.lock );
922 :
923 :
924 0 : if ( !info || (info->type != SVC_HANDLE_IS_DBLOCK) )
925 0 : return WERR_INVALID_HANDLE;
926 :
927 0 : return close_policy_hnd( p, r->out.lock) ? WERR_OK : WERR_INVALID_HANDLE;
928 : }
929 :
930 : /********************************************************************
931 : _svcctl_QueryServiceObjectSecurity
932 : ********************************************************************/
933 :
934 20 : WERROR _svcctl_QueryServiceObjectSecurity(struct pipes_struct *p,
935 : struct svcctl_QueryServiceObjectSecurity *r)
936 : {
937 20 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
938 0 : struct security_descriptor *sec_desc;
939 0 : NTSTATUS status;
940 20 : uint8_t *buffer = NULL;
941 20 : size_t len = 0;
942 0 : WERROR err;
943 :
944 :
945 : /* only support the SCM and individual services */
946 :
947 20 : if ( !info || !(info->type & (SVC_HANDLE_IS_SERVICE|SVC_HANDLE_IS_SCM)) )
948 0 : return WERR_INVALID_HANDLE;
949 :
950 : /* check access reights (according to MSDN) */
951 :
952 20 : if ( !(info->access_granted & SEC_STD_READ_CONTROL) )
953 0 : return WERR_ACCESS_DENIED;
954 :
955 : /* TODO: handle something besides SECINFO_DACL */
956 :
957 20 : if ( (r->in.security_flags & SECINFO_DACL) != SECINFO_DACL )
958 4 : return WERR_INVALID_PARAMETER;
959 :
960 : /* Lookup the security descriptor and marshall it up for a reply */
961 16 : err = svcctl_get_secdesc(p->msg_ctx,
962 : get_session_info_system(),
963 16 : info->name,
964 : p->mem_ctx,
965 : &sec_desc);
966 16 : if (W_ERROR_EQUAL(err, WERR_FILE_NOT_FOUND)) {
967 0 : DBG_NOTICE("service %s does not exist\n", info->name);
968 0 : return WERR_SERVICE_DOES_NOT_EXIST;
969 : }
970 16 : if (!W_ERROR_IS_OK(err)) {
971 0 : DBG_NOTICE("Failed to get a valid secdesc for %s: %s\n",
972 : info->name, win_errstr(err));
973 0 : return err;
974 : }
975 :
976 16 : *r->out.needed = ndr_size_security_descriptor(sec_desc, 0);
977 :
978 16 : if ( *r->out.needed > r->in.offered) {
979 8 : return WERR_INSUFFICIENT_BUFFER;
980 : }
981 :
982 8 : status = marshall_sec_desc(p->mem_ctx, sec_desc, &buffer, &len);
983 8 : if (!NT_STATUS_IS_OK(status)) {
984 0 : return ntstatus_to_werror(status);
985 : }
986 :
987 8 : *r->out.needed = len;
988 8 : memcpy(r->out.buffer, buffer, len);
989 :
990 8 : return WERR_OK;
991 : }
992 :
993 : /********************************************************************
994 : _svcctl_SetServiceObjectSecurity
995 : ********************************************************************/
996 :
997 4 : WERROR _svcctl_SetServiceObjectSecurity(struct pipes_struct *p,
998 : struct svcctl_SetServiceObjectSecurity *r)
999 : {
1000 4 : struct dcesrv_call_state *dce_call = p->dce_call;
1001 0 : struct auth_session_info *session_info =
1002 4 : dcesrv_call_session_info(dce_call);
1003 4 : SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
1004 4 : struct security_descriptor *sec_desc = NULL;
1005 0 : uint32_t required_access;
1006 0 : NTSTATUS status;
1007 :
1008 4 : if ( !info || !(info->type & (SVC_HANDLE_IS_SERVICE|SVC_HANDLE_IS_SCM)) )
1009 0 : return WERR_INVALID_HANDLE;
1010 :
1011 : /* can't set the security de4scriptor on the ServiceControlManager */
1012 :
1013 4 : if ( info->type == SVC_HANDLE_IS_SCM )
1014 0 : return WERR_ACCESS_DENIED;
1015 :
1016 : /* check the access on the open handle */
1017 :
1018 4 : switch ( r->in.security_flags ) {
1019 4 : case SECINFO_DACL:
1020 4 : required_access = SEC_STD_WRITE_DAC;
1021 4 : break;
1022 :
1023 0 : case SECINFO_OWNER:
1024 : case SECINFO_GROUP:
1025 0 : required_access = SEC_STD_WRITE_OWNER;
1026 0 : break;
1027 :
1028 0 : case SECINFO_SACL:
1029 0 : return WERR_INVALID_PARAMETER;
1030 0 : default:
1031 0 : return WERR_INVALID_PARAMETER;
1032 : }
1033 :
1034 4 : if ( !(info->access_granted & required_access) )
1035 0 : return WERR_ACCESS_DENIED;
1036 :
1037 : /* read the security descfriptor */
1038 :
1039 4 : status = unmarshall_sec_desc(p->mem_ctx,
1040 : r->in.buffer,
1041 4 : r->in.offered,
1042 : &sec_desc);
1043 4 : if (!NT_STATUS_IS_OK(status)) {
1044 0 : return ntstatus_to_werror(status);
1045 : }
1046 :
1047 : /* store the new SD */
1048 :
1049 4 : if (!svcctl_set_secdesc(p->msg_ctx, session_info, info->name, sec_desc))
1050 0 : return WERR_ACCESS_DENIED;
1051 :
1052 4 : return WERR_OK;
1053 : }
1054 :
1055 :
1056 0 : WERROR _svcctl_DeleteService(struct pipes_struct *p,
1057 : struct svcctl_DeleteService *r)
1058 : {
1059 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1060 0 : return WERR_NOT_SUPPORTED;
1061 : }
1062 :
1063 0 : WERROR _svcctl_SetServiceStatus(struct pipes_struct *p,
1064 : struct svcctl_SetServiceStatus *r)
1065 : {
1066 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1067 0 : return WERR_NOT_SUPPORTED;
1068 : }
1069 :
1070 0 : WERROR _svcctl_NotifyBootConfigStatus(struct pipes_struct *p,
1071 : struct svcctl_NotifyBootConfigStatus *r)
1072 : {
1073 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1074 0 : return WERR_NOT_SUPPORTED;
1075 : }
1076 :
1077 0 : WERROR _svcctl_SCSetServiceBitsW(struct pipes_struct *p,
1078 : struct svcctl_SCSetServiceBitsW *r)
1079 : {
1080 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1081 0 : return WERR_NOT_SUPPORTED;
1082 : }
1083 :
1084 4 : WERROR _svcctl_ChangeServiceConfigW(struct pipes_struct *p,
1085 : struct svcctl_ChangeServiceConfigW *r)
1086 : {
1087 4 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1088 4 : return WERR_NOT_SUPPORTED;
1089 : }
1090 :
1091 0 : WERROR _svcctl_CreateServiceW(struct pipes_struct *p,
1092 : struct svcctl_CreateServiceW *r)
1093 : {
1094 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1095 0 : return WERR_NOT_SUPPORTED;
1096 : }
1097 :
1098 0 : WERROR _svcctl_QueryServiceLockStatusW(struct pipes_struct *p,
1099 : struct svcctl_QueryServiceLockStatusW *r)
1100 : {
1101 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1102 0 : return WERR_NOT_SUPPORTED;
1103 : }
1104 :
1105 0 : WERROR _svcctl_GetServiceKeyNameW(struct pipes_struct *p,
1106 : struct svcctl_GetServiceKeyNameW *r)
1107 : {
1108 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1109 0 : return WERR_NOT_SUPPORTED;
1110 : }
1111 :
1112 0 : WERROR _svcctl_SCSetServiceBitsA(struct pipes_struct *p,
1113 : struct svcctl_SCSetServiceBitsA *r)
1114 : {
1115 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1116 0 : return WERR_NOT_SUPPORTED;
1117 : }
1118 :
1119 0 : WERROR _svcctl_ChangeServiceConfigA(struct pipes_struct *p,
1120 : struct svcctl_ChangeServiceConfigA *r)
1121 : {
1122 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1123 0 : return WERR_NOT_SUPPORTED;
1124 : }
1125 :
1126 0 : WERROR _svcctl_CreateServiceA(struct pipes_struct *p,
1127 : struct svcctl_CreateServiceA *r)
1128 : {
1129 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1130 0 : return WERR_NOT_SUPPORTED;
1131 : }
1132 :
1133 0 : WERROR _svcctl_EnumDependentServicesA(struct pipes_struct *p,
1134 : struct svcctl_EnumDependentServicesA *r)
1135 : {
1136 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1137 0 : return WERR_NOT_SUPPORTED;
1138 : }
1139 :
1140 0 : WERROR _svcctl_EnumServicesStatusA(struct pipes_struct *p,
1141 : struct svcctl_EnumServicesStatusA *r)
1142 : {
1143 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1144 0 : return WERR_NOT_SUPPORTED;
1145 : }
1146 :
1147 0 : WERROR _svcctl_OpenSCManagerA(struct pipes_struct *p,
1148 : struct svcctl_OpenSCManagerA *r)
1149 : {
1150 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1151 0 : return WERR_NOT_SUPPORTED;
1152 : }
1153 :
1154 0 : WERROR _svcctl_OpenServiceA(struct pipes_struct *p,
1155 : struct svcctl_OpenServiceA *r)
1156 : {
1157 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1158 0 : return WERR_NOT_SUPPORTED;
1159 : }
1160 :
1161 0 : WERROR _svcctl_QueryServiceConfigA(struct pipes_struct *p,
1162 : struct svcctl_QueryServiceConfigA *r)
1163 : {
1164 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1165 0 : return WERR_NOT_SUPPORTED;
1166 : }
1167 :
1168 0 : WERROR _svcctl_QueryServiceLockStatusA(struct pipes_struct *p,
1169 : struct svcctl_QueryServiceLockStatusA *r)
1170 : {
1171 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1172 0 : return WERR_NOT_SUPPORTED;
1173 : }
1174 :
1175 0 : WERROR _svcctl_StartServiceA(struct pipes_struct *p,
1176 : struct svcctl_StartServiceA *r)
1177 : {
1178 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1179 0 : return WERR_NOT_SUPPORTED;
1180 : }
1181 :
1182 0 : WERROR _svcctl_GetServiceDisplayNameA(struct pipes_struct *p,
1183 : struct svcctl_GetServiceDisplayNameA *r)
1184 : {
1185 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1186 0 : return WERR_NOT_SUPPORTED;
1187 : }
1188 :
1189 0 : WERROR _svcctl_GetServiceKeyNameA(struct pipes_struct *p,
1190 : struct svcctl_GetServiceKeyNameA *r)
1191 : {
1192 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1193 0 : return WERR_NOT_SUPPORTED;
1194 : }
1195 :
1196 0 : WERROR _svcctl_GetCurrentGroupeStateW(struct pipes_struct *p,
1197 : struct svcctl_GetCurrentGroupeStateW *r)
1198 : {
1199 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1200 0 : return WERR_NOT_SUPPORTED;
1201 : }
1202 :
1203 0 : WERROR _svcctl_EnumServiceGroupW(struct pipes_struct *p,
1204 : struct svcctl_EnumServiceGroupW *r)
1205 : {
1206 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1207 0 : return WERR_NOT_SUPPORTED;
1208 : }
1209 :
1210 0 : WERROR _svcctl_ChangeServiceConfig2A(struct pipes_struct *p,
1211 : struct svcctl_ChangeServiceConfig2A *r)
1212 : {
1213 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1214 0 : return WERR_NOT_SUPPORTED;
1215 : }
1216 :
1217 0 : WERROR _svcctl_ChangeServiceConfig2W(struct pipes_struct *p,
1218 : struct svcctl_ChangeServiceConfig2W *r)
1219 : {
1220 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1221 0 : return WERR_NOT_SUPPORTED;
1222 : }
1223 :
1224 0 : WERROR _svcctl_QueryServiceConfig2A(struct pipes_struct *p,
1225 : struct svcctl_QueryServiceConfig2A *r)
1226 : {
1227 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1228 0 : return WERR_NOT_SUPPORTED;
1229 : }
1230 :
1231 0 : WERROR _svcctl_EnumServicesStatusExA(struct pipes_struct *p,
1232 : struct svcctl_EnumServicesStatusExA *r)
1233 : {
1234 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1235 0 : return WERR_NOT_SUPPORTED;
1236 : }
1237 :
1238 0 : WERROR _svcctl_EnumServicesStatusExW(struct pipes_struct *p,
1239 : struct svcctl_EnumServicesStatusExW *r)
1240 : {
1241 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1242 0 : return WERR_NOT_SUPPORTED;
1243 : }
1244 :
1245 0 : WERROR _svcctl_SCSendTSMessage(struct pipes_struct *p,
1246 : struct svcctl_SCSendTSMessage *r)
1247 : {
1248 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1249 0 : return WERR_NOT_SUPPORTED;
1250 : }
1251 :
1252 : /****************************************************************
1253 : _svcctl_CreateServiceWOW64A
1254 : ****************************************************************/
1255 :
1256 0 : WERROR _svcctl_CreateServiceWOW64A(struct pipes_struct *p,
1257 : struct svcctl_CreateServiceWOW64A *r)
1258 : {
1259 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1260 0 : return WERR_NOT_SUPPORTED;
1261 : }
1262 :
1263 :
1264 : /****************************************************************
1265 : _svcctl_CreateServiceWOW64W
1266 : ****************************************************************/
1267 :
1268 0 : WERROR _svcctl_CreateServiceWOW64W(struct pipes_struct *p,
1269 : struct svcctl_CreateServiceWOW64W *r)
1270 : {
1271 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1272 0 : return WERR_NOT_SUPPORTED;
1273 : }
1274 :
1275 :
1276 : /****************************************************************
1277 : _Opnum46NotUsedOnWire
1278 : ****************************************************************/
1279 :
1280 0 : void _Opnum46NotUsedOnWire(struct pipes_struct *p,
1281 : struct Opnum46NotUsedOnWire *r)
1282 : {
1283 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1284 0 : }
1285 :
1286 :
1287 : /****************************************************************
1288 : _svcctl_NotifyServiceStatusChange
1289 : ****************************************************************/
1290 :
1291 0 : WERROR _svcctl_NotifyServiceStatusChange(struct pipes_struct *p,
1292 : struct svcctl_NotifyServiceStatusChange *r)
1293 : {
1294 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1295 0 : return WERR_NOT_SUPPORTED;
1296 : }
1297 :
1298 :
1299 : /****************************************************************
1300 : _svcctl_GetNotifyResults
1301 : ****************************************************************/
1302 :
1303 0 : WERROR _svcctl_GetNotifyResults(struct pipes_struct *p,
1304 : struct svcctl_GetNotifyResults *r)
1305 : {
1306 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1307 0 : return WERR_NOT_SUPPORTED;
1308 : }
1309 :
1310 :
1311 : /****************************************************************
1312 : _svcctl_CloseNotifyHandle
1313 : ****************************************************************/
1314 :
1315 0 : WERROR _svcctl_CloseNotifyHandle(struct pipes_struct *p,
1316 : struct svcctl_CloseNotifyHandle *r)
1317 : {
1318 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1319 0 : return WERR_NOT_SUPPORTED;
1320 : }
1321 :
1322 :
1323 : /****************************************************************
1324 : _svcctl_ControlServiceExA
1325 : ****************************************************************/
1326 :
1327 0 : WERROR _svcctl_ControlServiceExA(struct pipes_struct *p,
1328 : struct svcctl_ControlServiceExA *r)
1329 : {
1330 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1331 0 : return WERR_NOT_SUPPORTED;
1332 : }
1333 :
1334 :
1335 : /****************************************************************
1336 : _svcctl_ControlServiceExW
1337 : ****************************************************************/
1338 :
1339 4 : WERROR _svcctl_ControlServiceExW(struct pipes_struct *p,
1340 : struct svcctl_ControlServiceExW *r)
1341 : {
1342 4 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1343 4 : return WERR_NOT_SUPPORTED;
1344 : }
1345 :
1346 :
1347 : /****************************************************************
1348 : _Opnum52NotUsedOnWire
1349 : ****************************************************************/
1350 :
1351 0 : void _Opnum52NotUsedOnWire(struct pipes_struct *p,
1352 : struct Opnum52NotUsedOnWire *r)
1353 : {
1354 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1355 0 : }
1356 :
1357 :
1358 : /****************************************************************
1359 : _Opnum53NotUsedOnWire
1360 : ****************************************************************/
1361 :
1362 0 : void _Opnum53NotUsedOnWire(struct pipes_struct *p,
1363 : struct Opnum53NotUsedOnWire *r)
1364 : {
1365 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1366 0 : }
1367 :
1368 :
1369 : /****************************************************************
1370 : _Opnum54NotUsedOnWire
1371 : ****************************************************************/
1372 :
1373 0 : void _Opnum54NotUsedOnWire(struct pipes_struct *p,
1374 : struct Opnum54NotUsedOnWire *r)
1375 : {
1376 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1377 0 : }
1378 :
1379 :
1380 : /****************************************************************
1381 : _Opnum55NotUsedOnWire
1382 : ****************************************************************/
1383 :
1384 0 : void _Opnum55NotUsedOnWire(struct pipes_struct *p,
1385 : struct Opnum55NotUsedOnWire *r)
1386 : {
1387 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1388 0 : }
1389 :
1390 :
1391 : /****************************************************************
1392 : _svcctl_QueryServiceConfigEx
1393 : ****************************************************************/
1394 :
1395 4 : WERROR _svcctl_QueryServiceConfigEx(struct pipes_struct *p,
1396 : struct svcctl_QueryServiceConfigEx *r)
1397 : {
1398 4 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1399 4 : return WERR_NOT_SUPPORTED;
1400 : }
1401 :
1402 :
1403 : /****************************************************************
1404 : _Opnum57NotUsedOnWire
1405 : ****************************************************************/
1406 :
1407 0 : void _Opnum57NotUsedOnWire(struct pipes_struct *p,
1408 : struct Opnum57NotUsedOnWire *r)
1409 : {
1410 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1411 0 : }
1412 :
1413 :
1414 : /****************************************************************
1415 : _Opnum58NotUsedOnWire
1416 : ****************************************************************/
1417 :
1418 0 : void _Opnum58NotUsedOnWire(struct pipes_struct *p,
1419 : struct Opnum58NotUsedOnWire *r)
1420 : {
1421 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1422 0 : }
1423 :
1424 :
1425 : /****************************************************************
1426 : _Opnum59NotUsedOnWire
1427 : ****************************************************************/
1428 :
1429 0 : void _Opnum59NotUsedOnWire(struct pipes_struct *p,
1430 : struct Opnum59NotUsedOnWire *r)
1431 : {
1432 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1433 0 : }
1434 :
1435 :
1436 : /****************************************************************
1437 : _svcctl_CreateWowService
1438 : ****************************************************************/
1439 :
1440 0 : WERROR _svcctl_CreateWowService(struct pipes_struct *p,
1441 : struct svcctl_CreateWowService *r)
1442 : {
1443 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1444 0 : return WERR_NOT_SUPPORTED;
1445 : }
1446 :
1447 :
1448 : /****************************************************************
1449 : _svcctl_OpenSCManager2
1450 : ****************************************************************/
1451 :
1452 0 : WERROR _svcctl_OpenSCManager2(struct pipes_struct *p,
1453 : struct svcctl_OpenSCManager2 *r)
1454 : {
1455 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1456 0 : return WERR_NOT_SUPPORTED;
1457 : }
1458 :
1459 : static NTSTATUS svcctl__op_init_server(struct dcesrv_context *dce_ctx,
1460 : const struct dcesrv_endpoint_server *ep_server);
1461 :
1462 : static NTSTATUS svcctl__op_shutdown_server(struct dcesrv_context *dce_ctx,
1463 : const struct dcesrv_endpoint_server *ep_server);
1464 :
1465 : #define DCESRV_INTERFACE_SVCCTL_INIT_SERVER \
1466 : svcctl_init_server
1467 :
1468 : #define DCESRV_INTERFACE_SVCCTL_SHUTDOWN_SERVER \
1469 : svcctl_shutdown_server
1470 :
1471 126 : static NTSTATUS svcctl_init_server(struct dcesrv_context *dce_ctx,
1472 : const struct dcesrv_endpoint_server *ep_server)
1473 : {
1474 126 : struct messaging_context *msg_ctx = global_messaging_context();
1475 0 : bool ok;
1476 :
1477 : /* initialize the control hooks */
1478 126 : init_service_op_table();
1479 :
1480 126 : ok = svcctl_init_winreg(msg_ctx);
1481 126 : if (!ok) {
1482 0 : return NT_STATUS_UNSUCCESSFUL;
1483 : }
1484 :
1485 126 : return svcctl__op_init_server(dce_ctx, ep_server);
1486 : }
1487 :
1488 126 : static NTSTATUS svcctl_shutdown_server(struct dcesrv_context *dce_ctx,
1489 : const struct dcesrv_endpoint_server *ep_server)
1490 : {
1491 126 : shutdown_service_op_table();
1492 :
1493 126 : return svcctl__op_shutdown_server(dce_ctx, ep_server);
1494 : }
1495 :
1496 : /* include the generated boilerplate */
1497 : #include "librpc/gen_ndr/ndr_svcctl_scompat.c"
|