2008-11-14 12:18:35 +03:00
/*
2004-08-02 04:24:04 +04:00
Unix SMB / CIFS implementation .
2009-04-24 15:44:54 +04:00
test suite for svcctl rpc operations
2004-08-02 04:24:04 +04:00
Copyright ( C ) Jelmer Vernooij 2004
2009-04-09 17:30:18 +04:00
Copyright ( C ) Guenther Deschner 2008 , 2009
2008-11-14 12:18:35 +03:00
2004-08-02 04:24:04 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2004-08-02 04:24:04 +04:00
( at your option ) any later version .
2008-11-14 12:18:35 +03:00
2004-08-02 04:24:04 +04:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2008-11-14 12:18:35 +03:00
2004-08-02 04:24:04 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-08-02 04:24:04 +04:00
*/
# include "includes.h"
2006-03-15 02:35:30 +03:00
# include "librpc/gen_ndr/ndr_svcctl_c.h"
2009-01-09 18:16:11 +03:00
# include "librpc/gen_ndr/ndr_svcctl.h"
2010-09-21 04:41:18 +04:00
# include "librpc/gen_ndr/ndr_security.h"
2010-04-14 00:06:51 +04:00
# include "torture/rpc/torture_rpc.h"
2009-01-09 18:16:11 +03:00
# include "param/param.h"
2004-08-02 04:24:04 +04:00
2009-04-20 18:49:01 +04:00
# define TORTURE_DEFAULT_SERVICE "Spooler"
2009-04-15 01:30:13 +04:00
2010-03-15 12:50:12 +03:00
static bool test_OpenSCManager ( struct dcerpc_binding_handle * b ,
struct torture_context * tctx ,
struct policy_handle * h )
2007-08-28 16:54:27 +04:00
{
struct svcctl_OpenSCManagerW r ;
2008-11-14 12:18:35 +03:00
2007-08-28 16:54:27 +04:00
r . in . MachineName = NULL ;
r . in . DatabaseName = NULL ;
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
r . out . handle = h ;
2008-11-14 12:18:35 +03:00
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 12:50:12 +03:00
dcerpc_svcctl_OpenSCManagerW_r ( b , tctx , & r ) ,
2008-11-14 12:18:35 +03:00
" OpenSCManager failed! " ) ;
2007-08-28 16:54:27 +04:00
return true ;
}
2010-03-15 12:50:12 +03:00
static bool test_CloseServiceHandle ( struct dcerpc_binding_handle * b ,
struct torture_context * tctx ,
struct policy_handle * h )
2007-08-28 16:54:27 +04:00
{
2008-11-14 12:18:35 +03:00
struct svcctl_CloseServiceHandle r ;
2007-08-28 16:54:27 +04:00
r . in . handle = h ;
r . out . handle = h ;
2008-11-14 12:18:35 +03:00
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 12:50:12 +03:00
dcerpc_svcctl_CloseServiceHandle_r ( b , tctx , & r ) ,
2008-11-14 12:18:35 +03:00
" CloseServiceHandle failed " ) ;
2007-08-28 16:54:27 +04:00
return true ;
}
2010-03-15 12:50:12 +03:00
static bool test_OpenService ( struct dcerpc_binding_handle * b ,
struct torture_context * tctx ,
struct policy_handle * h ,
const char * name ,
struct policy_handle * s )
2008-11-14 13:24:52 +03:00
{
struct svcctl_OpenServiceW r ;
r . in . scmanager_handle = h ;
r . in . ServiceName = name ;
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
r . out . handle = s ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 12:50:12 +03:00
dcerpc_svcctl_OpenServiceW_r ( b , tctx , & r ) ,
2008-11-14 13:24:52 +03:00
" OpenServiceW failed! " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " OpenServiceW failed! " ) ;
return true ;
}
2009-04-09 12:01:02 +04:00
static bool test_QueryServiceStatus ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct svcctl_QueryServiceStatus r ;
struct policy_handle h , s ;
struct SERVICE_STATUS service_status ;
NTSTATUS status ;
2010-03-15 12:50:12 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-04-09 12:01:02 +04:00
2010-03-15 12:50:12 +03:00
if ( ! test_OpenSCManager ( b , tctx , & h ) )
2009-04-09 12:01:02 +04:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_OpenService ( b , tctx , & h , TORTURE_DEFAULT_SERVICE , & s ) )
2009-04-09 12:01:02 +04:00
return false ;
r . in . handle = & s ;
r . out . service_status = & service_status ;
2010-03-15 12:50:12 +03:00
status = dcerpc_svcctl_QueryServiceStatus_r ( b , tctx , & r ) ;
2009-04-09 12:01:02 +04:00
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceStatus failed! " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " QueryServiceStatus failed! " ) ;
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & s ) )
2009-04-09 12:01:02 +04:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & h ) )
2009-04-09 12:01:02 +04:00
return false ;
return true ;
}
2008-11-14 13:24:52 +03:00
static bool test_QueryServiceStatusEx ( struct torture_context * tctx , struct dcerpc_pipe * p )
{
struct svcctl_QueryServiceStatusEx r ;
struct policy_handle h , s ;
NTSTATUS status ;
2010-03-15 12:50:12 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2008-11-14 13:24:52 +03:00
2008-11-14 15:49:36 +03:00
uint32_t info_level = SVC_STATUS_PROCESS_INFO ;
2008-11-14 13:24:52 +03:00
uint8_t * buffer ;
2009-04-08 04:11:27 +04:00
uint32_t offered = 0 ;
uint32_t needed = 0 ;
2008-11-14 13:24:52 +03:00
2010-03-15 12:50:12 +03:00
if ( ! test_OpenSCManager ( b , tctx , & h ) )
2008-11-14 13:24:52 +03:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_OpenService ( b , tctx , & h , TORTURE_DEFAULT_SERVICE , & s ) )
2008-11-14 13:24:52 +03:00
return false ;
buffer = talloc ( tctx , uint8_t ) ;
r . in . handle = & s ;
2008-11-27 11:44:51 +03:00
r . in . info_level = info_level ;
2009-04-08 04:11:27 +04:00
r . in . offered = offered ;
2008-11-14 13:24:52 +03:00
r . out . buffer = buffer ;
2009-04-08 04:11:27 +04:00
r . out . needed = & needed ;
2008-11-14 13:24:52 +03:00
2010-03-15 12:50:12 +03:00
status = dcerpc_svcctl_QueryServiceStatusEx_r ( b , tctx , & r ) ;
2008-11-14 13:24:52 +03:00
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceStatusEx failed! " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
2009-04-08 04:11:27 +04:00
r . in . offered = needed ;
buffer = talloc_array ( tctx , uint8_t , needed ) ;
2008-11-14 13:24:52 +03:00
r . out . buffer = buffer ;
2010-03-15 12:50:12 +03:00
status = dcerpc_svcctl_QueryServiceStatusEx_r ( b , tctx , & r ) ;
2008-11-14 13:24:52 +03:00
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceStatusEx failed! " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " QueryServiceStatusEx failed! " ) ;
}
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & s ) )
2008-11-14 13:24:52 +03:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & h ) )
2008-11-14 13:24:52 +03:00
return false ;
return true ;
}
2009-04-09 12:07:07 +04:00
static bool test_QueryServiceConfigW ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct svcctl_QueryServiceConfigW r ;
struct QUERY_SERVICE_CONFIG query ;
struct policy_handle h , s ;
NTSTATUS status ;
2010-03-15 12:50:12 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-04-09 12:07:07 +04:00
uint32_t offered = 0 ;
uint32_t needed = 0 ;
2010-03-15 12:50:12 +03:00
if ( ! test_OpenSCManager ( b , tctx , & h ) )
2009-04-09 12:07:07 +04:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_OpenService ( b , tctx , & h , TORTURE_DEFAULT_SERVICE , & s ) )
2009-04-09 12:07:07 +04:00
return false ;
r . in . handle = & s ;
r . in . offered = offered ;
r . out . query = & query ;
r . out . needed = & needed ;
2010-03-15 12:50:12 +03:00
status = dcerpc_svcctl_QueryServiceConfigW_r ( b , tctx , & r ) ;
2009-04-09 12:07:07 +04:00
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceConfigW failed! " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
r . in . offered = needed ;
2010-03-15 12:50:12 +03:00
status = dcerpc_svcctl_QueryServiceConfigW_r ( b , tctx , & r ) ;
2009-04-09 12:07:07 +04:00
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceConfigW failed! " ) ;
}
torture_assert_werr_ok ( tctx , r . out . result , " QueryServiceConfigW failed! " ) ;
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & s ) )
2009-04-09 12:07:07 +04:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & h ) )
2009-04-09 12:07:07 +04:00
return false ;
return true ;
}
2008-11-14 13:36:47 +03:00
static bool test_QueryServiceConfig2W ( struct torture_context * tctx , struct dcerpc_pipe * p )
{
struct svcctl_QueryServiceConfig2W r ;
struct policy_handle h , s ;
NTSTATUS status ;
2010-03-15 12:50:12 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2008-11-14 13:36:47 +03:00
2008-11-14 14:03:18 +03:00
uint32_t info_level = SERVICE_CONFIG_DESCRIPTION ;
2008-11-14 13:36:47 +03:00
uint8_t * buffer ;
2009-04-08 04:11:27 +04:00
uint32_t offered = 0 ;
uint32_t needed = 0 ;
2008-11-14 13:36:47 +03:00
2010-03-15 12:50:12 +03:00
if ( ! test_OpenSCManager ( b , tctx , & h ) )
2008-11-14 13:36:47 +03:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_OpenService ( b , tctx , & h , TORTURE_DEFAULT_SERVICE , & s ) )
2008-11-14 13:36:47 +03:00
return false ;
buffer = talloc ( tctx , uint8_t ) ;
r . in . handle = & s ;
2008-11-27 11:44:51 +03:00
r . in . info_level = info_level ;
2009-04-08 04:11:27 +04:00
r . in . offered = offered ;
2008-11-14 13:36:47 +03:00
r . out . buffer = buffer ;
2009-04-08 04:11:27 +04:00
r . out . needed = & needed ;
2008-11-14 13:36:47 +03:00
2010-03-15 12:50:12 +03:00
status = dcerpc_svcctl_QueryServiceConfig2W_r ( b , tctx , & r ) ;
2008-11-14 13:36:47 +03:00
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceConfig2W failed! " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
2009-04-08 04:11:27 +04:00
r . in . offered = needed ;
buffer = talloc_array ( tctx , uint8_t , needed ) ;
2008-11-14 13:36:47 +03:00
r . out . buffer = buffer ;
2010-03-15 12:50:12 +03:00
status = dcerpc_svcctl_QueryServiceConfig2W_r ( b , tctx , & r ) ;
2008-11-14 13:36:47 +03:00
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceConfig2W failed! " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " QueryServiceConfig2W failed! " ) ;
}
2009-01-08 19:28:20 +03:00
r . in . info_level = SERVICE_CONFIG_FAILURE_ACTIONS ;
2009-04-08 04:11:27 +04:00
r . in . offered = offered ;
2009-01-08 19:28:20 +03:00
r . out . buffer = buffer ;
2009-04-08 04:11:27 +04:00
r . out . needed = & needed ;
2009-01-08 19:28:20 +03:00
2010-03-15 12:50:12 +03:00
status = dcerpc_svcctl_QueryServiceConfig2W_r ( b , tctx , & r ) ;
2009-01-08 19:28:20 +03:00
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceConfig2W failed! " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
2009-04-08 04:11:27 +04:00
r . in . offered = needed ;
buffer = talloc_array ( tctx , uint8_t , needed ) ;
2009-01-08 19:28:20 +03:00
r . out . buffer = buffer ;
2010-03-15 12:50:12 +03:00
status = dcerpc_svcctl_QueryServiceConfig2W_r ( b , tctx , & r ) ;
2009-01-08 19:28:20 +03:00
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceConfig2W failed! " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " QueryServiceConfig2W failed! " ) ;
}
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & s ) )
2008-11-14 13:36:47 +03:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & h ) )
2008-11-14 13:36:47 +03:00
return false ;
return true ;
}
2009-04-09 12:26:17 +04:00
static bool test_QueryServiceObjectSecurity ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct svcctl_QueryServiceObjectSecurity r ;
struct policy_handle h , s ;
2010-03-15 12:50:12 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-04-09 12:26:17 +04:00
uint8_t * buffer ;
uint32_t needed ;
2010-09-21 04:41:18 +04:00
enum ndr_err_code ndr_err ;
struct security_descriptor sd ;
DATA_BLOB blob ;
2010-03-15 12:50:12 +03:00
if ( ! test_OpenSCManager ( b , tctx , & h ) )
2009-04-09 12:26:17 +04:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_OpenService ( b , tctx , & h , TORTURE_DEFAULT_SERVICE , & s ) )
2009-04-09 12:26:17 +04:00
return false ;
r . in . handle = & s ;
r . in . security_flags = 0 ;
r . in . offered = 0 ;
r . out . buffer = NULL ;
r . out . needed = & needed ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 12:50:12 +03:00
dcerpc_svcctl_QueryServiceObjectSecurity_r ( b , tctx , & r ) ,
2009-04-09 12:26:17 +04:00
" QueryServiceObjectSecurity failed! " ) ;
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_PARAM ,
" QueryServiceObjectSecurity failed! " ) ;
r . in . security_flags = SECINFO_DACL ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 12:50:12 +03:00
dcerpc_svcctl_QueryServiceObjectSecurity_r ( b , tctx , & r ) ,
2009-04-09 12:26:17 +04:00
" QueryServiceObjectSecurity failed! " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
r . in . offered = needed ;
buffer = talloc_array ( tctx , uint8_t , needed ) ;
r . out . buffer = buffer ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 12:50:12 +03:00
dcerpc_svcctl_QueryServiceObjectSecurity_r ( b , tctx , & r ) ,
2009-04-09 12:26:17 +04:00
" QueryServiceObjectSecurity failed! " ) ;
}
torture_assert_werr_ok ( tctx , r . out . result , " QueryServiceObjectSecurity failed! " ) ;
2010-09-21 04:41:18 +04:00
blob = data_blob_const ( buffer , needed ) ;
ndr_err = ndr_pull_struct_blob ( & blob , tctx , & sd ,
( ndr_pull_flags_fn_t ) ndr_pull_security_descriptor ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
return false ;
}
if ( DEBUGLEVEL > = 1 ) {
NDR_PRINT_DEBUG ( security_descriptor , & sd ) ;
}
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & s ) )
2009-04-09 12:26:17 +04:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & h ) )
2009-04-09 12:26:17 +04:00
return false ;
return true ;
}
2009-04-24 15:44:54 +04:00
static bool test_SetServiceObjectSecurity ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct svcctl_QueryServiceObjectSecurity q ;
struct svcctl_SetServiceObjectSecurity r ;
struct policy_handle h , s ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
uint8_t * buffer ;
uint32_t needed ;
if ( ! test_OpenSCManager ( b , tctx , & h ) )
return false ;
if ( ! test_OpenService ( b , tctx , & h , TORTURE_DEFAULT_SERVICE , & s ) )
return false ;
q . in . handle = & s ;
q . in . security_flags = SECINFO_DACL ;
q . in . offered = 0 ;
q . out . buffer = NULL ;
q . out . needed = & needed ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_svcctl_QueryServiceObjectSecurity_r ( b , tctx , & q ) ,
" QueryServiceObjectSecurity failed! " ) ;
if ( W_ERROR_EQUAL ( q . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
q . in . offered = needed ;
buffer = talloc_array ( tctx , uint8_t , needed ) ;
q . out . buffer = buffer ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_svcctl_QueryServiceObjectSecurity_r ( b , tctx , & q ) ,
" QueryServiceObjectSecurity failed! " ) ;
}
torture_assert_werr_ok ( tctx , q . out . result ,
" QueryServiceObjectSecurity failed! " ) ;
r . in . handle = & s ;
r . in . security_flags = SECINFO_DACL ;
r . in . buffer = q . out . buffer ;
r . in . offered = * q . out . needed ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_svcctl_SetServiceObjectSecurity_r ( b , tctx , & r ) ,
" SetServiceObjectSecurity failed! " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" SetServiceObjectSecurity failed! " ) ;
if ( ! test_CloseServiceHandle ( b , tctx , & s ) )
return false ;
if ( ! test_CloseServiceHandle ( b , tctx , & h ) )
return false ;
return true ;
}
2009-04-10 22:55:10 +04:00
static bool test_StartServiceW ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct svcctl_StartServiceW r ;
struct policy_handle h , s ;
2010-03-15 12:50:12 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-04-10 22:55:10 +04:00
2010-03-15 12:50:12 +03:00
if ( ! test_OpenSCManager ( b , tctx , & h ) )
2009-04-10 22:55:10 +04:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_OpenService ( b , tctx , & h , TORTURE_DEFAULT_SERVICE , & s ) )
2009-04-10 22:55:10 +04:00
return false ;
r . in . handle = & s ;
r . in . NumArgs = 0 ;
r . in . Arguments = NULL ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 12:50:12 +03:00
dcerpc_svcctl_StartServiceW_r ( b , tctx , & r ) ,
2009-04-10 22:55:10 +04:00
" StartServiceW failed! " ) ;
torture_assert_werr_equal ( tctx , r . out . result ,
WERR_SERVICE_ALREADY_RUNNING ,
" StartServiceW failed! " ) ;
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & s ) )
2009-04-10 22:55:10 +04:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & h ) )
2009-04-10 22:55:10 +04:00
return false ;
return true ;
}
2009-04-10 23:10:07 +04:00
static bool test_ControlService ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct svcctl_ControlService r ;
struct policy_handle h , s ;
struct SERVICE_STATUS service_status ;
2010-03-15 12:50:12 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-04-10 23:10:07 +04:00
2010-03-15 12:50:12 +03:00
if ( ! test_OpenSCManager ( b , tctx , & h ) )
2009-04-10 23:10:07 +04:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_OpenService ( b , tctx , & h , TORTURE_DEFAULT_SERVICE , & s ) )
2009-04-10 23:10:07 +04:00
return false ;
r . in . handle = & s ;
r . in . control = 0 ;
r . out . service_status = & service_status ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 12:50:12 +03:00
dcerpc_svcctl_ControlService_r ( b , tctx , & r ) ,
2009-04-10 23:10:07 +04:00
" ControlService failed! " ) ;
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_PARAM ,
" ControlService failed! " ) ;
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & s ) )
2009-04-10 23:10:07 +04:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & h ) )
2009-04-10 23:10:07 +04:00
return false ;
return true ;
}
2007-08-28 16:54:27 +04:00
static bool test_EnumServicesStatus ( struct torture_context * tctx , struct dcerpc_pipe * p )
2004-08-02 04:24:04 +04:00
{
2004-08-11 00:55:42 +04:00
struct svcctl_EnumServicesStatusW r ;
2007-08-28 16:54:27 +04:00
struct policy_handle h ;
2004-08-02 04:24:04 +04:00
int i ;
NTSTATUS status ;
2005-02-10 08:09:35 +03:00
uint32_t resume_handle = 0 ;
2009-01-08 18:54:08 +03:00
struct ENUM_SERVICE_STATUSW * service = NULL ;
2009-04-08 04:11:27 +04:00
uint32_t needed = 0 ;
2008-11-14 13:25:30 +03:00
uint32_t services_returned = 0 ;
2010-03-15 12:50:12 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2004-08-02 04:24:04 +04:00
2010-03-15 12:50:12 +03:00
if ( ! test_OpenSCManager ( b , tctx , & h ) )
2007-08-28 16:54:27 +04:00
return false ;
r . in . handle = & h ;
2004-08-02 04:24:04 +04:00
r . in . type = SERVICE_TYPE_WIN32 ;
r . in . state = SERVICE_STATE_ALL ;
2009-04-08 04:11:27 +04:00
r . in . offered = 0 ;
2004-08-02 04:24:04 +04:00
r . in . resume_handle = & resume_handle ;
2004-08-04 03:06:15 +04:00
r . out . service = NULL ;
2004-08-02 04:24:04 +04:00
r . out . resume_handle = & resume_handle ;
2008-11-14 13:25:30 +03:00
r . out . services_returned = & services_returned ;
2009-04-08 04:11:27 +04:00
r . out . needed = & needed ;
2004-08-02 04:24:04 +04:00
2010-03-15 12:50:12 +03:00
status = dcerpc_svcctl_EnumServicesStatusW_r ( b , tctx , & r ) ;
2004-08-02 04:24:04 +04:00
2007-08-28 16:54:27 +04:00
torture_assert_ntstatus_ok ( tctx , status , " EnumServicesStatus failed! " ) ;
2004-08-02 04:24:04 +04:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_MORE_DATA ) ) {
2009-04-08 04:11:27 +04:00
r . in . offered = needed ;
r . out . service = talloc_array ( tctx , uint8_t , needed ) ;
2008-11-14 12:18:35 +03:00
2010-03-15 12:50:12 +03:00
status = dcerpc_svcctl_EnumServicesStatusW_r ( b , tctx , & r ) ;
2004-08-02 04:24:04 +04:00
2007-08-28 16:54:27 +04:00
torture_assert_ntstatus_ok ( tctx , status , " EnumServicesStatus failed! " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " EnumServicesStatus failed " ) ;
2009-01-09 18:16:11 +03:00
}
if ( services_returned > 0 ) {
enum ndr_err_code ndr_err ;
DATA_BLOB blob ;
struct ndr_pull * ndr ;
2009-04-08 04:11:27 +04:00
blob . length = r . in . offered ;
2009-01-09 18:16:11 +03:00
blob . data = talloc_steal ( tctx , r . out . service ) ;
2004-08-02 04:24:04 +04:00
2010-05-09 19:20:01 +04:00
ndr = ndr_pull_init_blob ( & blob , tctx ) ;
2009-01-09 18:16:11 +03:00
service = talloc_array ( tctx , struct ENUM_SERVICE_STATUSW , services_returned ) ;
if ( ! service ) {
return false ;
}
ndr_err = ndr_pull_ENUM_SERVICE_STATUSW_array (
ndr , services_returned , service ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
return false ;
}
2004-08-02 04:24:04 +04:00
}
2008-11-14 13:25:30 +03:00
for ( i = 0 ; i < services_returned ; i + + ) {
2009-01-09 18:16:11 +03:00
2009-04-14 14:10:22 +04:00
torture_assert ( tctx , service [ i ] . service_name ,
" Service without name returned! " ) ;
2009-01-09 18:16:11 +03:00
printf ( " %-20s \" %s \" , Type: %d, State: %d \n " ,
service [ i ] . service_name , service [ i ] . display_name ,
service [ i ] . status . type , service [ i ] . status . state ) ;
2004-08-02 04:24:04 +04:00
}
2008-11-14 12:18:35 +03:00
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & h ) )
2007-08-28 16:54:27 +04:00
return false ;
2004-08-02 04:24:04 +04:00
2007-08-28 16:54:27 +04:00
return true ;
2004-08-02 04:24:04 +04:00
}
2009-04-09 17:30:18 +04:00
static bool test_EnumDependentServicesW ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct svcctl_EnumDependentServicesW r ;
struct policy_handle h , s ;
uint32_t needed ;
uint32_t services_returned ;
uint32_t i ;
uint32_t states [ ] = { SERVICE_STATE_ACTIVE ,
SERVICE_STATE_INACTIVE ,
SERVICE_STATE_ALL } ;
2010-03-15 12:50:12 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-04-09 17:30:18 +04:00
2010-03-15 12:50:12 +03:00
if ( ! test_OpenSCManager ( b , tctx , & h ) )
2009-04-09 17:30:18 +04:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_OpenService ( b , tctx , & h , TORTURE_DEFAULT_SERVICE , & s ) )
2009-04-09 17:30:18 +04:00
return false ;
r . in . service = & s ;
r . in . offered = 0 ;
r . in . state = 0 ;
r . out . service_status = NULL ;
r . out . services_returned = & services_returned ;
r . out . needed = & needed ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 12:50:12 +03:00
dcerpc_svcctl_EnumDependentServicesW_r ( b , tctx , & r ) ,
2009-04-09 17:30:18 +04:00
" EnumDependentServicesW failed! " ) ;
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_PARAM ,
" EnumDependentServicesW failed! " ) ;
for ( i = 0 ; i < ARRAY_SIZE ( states ) ; i + + ) {
r . in . state = states [ i ] ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 12:50:12 +03:00
dcerpc_svcctl_EnumDependentServicesW_r ( b , tctx , & r ) ,
2009-04-09 17:30:18 +04:00
" EnumDependentServicesW failed! " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_MORE_DATA ) ) {
r . in . offered = needed ;
r . out . service_status = talloc_array ( tctx , uint8_t , needed ) ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 12:50:12 +03:00
dcerpc_svcctl_EnumDependentServicesW_r ( b , tctx , & r ) ,
2009-04-09 17:30:18 +04:00
" EnumDependentServicesW failed! " ) ;
}
torture_assert_werr_ok ( tctx , r . out . result ,
" EnumDependentServicesW failed " ) ;
}
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & s ) )
2009-04-09 17:30:18 +04:00
return false ;
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & h ) )
2009-04-09 17:30:18 +04:00
return false ;
return true ;
}
2008-11-14 12:18:35 +03:00
static bool test_SCManager ( struct torture_context * tctx ,
2010-03-15 12:50:12 +03:00
struct dcerpc_pipe * p )
2004-08-02 04:24:04 +04:00
{
2007-08-28 16:54:27 +04:00
struct policy_handle h ;
2010-03-15 12:50:12 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2004-08-02 04:24:04 +04:00
2010-03-15 12:50:12 +03:00
if ( ! test_OpenSCManager ( b , tctx , & h ) )
2007-08-28 16:54:27 +04:00
return false ;
2004-08-02 04:24:04 +04:00
2010-03-15 12:50:12 +03:00
if ( ! test_CloseServiceHandle ( b , tctx , & h ) )
2007-08-28 16:54:27 +04:00
return false ;
2004-08-02 04:24:04 +04:00
2007-08-28 16:54:27 +04:00
return true ;
}
2004-08-02 04:24:04 +04:00
2007-08-28 16:54:27 +04:00
struct torture_suite * torture_rpc_svcctl ( TALLOC_CTX * mem_ctx )
{
2010-12-11 05:26:31 +03:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " svcctl " ) ;
2007-08-28 20:24:18 +04:00
struct torture_rpc_tcase * tcase ;
2007-08-28 16:54:27 +04:00
2008-11-14 12:18:35 +03:00
tcase = torture_suite_add_rpc_iface_tcase ( suite , " svcctl " , & ndr_table_svcctl ) ;
torture_rpc_tcase_add_test ( tcase , " SCManager " ,
test_SCManager ) ;
torture_rpc_tcase_add_test ( tcase , " EnumServicesStatus " ,
test_EnumServicesStatus ) ;
2009-04-09 17:30:18 +04:00
torture_rpc_tcase_add_test ( tcase , " EnumDependentServicesW " ,
test_EnumDependentServicesW ) ;
2009-04-09 12:01:02 +04:00
torture_rpc_tcase_add_test ( tcase , " QueryServiceStatus " ,
test_QueryServiceStatus ) ;
2008-11-14 13:24:52 +03:00
torture_rpc_tcase_add_test ( tcase , " QueryServiceStatusEx " ,
test_QueryServiceStatusEx ) ;
2009-04-09 12:07:07 +04:00
torture_rpc_tcase_add_test ( tcase , " QueryServiceConfigW " ,
test_QueryServiceConfigW ) ;
2008-11-14 13:36:47 +03:00
torture_rpc_tcase_add_test ( tcase , " QueryServiceConfig2W " ,
test_QueryServiceConfig2W ) ;
2009-04-09 12:26:17 +04:00
torture_rpc_tcase_add_test ( tcase , " QueryServiceObjectSecurity " ,
test_QueryServiceObjectSecurity ) ;
2009-04-24 15:44:54 +04:00
torture_rpc_tcase_add_test ( tcase , " SetServiceObjectSecurity " ,
test_SetServiceObjectSecurity ) ;
2009-04-10 22:55:10 +04:00
torture_rpc_tcase_add_test ( tcase , " StartServiceW " ,
test_StartServiceW ) ;
2009-04-10 23:10:07 +04:00
torture_rpc_tcase_add_test ( tcase , " ControlService " ,
test_ControlService ) ;
2004-08-02 04:24:04 +04:00
2007-08-28 16:54:27 +04:00
return suite ;
2004-08-02 04:24:04 +04:00
}