LCOV - code coverage report
Current view: top level - source4/torture/rpc - svcctl.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 308 364 84.6 %
Date: 2021-09-23 10:06:22 Functions: 16 16 100.0 %

          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          48 : 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          48 :         r.in.MachineName = NULL;
      38          48 :         r.in.DatabaseName = NULL;
      39          48 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
      40          48 :         r.out.handle = h;
      41             : 
      42          48 :         torture_assert_ntstatus_ok(tctx,
      43             :                                    dcerpc_svcctl_OpenSCManagerW_r(b, tctx, &r),
      44             :                                    "OpenSCManager failed!");
      45             : 
      46          48 :         return true;
      47             : }
      48             : 
      49          80 : 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          80 :         r.in.handle = h;
      56          80 :         r.out.handle = h;
      57          80 :         torture_assert_ntstatus_ok(tctx,
      58             :                                    dcerpc_svcctl_CloseServiceHandle_r(b, tctx, &r),
      59             :                                    "CloseServiceHandle failed");
      60             : 
      61          80 :         return true;
      62             : }
      63             : 
      64          40 : 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          40 :         r.in.scmanager_handle = h;
      73          40 :         r.in.ServiceName = name;
      74          40 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
      75          40 :         r.out.handle = s;
      76             : 
      77          40 :         torture_assert_ntstatus_ok(tctx,
      78             :                                    dcerpc_svcctl_OpenServiceW_r(b, tctx, &r),
      79             :                                    "OpenServiceW failed!");
      80          40 :         torture_assert_werr_ok(tctx, r.out.result, "OpenServiceW failed!");
      81             : 
      82          40 :         return true;
      83             : 
      84             : }
      85             : 
      86           4 : 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           4 :         struct dcerpc_binding_handle *b = p->binding_handle;
      94             : 
      95           4 :         if (!test_OpenSCManager(b, tctx, &h))
      96           0 :                 return false;
      97             : 
      98           4 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
      99           0 :                 return false;
     100             : 
     101           4 :         r.in.handle = &s;
     102           4 :         r.out.service_status = &service_status;
     103             : 
     104           4 :         status = dcerpc_svcctl_QueryServiceStatus_r(b, tctx, &r);
     105           4 :         torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatus failed!");
     106           4 :         torture_assert_werr_ok(tctx, r.out.result, "QueryServiceStatus failed!");
     107             : 
     108           4 :         if (!test_CloseServiceHandle(b, tctx, &s))
     109           0 :                 return false;
     110             : 
     111           4 :         if (!test_CloseServiceHandle(b, tctx, &h))
     112           0 :                 return false;
     113             : 
     114           4 :         return true;
     115             : }
     116             : 
     117           4 : 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           4 :         struct dcerpc_binding_handle *b = p->binding_handle;
     123             : 
     124           4 :         uint32_t info_level = SVC_STATUS_PROCESS_INFO;
     125             :         uint8_t *buffer;
     126           4 :         uint32_t offered = 0;
     127           4 :         uint32_t needed = 0;
     128             : 
     129           4 :         if (!test_OpenSCManager(b, tctx, &h))
     130           0 :                 return false;
     131             : 
     132           4 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     133           0 :                 return false;
     134             : 
     135           4 :         buffer = talloc(tctx, uint8_t);
     136             : 
     137           4 :         r.in.handle = &s;
     138           4 :         r.in.info_level = info_level;
     139           4 :         r.in.offered = offered;
     140           4 :         r.out.buffer = buffer;
     141           4 :         r.out.needed = &needed;
     142             : 
     143           4 :         status = dcerpc_svcctl_QueryServiceStatusEx_r(b, tctx, &r);
     144           4 :         torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!");
     145             : 
     146           4 :         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
     147           4 :                 r.in.offered = needed;
     148           4 :                 buffer = talloc_array(tctx, uint8_t, needed);
     149           4 :                 r.out.buffer = buffer;
     150             : 
     151           4 :                 status = dcerpc_svcctl_QueryServiceStatusEx_r(b, tctx, &r);
     152           4 :                 torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!");
     153           4 :                 torture_assert_werr_ok(tctx, r.out.result, "QueryServiceStatusEx failed!");
     154             :         }
     155             : 
     156           4 :         if (!test_CloseServiceHandle(b, tctx, &s))
     157           0 :                 return false;
     158             : 
     159           4 :         if (!test_CloseServiceHandle(b, tctx, &h))
     160           0 :                 return false;
     161             : 
     162           4 :         return true;
     163             : }
     164             : 
     165           4 : 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           4 :         struct dcerpc_binding_handle *b = p->binding_handle;
     173             : 
     174           4 :         uint32_t offered = 0;
     175           4 :         uint32_t needed = 0;
     176             : 
     177           4 :         if (!test_OpenSCManager(b, tctx, &h))
     178           0 :                 return false;
     179             : 
     180           4 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     181           0 :                 return false;
     182             : 
     183           4 :         r.in.handle = &s;
     184           4 :         r.in.offered = offered;
     185           4 :         r.out.query = &query;
     186           4 :         r.out.needed = &needed;
     187             : 
     188           4 :         status = dcerpc_svcctl_QueryServiceConfigW_r(b, tctx, &r);
     189           4 :         torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfigW failed!");
     190             : 
     191           4 :         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
     192           4 :                 r.in.offered = needed;
     193           4 :                 status = dcerpc_svcctl_QueryServiceConfigW_r(b, tctx, &r);
     194           4 :                 torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfigW failed!");
     195             :         }
     196             : 
     197           4 :         torture_assert_werr_ok(tctx, r.out.result, "QueryServiceConfigW failed!");
     198             : 
     199           4 :         if (!test_CloseServiceHandle(b, tctx, &s))
     200           0 :                 return false;
     201             : 
     202           4 :         if (!test_CloseServiceHandle(b, tctx, &h))
     203           0 :                 return false;
     204             : 
     205           4 :         return true;
     206             : }
     207             : 
     208           4 : 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           4 :         struct dcerpc_binding_handle *b = p->binding_handle;
     214             : 
     215           4 :         uint32_t info_level = SERVICE_CONFIG_DESCRIPTION;
     216             :         uint8_t *buffer;
     217           4 :         uint32_t offered = 0;
     218           4 :         uint32_t needed = 0;
     219             : 
     220           4 :         if (!test_OpenSCManager(b, tctx, &h))
     221           0 :                 return false;
     222             : 
     223           4 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     224           0 :                 return false;
     225             : 
     226           4 :         buffer = talloc(tctx, uint8_t);
     227             : 
     228           4 :         r.in.handle = &s;
     229           4 :         r.in.info_level = info_level;
     230           4 :         r.in.offered = offered;
     231           4 :         r.out.buffer = buffer;
     232           4 :         r.out.needed = &needed;
     233             : 
     234           4 :         status = dcerpc_svcctl_QueryServiceConfig2W_r(b, tctx, &r);
     235           4 :         torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
     236             : 
     237           4 :         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
     238           4 :                 r.in.offered = needed;
     239           4 :                 buffer = talloc_array(tctx, uint8_t, needed);
     240           4 :                 r.out.buffer = buffer;
     241             : 
     242           4 :                 status = dcerpc_svcctl_QueryServiceConfig2W_r(b, tctx, &r);
     243           4 :                 torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
     244           4 :                 torture_assert_werr_ok(tctx, r.out.result, "QueryServiceConfig2W failed!");
     245             :         }
     246             : 
     247           4 :         r.in.info_level = SERVICE_CONFIG_FAILURE_ACTIONS;
     248           4 :         r.in.offered = offered;
     249           4 :         r.out.buffer = buffer;
     250           4 :         r.out.needed = &needed;
     251             : 
     252           4 :         status = dcerpc_svcctl_QueryServiceConfig2W_r(b, tctx, &r);
     253           4 :         torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
     254             : 
     255           4 :         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
     256           4 :                 r.in.offered = needed;
     257           4 :                 buffer = talloc_array(tctx, uint8_t, needed);
     258           4 :                 r.out.buffer = buffer;
     259             : 
     260           4 :                 status = dcerpc_svcctl_QueryServiceConfig2W_r(b, tctx, &r);
     261           4 :                 torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
     262           4 :                 torture_assert_werr_ok(tctx, r.out.result, "QueryServiceConfig2W failed!");
     263             :         }
     264             : 
     265           4 :         if (!test_CloseServiceHandle(b, tctx, &s))
     266           0 :                 return false;
     267             : 
     268           4 :         if (!test_CloseServiceHandle(b, tctx, &h))
     269           0 :                 return false;
     270             : 
     271           4 :         return true;
     272             : }
     273             : 
     274           4 : 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           4 :         struct dcerpc_binding_handle *b = p->binding_handle;
     280             : 
     281           4 :         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           4 :         if (!test_OpenSCManager(b, tctx, &h))
     289           0 :                 return false;
     290             : 
     291           4 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     292           0 :                 return false;
     293             : 
     294           4 :         r.in.handle = &s;
     295           4 :         r.in.security_flags = 0;
     296           4 :         r.in.offered = 0;
     297           4 :         r.out.buffer = NULL;
     298           4 :         r.out.needed = &needed;
     299             : 
     300           4 :         torture_assert_ntstatus_ok(tctx,
     301             :                 dcerpc_svcctl_QueryServiceObjectSecurity_r(b, tctx, &r),
     302             :                 "QueryServiceObjectSecurity failed!");
     303           4 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
     304             :                 "QueryServiceObjectSecurity failed!");
     305             : 
     306           4 :         r.in.security_flags = SECINFO_DACL;
     307             : 
     308           4 :         torture_assert_ntstatus_ok(tctx,
     309             :                 dcerpc_svcctl_QueryServiceObjectSecurity_r(b, tctx, &r),
     310             :                 "QueryServiceObjectSecurity failed!");
     311             : 
     312           4 :         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
     313           4 :                 r.in.offered = needed;
     314           4 :                 buffer = talloc_array(tctx, uint8_t, needed);
     315           4 :                 r.out.buffer = buffer;
     316           4 :                 torture_assert_ntstatus_ok(tctx,
     317             :                         dcerpc_svcctl_QueryServiceObjectSecurity_r(b, tctx, &r),
     318             :                         "QueryServiceObjectSecurity failed!");
     319             :         }
     320             : 
     321           4 :         torture_assert_werr_ok(tctx, r.out.result, "QueryServiceObjectSecurity failed!");
     322             : 
     323           4 :         blob = data_blob_const(buffer, needed);
     324             : 
     325           4 :         ndr_err = ndr_pull_struct_blob(&blob, tctx, &sd,
     326             :                 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     327           4 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     328           0 :                 return false;
     329             :         }
     330             : 
     331           4 :         if (DEBUGLEVEL >= 1) {
     332           4 :                 NDR_PRINT_DEBUG(security_descriptor, &sd);
     333             :         }
     334             : 
     335           4 :         if (!test_CloseServiceHandle(b, tctx, &s))
     336           0 :                 return false;
     337             : 
     338           4 :         if (!test_CloseServiceHandle(b, tctx, &h))
     339           0 :                 return false;
     340             : 
     341           4 :         return true;
     342             : }
     343             : 
     344           4 : 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           4 :         struct dcerpc_binding_handle *b = p->binding_handle;
     351             : 
     352             :         uint8_t *buffer;
     353             :         uint32_t needed;
     354             : 
     355           4 :         if (!test_OpenSCManager(b, tctx, &h))
     356           0 :                 return false;
     357             : 
     358           4 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     359           0 :                 return false;
     360             : 
     361           4 :         q.in.handle = &s;
     362           4 :         q.in.security_flags = SECINFO_DACL;
     363           4 :         q.in.offered = 0;
     364           4 :         q.out.buffer = NULL;
     365           4 :         q.out.needed = &needed;
     366             : 
     367           4 :         torture_assert_ntstatus_ok(tctx,
     368             :                 dcerpc_svcctl_QueryServiceObjectSecurity_r(b, tctx, &q),
     369             :                 "QueryServiceObjectSecurity failed!");
     370             : 
     371           4 :         if (W_ERROR_EQUAL(q.out.result, WERR_INSUFFICIENT_BUFFER)) {
     372           4 :                 q.in.offered = needed;
     373           4 :                 buffer = talloc_array(tctx, uint8_t, needed);
     374           4 :                 q.out.buffer = buffer;
     375           4 :                 torture_assert_ntstatus_ok(tctx,
     376             :                         dcerpc_svcctl_QueryServiceObjectSecurity_r(b, tctx, &q),
     377             :                         "QueryServiceObjectSecurity failed!");
     378             :         }
     379             : 
     380           4 :         torture_assert_werr_ok(tctx, q.out.result,
     381             :                 "QueryServiceObjectSecurity failed!");
     382             : 
     383           4 :         r.in.handle = &s;
     384           4 :         r.in.security_flags = SECINFO_DACL;
     385           4 :         r.in.buffer = q.out.buffer;
     386           4 :         r.in.offered = *q.out.needed;
     387             : 
     388           4 :         torture_assert_ntstatus_ok(tctx,
     389             :                 dcerpc_svcctl_SetServiceObjectSecurity_r(b, tctx, &r),
     390             :                 "SetServiceObjectSecurity failed!");
     391           4 :         torture_assert_werr_ok(tctx, r.out.result,
     392             :                 "SetServiceObjectSecurity failed!");
     393             : 
     394           4 :         if (!test_CloseServiceHandle(b, tctx, &s))
     395           0 :                 return false;
     396             : 
     397           4 :         if (!test_CloseServiceHandle(b, tctx, &h))
     398           0 :                 return false;
     399             : 
     400           4 :         return true;
     401             : }
     402             : 
     403           4 : 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           4 :         struct dcerpc_binding_handle *b = p->binding_handle;
     409             : 
     410           4 :         if (!test_OpenSCManager(b, tctx, &h))
     411           0 :                 return false;
     412             : 
     413           4 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     414           0 :                 return false;
     415             : 
     416           4 :         r.in.handle = &s;
     417           4 :         r.in.NumArgs = 0;
     418           4 :         r.in.Arguments = NULL;
     419             : 
     420           4 :         torture_assert_ntstatus_ok(tctx,
     421             :                 dcerpc_svcctl_StartServiceW_r(b, tctx, &r),
     422             :                 "StartServiceW failed!");
     423           4 :         torture_assert_werr_equal(tctx, r.out.result,
     424             :                 WERR_SERVICE_ALREADY_RUNNING,
     425             :                 "StartServiceW failed!");
     426             : 
     427           4 :         if (!test_CloseServiceHandle(b, tctx, &s))
     428           0 :                 return false;
     429             : 
     430           4 :         if (!test_CloseServiceHandle(b, tctx, &h))
     431           0 :                 return false;
     432             : 
     433           4 :         return true;
     434             : }
     435             : 
     436           4 : 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           4 :         struct dcerpc_binding_handle *b = p->binding_handle;
     443             : 
     444           4 :         if (!test_OpenSCManager(b, tctx, &h))
     445           0 :                 return false;
     446             : 
     447           4 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     448           0 :                 return false;
     449             : 
     450           4 :         r.in.handle = &s;
     451           4 :         r.in.control = 0;
     452           4 :         r.out.service_status = &service_status;
     453             : 
     454           4 :         torture_assert_ntstatus_ok(tctx,
     455             :                 dcerpc_svcctl_ControlService_r(b, tctx, &r),
     456             :                 "ControlService failed!");
     457           4 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
     458             :                 "ControlService failed!");
     459             : 
     460           4 :         if (!test_CloseServiceHandle(b, tctx, &s))
     461           0 :                 return false;
     462             : 
     463           4 :         if (!test_CloseServiceHandle(b, tctx, &h))
     464           0 :                 return false;
     465             : 
     466           4 :         return true;
     467             : }
     468             : 
     469           4 : 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           4 :         uint32_t resume_handle = 0;
     476           4 :         struct ENUM_SERVICE_STATUSW *service = NULL;
     477           4 :         uint32_t needed = 0;
     478           4 :         uint32_t services_returned = 0;
     479           4 :         struct dcerpc_binding_handle *b = p->binding_handle;
     480             : 
     481           4 :         if (!test_OpenSCManager(b, tctx, &h))
     482           0 :                 return false;
     483             : 
     484           4 :         r.in.handle = &h;
     485           4 :         r.in.type = SERVICE_TYPE_WIN32;
     486           4 :         r.in.state = SERVICE_STATE_ALL;
     487           4 :         r.in.offered = 0;
     488           4 :         r.in.resume_handle = &resume_handle;
     489           4 :         r.out.service = NULL;
     490           4 :         r.out.resume_handle = &resume_handle;
     491           4 :         r.out.services_returned = &services_returned;
     492           4 :         r.out.needed = &needed;
     493             : 
     494           4 :         status = dcerpc_svcctl_EnumServicesStatusW_r(b, tctx, &r);
     495             : 
     496           4 :         torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!");
     497             : 
     498           4 :         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
     499           4 :                 r.in.offered = needed;
     500           4 :                 r.out.service = talloc_array(tctx, uint8_t, needed);
     501             : 
     502           4 :                 status = dcerpc_svcctl_EnumServicesStatusW_r(b, tctx, &r);
     503             : 
     504           4 :                 torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!");
     505           4 :                 torture_assert_werr_ok(tctx, r.out.result, "EnumServicesStatus failed");
     506             :         }
     507             : 
     508           4 :         if (services_returned > 0) {
     509             : 
     510             :                 enum ndr_err_code ndr_err;
     511             :                 DATA_BLOB blob;
     512             :                 struct ndr_pull *ndr;
     513             : 
     514           4 :                 blob.length = r.in.offered;
     515           4 :                 blob.data = talloc_steal(tctx, r.out.service);
     516             : 
     517           4 :                 ndr = ndr_pull_init_blob(&blob, tctx);
     518             : 
     519           4 :                 service = talloc_array(tctx, struct ENUM_SERVICE_STATUSW, services_returned);
     520           4 :                 if (!service) {
     521           0 :                         return false;
     522             :                 }
     523             : 
     524           4 :                 ndr_err = ndr_pull_ENUM_SERVICE_STATUSW_array(
     525             :                                 ndr, services_returned, service);
     526           4 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     527           0 :                         return false;
     528             :                 }
     529             :         }
     530             : 
     531          20 :         for(i = 0; i < services_returned; i++) {
     532             : 
     533          16 :                 torture_assert(tctx, service[i].service_name,
     534             :                         "Service without name returned!");
     535             : 
     536          40 :                 printf("%-20s   \"%s\", Type: %d, State: %d\n",
     537          28 :                         service[i].service_name, service[i].display_name,
     538          16 :                         service[i].status.type, service[i].status.state);
     539             :         }
     540             : 
     541           4 :         if (!test_CloseServiceHandle(b, tctx, &h))
     542           0 :                 return false;
     543             : 
     544           4 :         return true;
     545             : }
     546             : 
     547           4 : 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           4 :         uint32_t states[] = { SERVICE_STATE_ACTIVE,
     556             :                               SERVICE_STATE_INACTIVE,
     557             :                               SERVICE_STATE_ALL };
     558           4 :         struct dcerpc_binding_handle *b = p->binding_handle;
     559             : 
     560           4 :         if (!test_OpenSCManager(b, tctx, &h))
     561           0 :                 return false;
     562             : 
     563           4 :         if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s))
     564           0 :                 return false;
     565             : 
     566           4 :         r.in.service = &s;
     567           4 :         r.in.offered = 0;
     568           4 :         r.in.state = 0;
     569           4 :         r.out.service_status = NULL;
     570           4 :         r.out.services_returned = &services_returned;
     571           4 :         r.out.needed = &needed;
     572             : 
     573           4 :         torture_assert_ntstatus_ok(tctx,
     574             :                 dcerpc_svcctl_EnumDependentServicesW_r(b, tctx, &r),
     575             :                 "EnumDependentServicesW failed!");
     576             : 
     577           4 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
     578             :                 "EnumDependentServicesW failed!");
     579             : 
     580          16 :         for (i=0; i<ARRAY_SIZE(states); i++) {
     581             : 
     582          12 :                 r.in.state = states[i];
     583             : 
     584          12 :                 torture_assert_ntstatus_ok(tctx,
     585             :                         dcerpc_svcctl_EnumDependentServicesW_r(b, tctx, &r),
     586             :                         "EnumDependentServicesW failed!");
     587             : 
     588          12 :                 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          12 :                 torture_assert_werr_ok(tctx, r.out.result,
     599             :                         "EnumDependentServicesW failed");
     600             :         }
     601             : 
     602           4 :         if (!test_CloseServiceHandle(b, tctx, &s))
     603           0 :                 return false;
     604             : 
     605           4 :         if (!test_CloseServiceHandle(b, tctx, &h))
     606           0 :                 return false;
     607             : 
     608           4 :         return true;
     609             : }
     610             : 
     611           4 : static bool test_SCManager(struct torture_context *tctx,
     612             :                            struct dcerpc_pipe *p)
     613             : {
     614             :         struct policy_handle h;
     615           4 :         struct dcerpc_binding_handle *b = p->binding_handle;
     616             : 
     617           4 :         if (!test_OpenSCManager(b, tctx, &h))
     618           0 :                 return false;
     619             : 
     620           4 :         if (!test_CloseServiceHandle(b, tctx, &h))
     621           0 :                 return false;
     622             : 
     623           4 :         return true;
     624             : }
     625             : 
     626           4 : 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           4 :         struct dcerpc_binding_handle *b = p->binding_handle;
     634             :         struct QUERY_SERVICE_CONFIG query;
     635             :         bool ok;
     636             : 
     637           4 :         uint32_t offered = 0;
     638           4 :         uint32_t needed = 0;
     639             : 
     640           4 :         ok = test_OpenSCManager(b, tctx, &h);
     641           4 :         if (!ok) {
     642           0 :                 return false;
     643             :         }
     644             : 
     645           4 :         ok = test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s);
     646           4 :         if (!ok) {
     647           0 :                 return false;
     648             :         }
     649             : 
     650           4 :         q.in.handle = &s;
     651           4 :         q.in.offered = offered;
     652           4 :         q.out.query = &query;
     653           4 :         q.out.needed = &needed;
     654             : 
     655           4 :         status = dcerpc_svcctl_QueryServiceConfigW_r(b, tctx, &q);
     656           4 :         torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfigW failed!");
     657             : 
     658           4 :         if (W_ERROR_EQUAL(q.out.result, WERR_INSUFFICIENT_BUFFER)) {
     659           4 :                 q.in.offered = needed;
     660           4 :                 status = dcerpc_svcctl_QueryServiceConfigW_r(b, tctx, &q);
     661           4 :                 torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfigW failed!");
     662             :         }
     663           4 :         torture_assert_werr_ok(tctx, q.out.result, "QueryServiceConfigW failed!");
     664             : 
     665           4 :         r.in.handle = &s;
     666           4 :         r.in.type               = query.service_type;
     667           4 :         r.in.start_type         = query.start_type;
     668           4 :         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           4 :         r.in.binary_path        = NULL;
     676           4 :         r.in.load_order_group   = NULL;
     677           4 :         r.in.dependencies       = NULL;
     678           4 :         r.in.dwDependSize       = 0;
     679           4 :         r.in.service_start_name = NULL;
     680           4 :         r.in.password           = NULL;
     681           4 :         r.in.dwPwSize           = 0;
     682           4 :         r.in.display_name       = NULL;
     683           4 :         r.in.tag_id             = NULL;
     684           4 :         r.out.tag_id            = NULL;
     685             : 
     686           4 :         status = dcerpc_svcctl_ChangeServiceConfigW_r(b, tctx, &r);
     687           4 :         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        2355 : struct torture_suite *torture_rpc_svcctl(TALLOC_CTX *mem_ctx)
     704             : {
     705        2355 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "svcctl");
     706             :         struct torture_rpc_tcase *tcase;
     707             : 
     708        2355 :         tcase = torture_suite_add_rpc_iface_tcase(suite, "svcctl", &ndr_table_svcctl);
     709             : 
     710        2355 :         torture_rpc_tcase_add_test(tcase, "SCManager",
     711             :                                    test_SCManager);
     712        2355 :         torture_rpc_tcase_add_test(tcase, "EnumServicesStatus",
     713             :                                    test_EnumServicesStatus);
     714        2355 :         torture_rpc_tcase_add_test(tcase, "EnumDependentServicesW",
     715             :                                    test_EnumDependentServicesW);
     716        2355 :         torture_rpc_tcase_add_test(tcase, "QueryServiceStatus",
     717             :                                    test_QueryServiceStatus);
     718        2355 :         torture_rpc_tcase_add_test(tcase, "QueryServiceStatusEx",
     719             :                                    test_QueryServiceStatusEx);
     720        2355 :         torture_rpc_tcase_add_test(tcase, "QueryServiceConfigW",
     721             :                                    test_QueryServiceConfigW);
     722        2355 :         torture_rpc_tcase_add_test(tcase, "QueryServiceConfig2W",
     723             :                                    test_QueryServiceConfig2W);
     724        2355 :         torture_rpc_tcase_add_test(tcase, "QueryServiceObjectSecurity",
     725             :                                    test_QueryServiceObjectSecurity);
     726        2355 :         torture_rpc_tcase_add_test(tcase, "SetServiceObjectSecurity",
     727             :                                    test_SetServiceObjectSecurity);
     728        2355 :         torture_rpc_tcase_add_test(tcase, "StartServiceW",
     729             :                                    test_StartServiceW);
     730        2355 :         torture_rpc_tcase_add_test(tcase, "ControlService",
     731             :                                    test_ControlService);
     732        2355 :         torture_rpc_tcase_add_test(tcase, "ChangeServiceConfigW",
     733             :                                    test_ChangeServiceConfigW);
     734             : 
     735        2355 :         return suite;
     736             : }

Generated by: LCOV version 1.13