LCOV - code coverage report
Current view: top level - source4/torture/rpc - svcctl.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 16 364 4.4 %
Date: 2024-06-13 04:01:37 Functions: 1 16 6.2 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    test suite for svcctl rpc operations
       4             : 
       5             :    Copyright (C) Jelmer Vernooij 2004
       6             :    Copyright (C) Guenther Deschner 2008,2009,2020
       7             : 
       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.
      12             : 
      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.
      17             : 
      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/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      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"
      28             : 
      29             : #define TORTURE_DEFAULT_SERVICE "Spooler"
      30             : 
      31           0 : static bool test_OpenSCManager(struct dcerpc_binding_handle *b,
      32             :                                struct torture_context *tctx,
      33             :                                struct policy_handle *h)
      34             : {
      35             :         struct svcctl_OpenSCManagerW r;
      36             : 
      37           0 :         r.in.MachineName = NULL;
      38           0 :         r.in.DatabaseName = NULL;
      39           0 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
      40           0 :         r.out.handle = h;
      41             : 
      42           0 :         torture_assert_ntstatus_ok(tctx,
      43             :                                    dcerpc_svcctl_OpenSCManagerW_r(b, tctx, &r),
      44             :                                    "OpenSCManager failed!");
      45             : 
      46           0 :         return true;
      47             : }
      48             : 
      49           0 : static bool test_CloseServiceHandle(struct dcerpc_binding_handle *b,
      50             :                                     struct torture_context *tctx,
      51             :                                     struct policy_handle *h)
      52             : {
      53             :         struct svcctl_CloseServiceHandle r;
      54             : 
      55           0 :         r.in.handle = h;
      56           0 :         r.out.handle = h;
      57           0 :         torture_assert_ntstatus_ok(tctx,
      58             :                                    dcerpc_svcctl_CloseServiceHandle_r(b, tctx, &r),
      59             :                                    "CloseServiceHandle failed");
      60             : 
      61           0 :         return true;
      62             : }
      63             : 
      64           0 : static bool test_OpenService(struct dcerpc_binding_handle *b,
      65             :                              struct torture_context *tctx,
      66             :                              struct policy_handle *h,
      67             :                              const char *name,
      68             :                              struct policy_handle *s)
      69             : {
      70             :         struct svcctl_OpenServiceW r;
      71             : 
      72           0 :         r.in.scmanager_handle = h;
      73           0 :         r.in.ServiceName = name;
      74           0 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
      75           0 :         r.out.handle = s;
      76             : 
      77           0 :         torture_assert_ntstatus_ok(tctx,
      78             :                                    dcerpc_svcctl_OpenServiceW_r(b, tctx, &r),
      79             :                                    "OpenServiceW failed!");
      80           0 :         torture_assert_werr_ok(tctx, r.out.result, "OpenServiceW failed!");
      81             : 
      82           0 :         return true;
      83             : 
      84             : }
      85             : 
      86           0 : static bool test_QueryServiceStatus(struct torture_context *tctx,
      87             :                                     struct dcerpc_pipe *p)
      88             : {
      89             :         struct svcctl_QueryServiceStatus r;
      90             :         struct policy_handle h, s;
      91             :         struct SERVICE_STATUS service_status;
      92             :         NTSTATUS status;
      93           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
      94             : 
      95           0 :         if (!test_OpenSCManager(b, tctx, &h))
      96           0 :                 return false;
      97             : 
      98           0 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
      99           0 :                 return false;
     100             : 
     101           0 :         r.in.handle = &s;
     102           0 :         r.out.service_status = &service_status;
     103             : 
     104           0 :         status = dcerpc_svcctl_QueryServiceStatus_r(b, tctx, &r);
     105           0 :         torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatus failed!");
     106           0 :         torture_assert_werr_ok(tctx, r.out.result, "QueryServiceStatus failed!");
     107             : 
     108           0 :         if (!test_CloseServiceHandle(b, tctx, &s))
     109           0 :                 return false;
     110             : 
     111           0 :         if (!test_CloseServiceHandle(b, tctx, &h))
     112           0 :                 return false;
     113             : 
     114           0 :         return true;
     115             : }
     116             : 
     117           0 : static bool test_QueryServiceStatusEx(struct torture_context *tctx, struct dcerpc_pipe *p)
     118             : {
     119             :         struct svcctl_QueryServiceStatusEx r;
     120             :         struct policy_handle h, s;
     121             :         NTSTATUS status;
     122           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     123             : 
     124           0 :         uint32_t info_level = SVC_STATUS_PROCESS_INFO;
     125             :         uint8_t *buffer;
     126           0 :         uint32_t offered = 0;
     127           0 :         uint32_t needed = 0;
     128             : 
     129           0 :         if (!test_OpenSCManager(b, tctx, &h))
     130           0 :                 return false;
     131             : 
     132           0 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     133           0 :                 return false;
     134             : 
     135           0 :         buffer = talloc(tctx, uint8_t);
     136             : 
     137           0 :         r.in.handle = &s;
     138           0 :         r.in.info_level = info_level;
     139           0 :         r.in.offered = offered;
     140           0 :         r.out.buffer = buffer;
     141           0 :         r.out.needed = &needed;
     142             : 
     143           0 :         status = dcerpc_svcctl_QueryServiceStatusEx_r(b, tctx, &r);
     144           0 :         torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!");
     145             : 
     146           0 :         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
     147           0 :                 r.in.offered = needed;
     148           0 :                 buffer = talloc_array(tctx, uint8_t, needed);
     149           0 :                 r.out.buffer = buffer;
     150             : 
     151           0 :                 status = dcerpc_svcctl_QueryServiceStatusEx_r(b, tctx, &r);
     152           0 :                 torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!");
     153           0 :                 torture_assert_werr_ok(tctx, r.out.result, "QueryServiceStatusEx failed!");
     154             :         }
     155             : 
     156           0 :         if (!test_CloseServiceHandle(b, tctx, &s))
     157           0 :                 return false;
     158             : 
     159           0 :         if (!test_CloseServiceHandle(b, tctx, &h))
     160           0 :                 return false;
     161             : 
     162           0 :         return true;
     163             : }
     164             : 
     165           0 : static bool test_QueryServiceConfigW(struct torture_context *tctx,
     166             :                                      struct dcerpc_pipe *p)
     167             : {
     168             :         struct svcctl_QueryServiceConfigW r;
     169             :         struct QUERY_SERVICE_CONFIG query;
     170             :         struct policy_handle h, s;
     171             :         NTSTATUS status;
     172           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     173             : 
     174           0 :         uint32_t offered = 0;
     175           0 :         uint32_t needed = 0;
     176             : 
     177           0 :         if (!test_OpenSCManager(b, tctx, &h))
     178           0 :                 return false;
     179             : 
     180           0 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     181           0 :                 return false;
     182             : 
     183           0 :         r.in.handle = &s;
     184           0 :         r.in.offered = offered;
     185           0 :         r.out.query = &query;
     186           0 :         r.out.needed = &needed;
     187             : 
     188           0 :         status = dcerpc_svcctl_QueryServiceConfigW_r(b, tctx, &r);
     189           0 :         torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfigW failed!");
     190             : 
     191           0 :         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
     192           0 :                 r.in.offered = needed;
     193           0 :                 status = dcerpc_svcctl_QueryServiceConfigW_r(b, tctx, &r);
     194           0 :                 torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfigW failed!");
     195             :         }
     196             : 
     197           0 :         torture_assert_werr_ok(tctx, r.out.result, "QueryServiceConfigW failed!");
     198             : 
     199           0 :         if (!test_CloseServiceHandle(b, tctx, &s))
     200           0 :                 return false;
     201             : 
     202           0 :         if (!test_CloseServiceHandle(b, tctx, &h))
     203           0 :                 return false;
     204             : 
     205           0 :         return true;
     206             : }
     207             : 
     208           0 : static bool test_QueryServiceConfig2W(struct torture_context *tctx, struct dcerpc_pipe *p)
     209             : {
     210             :         struct svcctl_QueryServiceConfig2W r;
     211             :         struct policy_handle h, s;
     212             :         NTSTATUS status;
     213           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     214             : 
     215           0 :         uint32_t info_level = SERVICE_CONFIG_DESCRIPTION;
     216             :         uint8_t *buffer;
     217           0 :         uint32_t offered = 0;
     218           0 :         uint32_t needed = 0;
     219             : 
     220           0 :         if (!test_OpenSCManager(b, tctx, &h))
     221           0 :                 return false;
     222             : 
     223           0 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     224           0 :                 return false;
     225             : 
     226           0 :         buffer = talloc(tctx, uint8_t);
     227             : 
     228           0 :         r.in.handle = &s;
     229           0 :         r.in.info_level = info_level;
     230           0 :         r.in.offered = offered;
     231           0 :         r.out.buffer = buffer;
     232           0 :         r.out.needed = &needed;
     233             : 
     234           0 :         status = dcerpc_svcctl_QueryServiceConfig2W_r(b, tctx, &r);
     235           0 :         torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
     236             : 
     237           0 :         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
     238           0 :                 r.in.offered = needed;
     239           0 :                 buffer = talloc_array(tctx, uint8_t, needed);
     240           0 :                 r.out.buffer = buffer;
     241             : 
     242           0 :                 status = dcerpc_svcctl_QueryServiceConfig2W_r(b, tctx, &r);
     243           0 :                 torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
     244           0 :                 torture_assert_werr_ok(tctx, r.out.result, "QueryServiceConfig2W failed!");
     245             :         }
     246             : 
     247           0 :         r.in.info_level = SERVICE_CONFIG_FAILURE_ACTIONS;
     248           0 :         r.in.offered = offered;
     249           0 :         r.out.buffer = buffer;
     250           0 :         r.out.needed = &needed;
     251             : 
     252           0 :         status = dcerpc_svcctl_QueryServiceConfig2W_r(b, tctx, &r);
     253           0 :         torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
     254             : 
     255           0 :         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
     256           0 :                 r.in.offered = needed;
     257           0 :                 buffer = talloc_array(tctx, uint8_t, needed);
     258           0 :                 r.out.buffer = buffer;
     259             : 
     260           0 :                 status = dcerpc_svcctl_QueryServiceConfig2W_r(b, tctx, &r);
     261           0 :                 torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
     262           0 :                 torture_assert_werr_ok(tctx, r.out.result, "QueryServiceConfig2W failed!");
     263             :         }
     264             : 
     265           0 :         if (!test_CloseServiceHandle(b, tctx, &s))
     266           0 :                 return false;
     267             : 
     268           0 :         if (!test_CloseServiceHandle(b, tctx, &h))
     269           0 :                 return false;
     270             : 
     271           0 :         return true;
     272             : }
     273             : 
     274           0 : static bool test_QueryServiceObjectSecurity(struct torture_context *tctx,
     275             :                                             struct dcerpc_pipe *p)
     276             : {
     277             :         struct svcctl_QueryServiceObjectSecurity r;
     278             :         struct policy_handle h, s;
     279           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     280             : 
     281           0 :         uint8_t *buffer = NULL;
     282             :         uint32_t needed;
     283             : 
     284             :         enum ndr_err_code ndr_err;
     285             :         struct security_descriptor sd;
     286             :         DATA_BLOB blob;
     287             : 
     288           0 :         if (!test_OpenSCManager(b, tctx, &h))
     289           0 :                 return false;
     290             : 
     291           0 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     292           0 :                 return false;
     293             : 
     294           0 :         r.in.handle = &s;
     295           0 :         r.in.security_flags = 0;
     296           0 :         r.in.offered = 0;
     297           0 :         r.out.buffer = NULL;
     298           0 :         r.out.needed = &needed;
     299             : 
     300           0 :         torture_assert_ntstatus_ok(tctx,
     301             :                 dcerpc_svcctl_QueryServiceObjectSecurity_r(b, tctx, &r),
     302             :                 "QueryServiceObjectSecurity failed!");
     303           0 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
     304             :                 "QueryServiceObjectSecurity failed!");
     305             : 
     306           0 :         r.in.security_flags = SECINFO_DACL;
     307             : 
     308           0 :         torture_assert_ntstatus_ok(tctx,
     309             :                 dcerpc_svcctl_QueryServiceObjectSecurity_r(b, tctx, &r),
     310             :                 "QueryServiceObjectSecurity failed!");
     311             : 
     312           0 :         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
     313           0 :                 r.in.offered = needed;
     314           0 :                 buffer = talloc_array(tctx, uint8_t, needed);
     315           0 :                 r.out.buffer = buffer;
     316           0 :                 torture_assert_ntstatus_ok(tctx,
     317             :                         dcerpc_svcctl_QueryServiceObjectSecurity_r(b, tctx, &r),
     318             :                         "QueryServiceObjectSecurity failed!");
     319             :         }
     320             : 
     321           0 :         torture_assert_werr_ok(tctx, r.out.result, "QueryServiceObjectSecurity failed!");
     322             : 
     323           0 :         blob = data_blob_const(buffer, needed);
     324             : 
     325           0 :         ndr_err = ndr_pull_struct_blob(&blob, tctx, &sd,
     326             :                 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     327           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     328           0 :                 return false;
     329             :         }
     330             : 
     331           0 :         if (DEBUGLEVEL >= 1) {
     332           0 :                 NDR_PRINT_DEBUG(security_descriptor, &sd);
     333             :         }
     334             : 
     335           0 :         if (!test_CloseServiceHandle(b, tctx, &s))
     336           0 :                 return false;
     337             : 
     338           0 :         if (!test_CloseServiceHandle(b, tctx, &h))
     339           0 :                 return false;
     340             : 
     341           0 :         return true;
     342             : }
     343             : 
     344           0 : static bool test_SetServiceObjectSecurity(struct torture_context *tctx,
     345             :                                           struct dcerpc_pipe *p)
     346             : {
     347             :         struct svcctl_QueryServiceObjectSecurity q;
     348             :         struct svcctl_SetServiceObjectSecurity r;
     349             :         struct policy_handle h, s;
     350           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     351             : 
     352             :         uint8_t *buffer;
     353             :         uint32_t needed;
     354             : 
     355           0 :         if (!test_OpenSCManager(b, tctx, &h))
     356           0 :                 return false;
     357             : 
     358           0 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     359           0 :                 return false;
     360             : 
     361           0 :         q.in.handle = &s;
     362           0 :         q.in.security_flags = SECINFO_DACL;
     363           0 :         q.in.offered = 0;
     364           0 :         q.out.buffer = NULL;
     365           0 :         q.out.needed = &needed;
     366             : 
     367           0 :         torture_assert_ntstatus_ok(tctx,
     368             :                 dcerpc_svcctl_QueryServiceObjectSecurity_r(b, tctx, &q),
     369             :                 "QueryServiceObjectSecurity failed!");
     370             : 
     371           0 :         if (W_ERROR_EQUAL(q.out.result, WERR_INSUFFICIENT_BUFFER)) {
     372           0 :                 q.in.offered = needed;
     373           0 :                 buffer = talloc_array(tctx, uint8_t, needed);
     374           0 :                 q.out.buffer = buffer;
     375           0 :                 torture_assert_ntstatus_ok(tctx,
     376             :                         dcerpc_svcctl_QueryServiceObjectSecurity_r(b, tctx, &q),
     377             :                         "QueryServiceObjectSecurity failed!");
     378             :         }
     379             : 
     380           0 :         torture_assert_werr_ok(tctx, q.out.result,
     381             :                 "QueryServiceObjectSecurity failed!");
     382             : 
     383           0 :         r.in.handle = &s;
     384           0 :         r.in.security_flags = SECINFO_DACL;
     385           0 :         r.in.buffer = q.out.buffer;
     386           0 :         r.in.offered = *q.out.needed;
     387             : 
     388           0 :         torture_assert_ntstatus_ok(tctx,
     389             :                 dcerpc_svcctl_SetServiceObjectSecurity_r(b, tctx, &r),
     390             :                 "SetServiceObjectSecurity failed!");
     391           0 :         torture_assert_werr_ok(tctx, r.out.result,
     392             :                 "SetServiceObjectSecurity failed!");
     393             : 
     394           0 :         if (!test_CloseServiceHandle(b, tctx, &s))
     395           0 :                 return false;
     396             : 
     397           0 :         if (!test_CloseServiceHandle(b, tctx, &h))
     398           0 :                 return false;
     399             : 
     400           0 :         return true;
     401             : }
     402             : 
     403           0 : static bool test_StartServiceW(struct torture_context *tctx,
     404             :                                struct dcerpc_pipe *p)
     405             : {
     406             :         struct svcctl_StartServiceW r;
     407             :         struct policy_handle h, s;
     408           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     409             : 
     410           0 :         if (!test_OpenSCManager(b, tctx, &h))
     411           0 :                 return false;
     412             : 
     413           0 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     414           0 :                 return false;
     415             : 
     416           0 :         r.in.handle = &s;
     417           0 :         r.in.NumArgs = 0;
     418           0 :         r.in.Arguments = NULL;
     419             : 
     420           0 :         torture_assert_ntstatus_ok(tctx,
     421             :                 dcerpc_svcctl_StartServiceW_r(b, tctx, &r),
     422             :                 "StartServiceW failed!");
     423           0 :         torture_assert_werr_equal(tctx, r.out.result,
     424             :                 WERR_SERVICE_ALREADY_RUNNING,
     425             :                 "StartServiceW failed!");
     426             : 
     427           0 :         if (!test_CloseServiceHandle(b, tctx, &s))
     428           0 :                 return false;
     429             : 
     430           0 :         if (!test_CloseServiceHandle(b, tctx, &h))
     431           0 :                 return false;
     432             : 
     433           0 :         return true;
     434             : }
     435             : 
     436           0 : static bool test_ControlService(struct torture_context *tctx,
     437             :                                 struct dcerpc_pipe *p)
     438             : {
     439             :         struct svcctl_ControlService r;
     440             :         struct policy_handle h, s;
     441             :         struct SERVICE_STATUS service_status;
     442           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     443             : 
     444           0 :         if (!test_OpenSCManager(b, tctx, &h))
     445           0 :                 return false;
     446             : 
     447           0 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     448           0 :                 return false;
     449             : 
     450           0 :         r.in.handle = &s;
     451           0 :         r.in.control = 0;
     452           0 :         r.out.service_status = &service_status;
     453             : 
     454           0 :         torture_assert_ntstatus_ok(tctx,
     455             :                 dcerpc_svcctl_ControlService_r(b, tctx, &r),
     456             :                 "ControlService failed!");
     457           0 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
     458             :                 "ControlService failed!");
     459             : 
     460           0 :         if (!test_CloseServiceHandle(b, tctx, &s))
     461           0 :                 return false;
     462             : 
     463           0 :         if (!test_CloseServiceHandle(b, tctx, &h))
     464           0 :                 return false;
     465             : 
     466           0 :         return true;
     467             : }
     468             : 
     469           0 : static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_pipe *p)
     470             : {
     471             :         struct svcctl_EnumServicesStatusW r;
     472             :         struct policy_handle h;
     473             :         int i;
     474             :         NTSTATUS status;
     475           0 :         uint32_t resume_handle = 0;
     476           0 :         struct ENUM_SERVICE_STATUSW *service = NULL;
     477           0 :         uint32_t needed = 0;
     478           0 :         uint32_t services_returned = 0;
     479           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     480             : 
     481           0 :         if (!test_OpenSCManager(b, tctx, &h))
     482           0 :                 return false;
     483             : 
     484           0 :         r.in.handle = &h;
     485           0 :         r.in.type = SERVICE_TYPE_WIN32;
     486           0 :         r.in.state = SERVICE_STATE_ALL;
     487           0 :         r.in.offered = 0;
     488           0 :         r.in.resume_handle = &resume_handle;
     489           0 :         r.out.service = NULL;
     490           0 :         r.out.resume_handle = &resume_handle;
     491           0 :         r.out.services_returned = &services_returned;
     492           0 :         r.out.needed = &needed;
     493             : 
     494           0 :         status = dcerpc_svcctl_EnumServicesStatusW_r(b, tctx, &r);
     495             : 
     496           0 :         torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!");
     497             : 
     498           0 :         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
     499           0 :                 r.in.offered = needed;
     500           0 :                 r.out.service = talloc_array(tctx, uint8_t, needed);
     501             : 
     502           0 :                 status = dcerpc_svcctl_EnumServicesStatusW_r(b, tctx, &r);
     503             : 
     504           0 :                 torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!");
     505           0 :                 torture_assert_werr_ok(tctx, r.out.result, "EnumServicesStatus failed");
     506             :         }
     507             : 
     508           0 :         if (services_returned > 0) {
     509             : 
     510             :                 enum ndr_err_code ndr_err;
     511             :                 DATA_BLOB blob;
     512             :                 struct ndr_pull *ndr;
     513             : 
     514           0 :                 blob.length = r.in.offered;
     515           0 :                 blob.data = talloc_steal(tctx, r.out.service);
     516             : 
     517           0 :                 ndr = ndr_pull_init_blob(&blob, tctx);
     518             : 
     519           0 :                 service = talloc_array(tctx, struct ENUM_SERVICE_STATUSW, services_returned);
     520           0 :                 if (!service) {
     521           0 :                         return false;
     522             :                 }
     523             : 
     524           0 :                 ndr_err = ndr_pull_ENUM_SERVICE_STATUSW_array(
     525             :                                 ndr, services_returned, service);
     526           0 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     527           0 :                         return false;
     528             :                 }
     529             :         }
     530             : 
     531           0 :         for(i = 0; i < services_returned; i++) {
     532             : 
     533           0 :                 torture_assert(tctx, service[i].service_name,
     534             :                         "Service without name returned!");
     535             : 
     536           0 :                 printf("%-20s   \"%s\", Type: %d, State: %d\n",
     537           0 :                         service[i].service_name, service[i].display_name,
     538           0 :                         service[i].status.type, service[i].status.state);
     539             :         }
     540             : 
     541           0 :         if (!test_CloseServiceHandle(b, tctx, &h))
     542           0 :                 return false;
     543             : 
     544           0 :         return true;
     545             : }
     546             : 
     547           0 : static bool test_EnumDependentServicesW(struct torture_context *tctx,
     548             :                                         struct dcerpc_pipe *p)
     549             : {
     550             :         struct svcctl_EnumDependentServicesW r;
     551             :         struct policy_handle h, s;
     552             :         uint32_t needed;
     553             :         uint32_t services_returned;
     554             :         uint32_t i;
     555           0 :         uint32_t states[] = { SERVICE_STATE_ACTIVE,
     556             :                               SERVICE_STATE_INACTIVE,
     557             :                               SERVICE_STATE_ALL };
     558           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     559             : 
     560           0 :         if (!test_OpenSCManager(b, tctx, &h))
     561           0 :                 return false;
     562             : 
     563           0 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     564           0 :                 return false;
     565             : 
     566           0 :         r.in.service = &s;
     567           0 :         r.in.offered = 0;
     568           0 :         r.in.state = 0;
     569           0 :         r.out.service_status = NULL;
     570           0 :         r.out.services_returned = &services_returned;
     571           0 :         r.out.needed = &needed;
     572             : 
     573           0 :         torture_assert_ntstatus_ok(tctx,
     574             :                 dcerpc_svcctl_EnumDependentServicesW_r(b, tctx, &r),
     575             :                 "EnumDependentServicesW failed!");
     576             : 
     577           0 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
     578             :                 "EnumDependentServicesW failed!");
     579             : 
     580           0 :         for (i=0; i<ARRAY_SIZE(states); i++) {
     581             : 
     582           0 :                 r.in.state = states[i];
     583             : 
     584           0 :                 torture_assert_ntstatus_ok(tctx,
     585             :                         dcerpc_svcctl_EnumDependentServicesW_r(b, tctx, &r),
     586             :                         "EnumDependentServicesW failed!");
     587             : 
     588           0 :                 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
     589           0 :                         r.in.offered = needed;
     590           0 :                         r.out.service_status = talloc_array(tctx, uint8_t, needed);
     591             : 
     592           0 :                         torture_assert_ntstatus_ok(tctx,
     593             :                                 dcerpc_svcctl_EnumDependentServicesW_r(b, tctx, &r),
     594             :                                 "EnumDependentServicesW failed!");
     595             : 
     596             :                 }
     597             : 
     598           0 :                 torture_assert_werr_ok(tctx, r.out.result,
     599             :                         "EnumDependentServicesW failed");
     600             :         }
     601             : 
     602           0 :         if (!test_CloseServiceHandle(b, tctx, &s))
     603           0 :                 return false;
     604             : 
     605           0 :         if (!test_CloseServiceHandle(b, tctx, &h))
     606           0 :                 return false;
     607             : 
     608           0 :         return true;
     609             : }
     610             : 
     611           0 : static bool test_SCManager(struct torture_context *tctx,
     612             :                            struct dcerpc_pipe *p)
     613             : {
     614             :         struct policy_handle h;
     615           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     616             : 
     617           0 :         if (!test_OpenSCManager(b, tctx, &h))
     618           0 :                 return false;
     619             : 
     620           0 :         if (!test_CloseServiceHandle(b, tctx, &h))
     621           0 :                 return false;
     622             : 
     623           0 :         return true;
     624             : }
     625             : 
     626           0 : static bool test_ChangeServiceConfigW(struct torture_context *tctx,
     627             :                                       struct dcerpc_pipe *p)
     628             : {
     629             :         struct svcctl_ChangeServiceConfigW r;
     630             :         struct svcctl_QueryServiceConfigW q;
     631             :         struct policy_handle h, s;
     632             :         NTSTATUS status;
     633           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     634             :         struct QUERY_SERVICE_CONFIG query;
     635             :         bool ok;
     636             : 
     637           0 :         uint32_t offered = 0;
     638           0 :         uint32_t needed = 0;
     639             : 
     640           0 :         ok = test_OpenSCManager(b, tctx, &h);
     641           0 :         if (!ok) {
     642           0 :                 return false;
     643             :         }
     644             : 
     645           0 :         ok = test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s);
     646           0 :         if (!ok) {
     647           0 :                 return false;
     648             :         }
     649             : 
     650           0 :         q.in.handle = &s;
     651           0 :         q.in.offered = offered;
     652           0 :         q.out.query = &query;
     653           0 :         q.out.needed = &needed;
     654             : 
     655           0 :         status = dcerpc_svcctl_QueryServiceConfigW_r(b, tctx, &q);
     656           0 :         torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfigW failed!");
     657             : 
     658           0 :         if (W_ERROR_EQUAL(q.out.result, WERR_INSUFFICIENT_BUFFER)) {
     659           0 :                 q.in.offered = needed;
     660           0 :                 status = dcerpc_svcctl_QueryServiceConfigW_r(b, tctx, &q);
     661           0 :                 torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfigW failed!");
     662             :         }
     663           0 :         torture_assert_werr_ok(tctx, q.out.result, "QueryServiceConfigW failed!");
     664             : 
     665           0 :         r.in.handle = &s;
     666           0 :         r.in.type               = query.service_type;
     667           0 :         r.in.start_type         = query.start_type;
     668           0 :         r.in.error_control      = query.error_control;
     669             : 
     670             :         /*
     671             :          * according to MS-SCMR 3.1.4.11 NULL params are supposed to leave the
     672             :          * existing values intact.
     673             :          */
     674             : 
     675           0 :         r.in.binary_path        = NULL;
     676           0 :         r.in.load_order_group   = NULL;
     677           0 :         r.in.dependencies       = NULL;
     678           0 :         r.in.dwDependSize       = 0;
     679           0 :         r.in.service_start_name = NULL;
     680           0 :         r.in.password           = NULL;
     681           0 :         r.in.dwPwSize           = 0;
     682           0 :         r.in.display_name       = NULL;
     683           0 :         r.in.tag_id             = NULL;
     684           0 :         r.out.tag_id            = NULL;
     685             : 
     686           0 :         status = dcerpc_svcctl_ChangeServiceConfigW_r(b, tctx, &r);
     687           0 :         torture_assert_ntstatus_ok(tctx, status, "ChangeServiceConfigW failed!");
     688           0 :         torture_assert_werr_ok(tctx, r.out.result, "ChangeServiceConfigW failed!");
     689             : 
     690           0 :         ok = test_CloseServiceHandle(b, tctx, &s);
     691           0 :         if (!ok) {
     692           0 :                 return false;
     693             :         }
     694             : 
     695           0 :         ok = test_CloseServiceHandle(b, tctx, &h);
     696           0 :         if (!ok) {
     697           0 :                 return false;
     698             :         }
     699             : 
     700           0 :         return true;
     701             : }
     702             : 
     703         964 : struct torture_suite *torture_rpc_svcctl(TALLOC_CTX *mem_ctx)
     704             : {
     705         964 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "svcctl");
     706             :         struct torture_rpc_tcase *tcase;
     707             : 
     708         964 :         tcase = torture_suite_add_rpc_iface_tcase(suite, "svcctl", &ndr_table_svcctl);
     709             : 
     710         964 :         torture_rpc_tcase_add_test(tcase, "SCManager",
     711             :                                    test_SCManager);
     712         964 :         torture_rpc_tcase_add_test(tcase, "EnumServicesStatus",
     713             :                                    test_EnumServicesStatus);
     714         964 :         torture_rpc_tcase_add_test(tcase, "EnumDependentServicesW",
     715             :                                    test_EnumDependentServicesW);
     716         964 :         torture_rpc_tcase_add_test(tcase, "QueryServiceStatus",
     717             :                                    test_QueryServiceStatus);
     718         964 :         torture_rpc_tcase_add_test(tcase, "QueryServiceStatusEx",
     719             :                                    test_QueryServiceStatusEx);
     720         964 :         torture_rpc_tcase_add_test(tcase, "QueryServiceConfigW",
     721             :                                    test_QueryServiceConfigW);
     722         964 :         torture_rpc_tcase_add_test(tcase, "QueryServiceConfig2W",
     723             :                                    test_QueryServiceConfig2W);
     724         964 :         torture_rpc_tcase_add_test(tcase, "QueryServiceObjectSecurity",
     725             :                                    test_QueryServiceObjectSecurity);
     726         964 :         torture_rpc_tcase_add_test(tcase, "SetServiceObjectSecurity",
     727             :                                    test_SetServiceObjectSecurity);
     728         964 :         torture_rpc_tcase_add_test(tcase, "StartServiceW",
     729             :                                    test_StartServiceW);
     730         964 :         torture_rpc_tcase_add_test(tcase, "ControlService",
     731             :                                    test_ControlService);
     732         964 :         torture_rpc_tcase_add_test(tcase, "ChangeServiceConfigW",
     733             :                                    test_ChangeServiceConfigW);
     734             : 
     735         964 :         return suite;
     736             : }

Generated by: LCOV version 1.13