2 Unix SMB/CIFS implementation.
3 test suite for svcctl rpc operations
5 Copyright (C) Jelmer Vernooij 2004
6 Copyright (C) Guenther Deschner 2008,2009,2020
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "librpc/gen_ndr/ndr_svcctl_c.h"
24 #include "librpc/gen_ndr/ndr_svcctl.h"
25 #include "librpc/gen_ndr/ndr_security.h"
26 #include "torture/rpc/torture_rpc.h"
27 #include "param/param.h"
29 #define TORTURE_DEFAULT_SERVICE "Spooler"
31 static bool test_OpenSCManager(struct dcerpc_binding_handle
*b
,
32 struct torture_context
*tctx
,
33 struct policy_handle
*h
)
35 struct svcctl_OpenSCManagerW r
;
37 r
.in
.MachineName
= NULL
;
38 r
.in
.DatabaseName
= NULL
;
39 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
42 torture_assert_ntstatus_ok(tctx
,
43 dcerpc_svcctl_OpenSCManagerW_r(b
, tctx
, &r
),
44 "OpenSCManager failed!");
49 static bool test_CloseServiceHandle(struct dcerpc_binding_handle
*b
,
50 struct torture_context
*tctx
,
51 struct policy_handle
*h
)
53 struct svcctl_CloseServiceHandle r
;
57 torture_assert_ntstatus_ok(tctx
,
58 dcerpc_svcctl_CloseServiceHandle_r(b
, tctx
, &r
),
59 "CloseServiceHandle failed");
64 static bool test_OpenService(struct dcerpc_binding_handle
*b
,
65 struct torture_context
*tctx
,
66 struct policy_handle
*h
,
68 struct policy_handle
*s
)
70 struct svcctl_OpenServiceW r
;
72 r
.in
.scmanager_handle
= h
;
73 r
.in
.ServiceName
= name
;
74 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
77 torture_assert_ntstatus_ok(tctx
,
78 dcerpc_svcctl_OpenServiceW_r(b
, tctx
, &r
),
79 "OpenServiceW failed!");
80 torture_assert_werr_ok(tctx
, r
.out
.result
, "OpenServiceW failed!");
86 static bool test_QueryServiceStatus(struct torture_context
*tctx
,
87 struct dcerpc_pipe
*p
)
89 struct svcctl_QueryServiceStatus r
;
90 struct policy_handle h
, s
;
91 struct SERVICE_STATUS service_status
;
93 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
95 if (!test_OpenSCManager(b
, tctx
, &h
))
98 if (!test_OpenService(b
, tctx
, &h
, TORTURE_DEFAULT_SERVICE
, &s
))
102 r
.out
.service_status
= &service_status
;
104 status
= dcerpc_svcctl_QueryServiceStatus_r(b
, tctx
, &r
);
105 torture_assert_ntstatus_ok(tctx
, status
, "QueryServiceStatus failed!");
106 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryServiceStatus failed!");
108 if (!test_CloseServiceHandle(b
, tctx
, &s
))
111 if (!test_CloseServiceHandle(b
, tctx
, &h
))
117 static bool test_QueryServiceStatusEx(struct torture_context
*tctx
, struct dcerpc_pipe
*p
)
119 struct svcctl_QueryServiceStatusEx r
;
120 struct policy_handle h
, s
;
122 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
124 uint32_t info_level
= SVC_STATUS_PROCESS_INFO
;
126 uint32_t offered
= 0;
129 if (!test_OpenSCManager(b
, tctx
, &h
))
132 if (!test_OpenService(b
, tctx
, &h
, TORTURE_DEFAULT_SERVICE
, &s
))
135 buffer
= talloc(tctx
, uint8_t);
138 r
.in
.info_level
= info_level
;
139 r
.in
.offered
= offered
;
140 r
.out
.buffer
= buffer
;
141 r
.out
.needed
= &needed
;
143 status
= dcerpc_svcctl_QueryServiceStatusEx_r(b
, tctx
, &r
);
144 torture_assert_ntstatus_ok(tctx
, status
, "QueryServiceStatusEx failed!");
146 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
147 r
.in
.offered
= needed
;
148 buffer
= talloc_array(tctx
, uint8_t, needed
);
149 r
.out
.buffer
= buffer
;
151 status
= dcerpc_svcctl_QueryServiceStatusEx_r(b
, tctx
, &r
);
152 torture_assert_ntstatus_ok(tctx
, status
, "QueryServiceStatusEx failed!");
153 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryServiceStatusEx failed!");
156 if (!test_CloseServiceHandle(b
, tctx
, &s
))
159 if (!test_CloseServiceHandle(b
, tctx
, &h
))
165 static bool test_QueryServiceConfigW(struct torture_context
*tctx
,
166 struct dcerpc_pipe
*p
)
168 struct svcctl_QueryServiceConfigW r
;
169 struct QUERY_SERVICE_CONFIG query
;
170 struct policy_handle h
, s
;
172 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
174 uint32_t offered
= 0;
177 if (!test_OpenSCManager(b
, tctx
, &h
))
180 if (!test_OpenService(b
, tctx
, &h
, TORTURE_DEFAULT_SERVICE
, &s
))
184 r
.in
.offered
= offered
;
185 r
.out
.query
= &query
;
186 r
.out
.needed
= &needed
;
188 status
= dcerpc_svcctl_QueryServiceConfigW_r(b
, tctx
, &r
);
189 torture_assert_ntstatus_ok(tctx
, status
, "QueryServiceConfigW failed!");
191 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
192 r
.in
.offered
= needed
;
193 status
= dcerpc_svcctl_QueryServiceConfigW_r(b
, tctx
, &r
);
194 torture_assert_ntstatus_ok(tctx
, status
, "QueryServiceConfigW failed!");
197 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryServiceConfigW failed!");
199 if (!test_CloseServiceHandle(b
, tctx
, &s
))
202 if (!test_CloseServiceHandle(b
, tctx
, &h
))
208 static bool test_QueryServiceConfig2W(struct torture_context
*tctx
, struct dcerpc_pipe
*p
)
210 struct svcctl_QueryServiceConfig2W r
;
211 struct policy_handle h
, s
;
213 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
215 uint32_t info_level
= SERVICE_CONFIG_DESCRIPTION
;
217 uint32_t offered
= 0;
220 if (!test_OpenSCManager(b
, tctx
, &h
))
223 if (!test_OpenService(b
, tctx
, &h
, TORTURE_DEFAULT_SERVICE
, &s
))
226 buffer
= talloc(tctx
, uint8_t);
229 r
.in
.info_level
= info_level
;
230 r
.in
.offered
= offered
;
231 r
.out
.buffer
= buffer
;
232 r
.out
.needed
= &needed
;
234 status
= dcerpc_svcctl_QueryServiceConfig2W_r(b
, tctx
, &r
);
235 torture_assert_ntstatus_ok(tctx
, status
, "QueryServiceConfig2W failed!");
237 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
238 r
.in
.offered
= needed
;
239 buffer
= talloc_array(tctx
, uint8_t, needed
);
240 r
.out
.buffer
= buffer
;
242 status
= dcerpc_svcctl_QueryServiceConfig2W_r(b
, tctx
, &r
);
243 torture_assert_ntstatus_ok(tctx
, status
, "QueryServiceConfig2W failed!");
244 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryServiceConfig2W failed!");
247 r
.in
.info_level
= SERVICE_CONFIG_FAILURE_ACTIONS
;
248 r
.in
.offered
= offered
;
249 r
.out
.buffer
= buffer
;
250 r
.out
.needed
= &needed
;
252 status
= dcerpc_svcctl_QueryServiceConfig2W_r(b
, tctx
, &r
);
253 torture_assert_ntstatus_ok(tctx
, status
, "QueryServiceConfig2W failed!");
255 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
256 r
.in
.offered
= needed
;
257 buffer
= talloc_array(tctx
, uint8_t, needed
);
258 r
.out
.buffer
= buffer
;
260 status
= dcerpc_svcctl_QueryServiceConfig2W_r(b
, tctx
, &r
);
261 torture_assert_ntstatus_ok(tctx
, status
, "QueryServiceConfig2W failed!");
262 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryServiceConfig2W failed!");
265 if (!test_CloseServiceHandle(b
, tctx
, &s
))
268 if (!test_CloseServiceHandle(b
, tctx
, &h
))
274 static bool test_QueryServiceConfigEx(struct torture_context
*tctx
, struct dcerpc_pipe
*p
)
276 struct svcctl_QueryServiceConfigEx r
;
277 struct policy_handle h
, s
;
279 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
280 struct SC_RPC_CONFIG_INFOW info
;
283 if (!test_OpenSCManager(b
, tctx
, &h
))
286 if (!test_OpenService(b
, tctx
, &h
, TORTURE_DEFAULT_SERVICE
, &s
))
289 for (i
=0; i
< 16; i
++) {
292 r
.in
.dwInfoLevel
= i
;
295 status
= dcerpc_svcctl_QueryServiceConfigEx_r(b
, tctx
, &r
);
297 torture_assert_ntstatus_ok(tctx
, status
, "QueryServiceConfigEx failed!");
298 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryServiceConfigEx failed!");
300 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
, "QueryServiceConfigEx failed!");
304 if (!test_CloseServiceHandle(b
, tctx
, &s
))
307 if (!test_CloseServiceHandle(b
, tctx
, &h
))
313 static bool test_QueryServiceObjectSecurity(struct torture_context
*tctx
,
314 struct dcerpc_pipe
*p
)
316 struct svcctl_QueryServiceObjectSecurity r
;
317 struct policy_handle h
, s
;
318 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
320 uint8_t *buffer
= NULL
;
323 enum ndr_err_code ndr_err
;
324 struct security_descriptor sd
;
327 if (!test_OpenSCManager(b
, tctx
, &h
))
330 if (!test_OpenService(b
, tctx
, &h
, TORTURE_DEFAULT_SERVICE
, &s
))
334 r
.in
.security_flags
= 0;
337 r
.out
.needed
= &needed
;
339 torture_assert_ntstatus_ok(tctx
,
340 dcerpc_svcctl_QueryServiceObjectSecurity_r(b
, tctx
, &r
),
341 "QueryServiceObjectSecurity failed!");
342 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAMETER
,
343 "QueryServiceObjectSecurity failed!");
345 r
.in
.security_flags
= SECINFO_DACL
;
347 torture_assert_ntstatus_ok(tctx
,
348 dcerpc_svcctl_QueryServiceObjectSecurity_r(b
, tctx
, &r
),
349 "QueryServiceObjectSecurity failed!");
351 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
352 r
.in
.offered
= needed
;
353 buffer
= talloc_array(tctx
, uint8_t, needed
);
354 r
.out
.buffer
= buffer
;
355 torture_assert_ntstatus_ok(tctx
,
356 dcerpc_svcctl_QueryServiceObjectSecurity_r(b
, tctx
, &r
),
357 "QueryServiceObjectSecurity failed!");
360 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryServiceObjectSecurity failed!");
362 blob
= data_blob_const(buffer
, needed
);
364 ndr_err
= ndr_pull_struct_blob(&blob
, tctx
, &sd
,
365 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
366 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
370 if (DEBUGLEVEL
>= 1) {
371 NDR_PRINT_DEBUG(security_descriptor
, &sd
);
374 if (!test_CloseServiceHandle(b
, tctx
, &s
))
377 if (!test_CloseServiceHandle(b
, tctx
, &h
))
383 static bool test_SetServiceObjectSecurity(struct torture_context
*tctx
,
384 struct dcerpc_pipe
*p
)
386 struct svcctl_QueryServiceObjectSecurity q
;
387 struct svcctl_SetServiceObjectSecurity r
;
388 struct policy_handle h
, s
;
389 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
394 if (!test_OpenSCManager(b
, tctx
, &h
))
397 if (!test_OpenService(b
, tctx
, &h
, TORTURE_DEFAULT_SERVICE
, &s
))
401 q
.in
.security_flags
= SECINFO_DACL
;
404 q
.out
.needed
= &needed
;
406 torture_assert_ntstatus_ok(tctx
,
407 dcerpc_svcctl_QueryServiceObjectSecurity_r(b
, tctx
, &q
),
408 "QueryServiceObjectSecurity failed!");
410 if (W_ERROR_EQUAL(q
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
411 q
.in
.offered
= needed
;
412 buffer
= talloc_array(tctx
, uint8_t, needed
);
413 q
.out
.buffer
= buffer
;
414 torture_assert_ntstatus_ok(tctx
,
415 dcerpc_svcctl_QueryServiceObjectSecurity_r(b
, tctx
, &q
),
416 "QueryServiceObjectSecurity failed!");
419 torture_assert_werr_ok(tctx
, q
.out
.result
,
420 "QueryServiceObjectSecurity failed!");
423 r
.in
.security_flags
= SECINFO_DACL
;
424 r
.in
.buffer
= q
.out
.buffer
;
425 r
.in
.offered
= *q
.out
.needed
;
427 torture_assert_ntstatus_ok(tctx
,
428 dcerpc_svcctl_SetServiceObjectSecurity_r(b
, tctx
, &r
),
429 "SetServiceObjectSecurity failed!");
430 torture_assert_werr_ok(tctx
, r
.out
.result
,
431 "SetServiceObjectSecurity failed!");
433 if (!test_CloseServiceHandle(b
, tctx
, &s
))
436 if (!test_CloseServiceHandle(b
, tctx
, &h
))
442 static bool test_StartServiceW(struct torture_context
*tctx
,
443 struct dcerpc_pipe
*p
)
445 struct svcctl_StartServiceW r
;
446 struct policy_handle h
, s
;
447 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
449 if (!test_OpenSCManager(b
, tctx
, &h
))
452 if (!test_OpenService(b
, tctx
, &h
, TORTURE_DEFAULT_SERVICE
, &s
))
457 r
.in
.Arguments
= NULL
;
459 torture_assert_ntstatus_ok(tctx
,
460 dcerpc_svcctl_StartServiceW_r(b
, tctx
, &r
),
461 "StartServiceW failed!");
462 torture_assert_werr_equal(tctx
, r
.out
.result
,
463 WERR_SERVICE_ALREADY_RUNNING
,
464 "StartServiceW failed!");
466 if (!test_CloseServiceHandle(b
, tctx
, &s
))
469 if (!test_CloseServiceHandle(b
, tctx
, &h
))
475 static bool test_ControlService(struct torture_context
*tctx
,
476 struct dcerpc_pipe
*p
)
478 struct svcctl_ControlService r
;
479 struct policy_handle h
, s
;
480 struct SERVICE_STATUS service_status
;
481 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
483 if (!test_OpenSCManager(b
, tctx
, &h
))
486 if (!test_OpenService(b
, tctx
, &h
, TORTURE_DEFAULT_SERVICE
, &s
))
491 r
.out
.service_status
= &service_status
;
493 torture_assert_ntstatus_ok(tctx
,
494 dcerpc_svcctl_ControlService_r(b
, tctx
, &r
),
495 "ControlService failed!");
496 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAMETER
,
497 "ControlService failed!");
499 if (!test_CloseServiceHandle(b
, tctx
, &s
))
502 if (!test_CloseServiceHandle(b
, tctx
, &h
))
508 static bool test_ControlServiceExW(struct torture_context
*tctx
,
509 struct dcerpc_pipe
*p
)
511 struct svcctl_ControlServiceExW r
;
512 struct policy_handle h
, s
;
513 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
514 union SC_RPC_SERVICE_CONTROL_IN_PARAMSW ControlInParams
;
515 union SC_RPC_SERVICE_CONTROL_OUT_PARAMSW ControlOutParams
;
516 struct SERVICE_CONTROL_STATUS_REASON_OUT_PARAMS psrOutParams
;
517 struct SERVICE_CONTROL_STATUS_REASON_IN_PARAMSW psrInParams
;
519 if (!test_OpenSCManager(b
, tctx
, &h
))
522 if (!test_OpenService(b
, tctx
, &h
, TORTURE_DEFAULT_SERVICE
, &s
))
525 ZERO_STRUCT(psrInParams
);
526 ZERO_STRUCT(psrOutParams
);
528 psrInParams
.dwReason
= SERVICE_STOP_CUSTOM
|
529 SERVICE_STOP_REASON_MAJOR_APPLICATION
|
530 SERVICE_STOP_REASON_MINOR_ENVIRONMENT
;
531 psrInParams
.pszComment
= "wurst";
533 ControlInParams
.psrInParams
= &psrInParams
;
534 ControlOutParams
.psrOutParams
= &psrOutParams
;
537 r
.in
.dwControl
= SVCCTL_CONTROL_STOP
;
538 r
.in
.dwInfoLevel
= 1;
539 r
.in
.pControlInParams
= &ControlInParams
;
540 r
.out
.pControlOutParams
= &ControlOutParams
;
542 torture_assert_ntstatus_ok(tctx
,
543 dcerpc_svcctl_ControlServiceExW_r(b
, tctx
, &r
),
544 "ControlServiceExW failed!");
545 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAMETER
,
546 "ControlServiceExW failed!");
548 if (!test_CloseServiceHandle(b
, tctx
, &s
))
551 if (!test_CloseServiceHandle(b
, tctx
, &h
))
557 static bool test_EnumServicesStatus(struct torture_context
*tctx
, struct dcerpc_pipe
*p
)
559 struct svcctl_EnumServicesStatusW r
;
560 struct policy_handle h
;
563 uint32_t resume_handle
= 0;
564 struct ENUM_SERVICE_STATUSW
*service
= NULL
;
566 uint32_t services_returned
= 0;
567 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
569 if (!test_OpenSCManager(b
, tctx
, &h
))
573 r
.in
.type
= SERVICE_TYPE_WIN32
;
574 r
.in
.state
= SERVICE_STATE_ALL
;
576 r
.in
.resume_handle
= &resume_handle
;
577 r
.out
.service
= NULL
;
578 r
.out
.resume_handle
= &resume_handle
;
579 r
.out
.services_returned
= &services_returned
;
580 r
.out
.needed
= &needed
;
582 status
= dcerpc_svcctl_EnumServicesStatusW_r(b
, tctx
, &r
);
584 torture_assert_ntstatus_ok(tctx
, status
, "EnumServicesStatus failed!");
586 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
587 r
.in
.offered
= needed
;
588 r
.out
.service
= talloc_array(tctx
, uint8_t, needed
);
590 status
= dcerpc_svcctl_EnumServicesStatusW_r(b
, tctx
, &r
);
592 torture_assert_ntstatus_ok(tctx
, status
, "EnumServicesStatus failed!");
593 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumServicesStatus failed");
596 if (services_returned
> 0) {
598 enum ndr_err_code ndr_err
;
600 struct ndr_pull
*ndr
;
602 blob
.length
= r
.in
.offered
;
603 blob
.data
= talloc_steal(tctx
, r
.out
.service
);
605 ndr
= ndr_pull_init_blob(&blob
, tctx
);
607 service
= talloc_array(tctx
, struct ENUM_SERVICE_STATUSW
, services_returned
);
612 ndr_err
= ndr_pull_ENUM_SERVICE_STATUSW_array(
613 ndr
, services_returned
, service
);
614 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
619 for(i
= 0; i
< services_returned
; i
++) {
621 torture_assert(tctx
, service
[i
].service_name
,
622 "Service without name returned!");
624 printf("%-20s \"%s\", Type: %d, State: %d\n",
625 service
[i
].service_name
, service
[i
].display_name
,
626 service
[i
].status
.type
, service
[i
].status
.state
);
629 if (!test_CloseServiceHandle(b
, tctx
, &h
))
635 static bool test_EnumDependentServicesW(struct torture_context
*tctx
,
636 struct dcerpc_pipe
*p
)
638 struct svcctl_EnumDependentServicesW r
;
639 struct policy_handle h
, s
;
641 uint32_t services_returned
;
643 uint32_t states
[] = { SERVICE_STATE_ACTIVE
,
644 SERVICE_STATE_INACTIVE
,
646 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
648 if (!test_OpenSCManager(b
, tctx
, &h
))
651 if (!test_OpenService(b
, tctx
, &h
, TORTURE_DEFAULT_SERVICE
, &s
))
657 r
.out
.service_status
= NULL
;
658 r
.out
.services_returned
= &services_returned
;
659 r
.out
.needed
= &needed
;
661 torture_assert_ntstatus_ok(tctx
,
662 dcerpc_svcctl_EnumDependentServicesW_r(b
, tctx
, &r
),
663 "EnumDependentServicesW failed!");
665 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAMETER
,
666 "EnumDependentServicesW failed!");
668 for (i
=0; i
<ARRAY_SIZE(states
); i
++) {
670 r
.in
.state
= states
[i
];
672 torture_assert_ntstatus_ok(tctx
,
673 dcerpc_svcctl_EnumDependentServicesW_r(b
, tctx
, &r
),
674 "EnumDependentServicesW failed!");
676 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
677 r
.in
.offered
= needed
;
678 r
.out
.service_status
= talloc_array(tctx
, uint8_t, needed
);
680 torture_assert_ntstatus_ok(tctx
,
681 dcerpc_svcctl_EnumDependentServicesW_r(b
, tctx
, &r
),
682 "EnumDependentServicesW failed!");
686 torture_assert_werr_ok(tctx
, r
.out
.result
,
687 "EnumDependentServicesW failed");
690 if (!test_CloseServiceHandle(b
, tctx
, &s
))
693 if (!test_CloseServiceHandle(b
, tctx
, &h
))
699 static bool test_SCManager(struct torture_context
*tctx
,
700 struct dcerpc_pipe
*p
)
702 struct policy_handle h
;
703 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
705 if (!test_OpenSCManager(b
, tctx
, &h
))
708 if (!test_CloseServiceHandle(b
, tctx
, &h
))
714 static bool test_ChangeServiceConfigW(struct torture_context
*tctx
,
715 struct dcerpc_pipe
*p
)
717 struct svcctl_ChangeServiceConfigW r
;
718 struct svcctl_QueryServiceConfigW q
;
719 struct policy_handle h
, s
;
721 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
722 struct QUERY_SERVICE_CONFIG query
;
725 uint32_t offered
= 0;
728 ok
= test_OpenSCManager(b
, tctx
, &h
);
733 ok
= test_OpenService(b
, tctx
, &h
, TORTURE_DEFAULT_SERVICE
, &s
);
739 q
.in
.offered
= offered
;
740 q
.out
.query
= &query
;
741 q
.out
.needed
= &needed
;
743 status
= dcerpc_svcctl_QueryServiceConfigW_r(b
, tctx
, &q
);
744 torture_assert_ntstatus_ok(tctx
, status
, "QueryServiceConfigW failed!");
746 if (W_ERROR_EQUAL(q
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
747 q
.in
.offered
= needed
;
748 status
= dcerpc_svcctl_QueryServiceConfigW_r(b
, tctx
, &q
);
749 torture_assert_ntstatus_ok(tctx
, status
, "QueryServiceConfigW failed!");
751 torture_assert_werr_ok(tctx
, q
.out
.result
, "QueryServiceConfigW failed!");
754 r
.in
.type
= query
.service_type
;
755 r
.in
.start_type
= query
.start_type
;
756 r
.in
.error_control
= query
.error_control
;
759 * according to MS-SCMR 3.1.4.11 NULL params are supposed to leave the
760 * existing values intact.
763 r
.in
.binary_path
= NULL
;
764 r
.in
.load_order_group
= NULL
;
765 r
.in
.dependencies
= NULL
;
766 r
.in
.dwDependSize
= 0;
767 r
.in
.service_start_name
= NULL
;
768 r
.in
.password
= NULL
;
770 r
.in
.display_name
= NULL
;
774 status
= dcerpc_svcctl_ChangeServiceConfigW_r(b
, tctx
, &r
);
775 torture_assert_ntstatus_ok(tctx
, status
, "ChangeServiceConfigW failed!");
776 torture_assert_werr_ok(tctx
, r
.out
.result
, "ChangeServiceConfigW failed!");
778 ok
= test_CloseServiceHandle(b
, tctx
, &s
);
783 ok
= test_CloseServiceHandle(b
, tctx
, &h
);
791 struct torture_suite
*torture_rpc_svcctl(TALLOC_CTX
*mem_ctx
)
793 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "svcctl");
794 struct torture_rpc_tcase
*tcase
;
796 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "svcctl", &ndr_table_svcctl
);
798 torture_rpc_tcase_add_test(tcase
, "SCManager",
800 torture_rpc_tcase_add_test(tcase
, "EnumServicesStatus",
801 test_EnumServicesStatus
);
802 torture_rpc_tcase_add_test(tcase
, "EnumDependentServicesW",
803 test_EnumDependentServicesW
);
804 torture_rpc_tcase_add_test(tcase
, "QueryServiceStatus",
805 test_QueryServiceStatus
);
806 torture_rpc_tcase_add_test(tcase
, "QueryServiceStatusEx",
807 test_QueryServiceStatusEx
);
808 torture_rpc_tcase_add_test(tcase
, "QueryServiceConfigW",
809 test_QueryServiceConfigW
);
810 torture_rpc_tcase_add_test(tcase
, "QueryServiceConfig2W",
811 test_QueryServiceConfig2W
);
812 torture_rpc_tcase_add_test(tcase
, "QueryServiceConfigEx",
813 test_QueryServiceConfigEx
);
814 torture_rpc_tcase_add_test(tcase
, "QueryServiceObjectSecurity",
815 test_QueryServiceObjectSecurity
);
816 torture_rpc_tcase_add_test(tcase
, "SetServiceObjectSecurity",
817 test_SetServiceObjectSecurity
);
818 torture_rpc_tcase_add_test(tcase
, "StartServiceW",
820 torture_rpc_tcase_add_test(tcase
, "ControlService",
821 test_ControlService
);
822 torture_rpc_tcase_add_test(tcase
, "ControlServiceExW",
823 test_ControlServiceExW
);
824 torture_rpc_tcase_add_test(tcase
, "ChangeServiceConfigW",
825 test_ChangeServiceConfigW
);