2008-11-14 10:18:35 +01:00
/*
2004-08-02 00:24:04 +00:00
Unix SMB / CIFS implementation .
test suite for srvsvc rpc operations
Copyright ( C ) Jelmer Vernooij 2004
2008-11-14 10:18:35 +01:00
2004-08-02 00:24:04 +00: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 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2004-08-02 00:24:04 +00:00
( at your option ) any later version .
2008-11-14 10:18:35 +01:00
2004-08-02 00:24:04 +00: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 10:18:35 +01:00
2004-08-02 00:24:04 +00:00
You should have received a copy of the GNU General Public License
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-08-02 00:24:04 +00:00
*/
# include "includes.h"
2006-01-03 13:41:17 +00:00
# include "torture/torture.h"
2006-03-14 23:35:30 +00:00
# include "librpc/gen_ndr/ndr_svcctl_c.h"
2006-03-14 15:02:05 +00:00
# include "torture/rpc/rpc.h"
2004-08-02 00:24:04 +00:00
2007-08-28 12:54:27 +00:00
static bool test_OpenSCManager ( struct dcerpc_pipe * p , struct torture_context * tctx , struct policy_handle * h )
{
struct svcctl_OpenSCManagerW r ;
2008-11-14 10:18:35 +01:00
2007-08-28 12:54:27 +00:00
r . in . MachineName = NULL ;
r . in . DatabaseName = NULL ;
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
r . out . handle = h ;
2008-11-14 10:18:35 +01:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_svcctl_OpenSCManagerW ( p , tctx , & r ) ,
" OpenSCManager failed! " ) ;
2007-08-28 12:54:27 +00:00
return true ;
}
static bool test_CloseServiceHandle ( struct dcerpc_pipe * p , struct torture_context * tctx , struct policy_handle * h )
{
2008-11-14 10:18:35 +01:00
struct svcctl_CloseServiceHandle r ;
2007-08-28 12:54:27 +00:00
r . in . handle = h ;
r . out . handle = h ;
2008-11-14 10:18:35 +01:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_svcctl_CloseServiceHandle ( p , tctx , & r ) ,
" CloseServiceHandle failed " ) ;
2007-08-28 12:54:27 +00:00
return true ;
}
2008-11-14 11:24:52 +01:00
static bool test_OpenService ( struct dcerpc_pipe * p , struct torture_context * tctx ,
struct policy_handle * h , const char * name , struct policy_handle * s )
{
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 ,
dcerpc_svcctl_OpenServiceW ( p , tctx , & r ) ,
" OpenServiceW failed! " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " OpenServiceW failed! " ) ;
return true ;
}
static bool test_QueryServiceStatusEx ( struct torture_context * tctx , struct dcerpc_pipe * p )
{
struct svcctl_QueryServiceStatusEx r ;
struct policy_handle h , s ;
NTSTATUS status ;
uint32_t info_level = 0 ;
uint8_t * buffer ;
uint32_t buf_size = 0 ;
uint32_t bytes_needed = 0 ;
if ( ! test_OpenSCManager ( p , tctx , & h ) )
return false ;
if ( ! test_OpenService ( p , tctx , & h , " Netlogon " , & s ) )
return false ;
buffer = talloc ( tctx , uint8_t ) ;
r . in . handle = & s ;
2008-11-27 09:44:51 +01:00
r . in . info_level = info_level ;
2008-11-14 11:24:52 +01:00
r . in . buf_size = buf_size ;
r . out . buffer = buffer ;
r . out . bytes_needed = & bytes_needed ;
status = dcerpc_svcctl_QueryServiceStatusEx ( p , tctx , & r ) ;
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceStatusEx failed! " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
r . in . buf_size = bytes_needed ;
buffer = talloc_array ( tctx , uint8_t , bytes_needed ) ;
r . out . buffer = buffer ;
status = dcerpc_svcctl_QueryServiceStatusEx ( p , tctx , & r ) ;
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceStatusEx failed! " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " QueryServiceStatusEx failed! " ) ;
}
if ( ! test_CloseServiceHandle ( p , tctx , & s ) )
return false ;
if ( ! test_CloseServiceHandle ( p , tctx , & h ) )
return false ;
return true ;
}
2008-11-14 11:36:47 +01:00
static bool test_QueryServiceConfig2W ( struct torture_context * tctx , struct dcerpc_pipe * p )
{
struct svcctl_QueryServiceConfig2W r ;
struct policy_handle h , s ;
NTSTATUS status ;
2008-11-27 09:44:51 +01:00
uint32_t info_level = 1 ;
2008-11-14 11:36:47 +01:00
uint8_t * buffer ;
uint32_t buf_size = 0 ;
uint32_t bytes_needed = 0 ;
if ( ! test_OpenSCManager ( p , tctx , & h ) )
return false ;
if ( ! test_OpenService ( p , tctx , & h , " Netlogon " , & s ) )
return false ;
buffer = talloc ( tctx , uint8_t ) ;
r . in . handle = & s ;
2008-11-27 09:44:51 +01:00
r . in . info_level = info_level ;
2008-11-14 11:36:47 +01:00
r . in . buf_size = buf_size ;
r . out . buffer = buffer ;
r . out . bytes_needed = & bytes_needed ;
status = dcerpc_svcctl_QueryServiceConfig2W ( p , tctx , & r ) ;
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceConfig2W failed! " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
r . in . buf_size = bytes_needed ;
buffer = talloc_array ( tctx , uint8_t , bytes_needed ) ;
r . out . buffer = buffer ;
status = dcerpc_svcctl_QueryServiceConfig2W ( p , tctx , & r ) ;
torture_assert_ntstatus_ok ( tctx , status , " QueryServiceConfig2W failed! " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " QueryServiceConfig2W failed! " ) ;
}
if ( ! test_CloseServiceHandle ( p , tctx , & s ) )
return false ;
if ( ! test_CloseServiceHandle ( p , tctx , & h ) )
return false ;
return true ;
}
2007-08-28 12:54:27 +00:00
static bool test_EnumServicesStatus ( struct torture_context * tctx , struct dcerpc_pipe * p )
2004-08-02 00:24:04 +00:00
{
2004-08-10 20:55:42 +00:00
struct svcctl_EnumServicesStatusW r ;
2007-08-28 12:54:27 +00:00
struct policy_handle h ;
2004-08-02 00:24:04 +00:00
int i ;
NTSTATUS status ;
2005-02-10 05:09:35 +00:00
uint32_t resume_handle = 0 ;
2008-11-14 10:18:35 +01:00
struct ENUM_SERVICE_STATUS * service = NULL ;
2008-11-14 11:25:30 +01:00
uint32_t bytes_needed = 0 ;
uint32_t services_returned = 0 ;
2004-08-02 00:24:04 +00:00
2007-08-28 12:54:27 +00:00
if ( ! test_OpenSCManager ( p , tctx , & h ) )
return false ;
r . in . handle = & h ;
2004-08-02 00:24:04 +00:00
r . in . type = SERVICE_TYPE_WIN32 ;
r . in . state = SERVICE_STATE_ALL ;
2004-08-03 23:06:15 +00:00
r . in . buf_size = 0 ;
2004-08-02 00:24:04 +00:00
r . in . resume_handle = & resume_handle ;
2004-08-03 23:06:15 +00:00
r . out . service = NULL ;
2004-08-02 00:24:04 +00:00
r . out . resume_handle = & resume_handle ;
2008-11-14 11:25:30 +01:00
r . out . services_returned = & services_returned ;
r . out . bytes_needed = & bytes_needed ;
2004-08-02 00:24:04 +00:00
2007-08-28 12:54:27 +00:00
status = dcerpc_svcctl_EnumServicesStatusW ( p , tctx , & r ) ;
2004-08-02 00:24:04 +00:00
2007-08-28 12:54:27 +00:00
torture_assert_ntstatus_ok ( tctx , status , " EnumServicesStatus failed! " ) ;
2004-08-02 00:24:04 +00:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_MORE_DATA ) ) {
2008-11-14 11:25:30 +01:00
r . in . buf_size = bytes_needed ;
r . out . service = talloc_array ( tctx , uint8_t , bytes_needed ) ;
2008-11-14 10:18:35 +01:00
2007-08-28 12:54:27 +00:00
status = dcerpc_svcctl_EnumServicesStatusW ( p , tctx , & r ) ;
2004-08-02 00:24:04 +00:00
2007-08-28 12:54:27 +00:00
torture_assert_ntstatus_ok ( tctx , status , " EnumServicesStatus failed! " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " EnumServicesStatus failed " ) ;
2004-08-02 00:24:04 +00:00
2004-08-03 23:06:15 +00:00
service = ( struct ENUM_SERVICE_STATUS * ) r . out . service ;
2004-08-02 00:24:04 +00:00
}
2008-11-14 11:25:30 +01:00
for ( i = 0 ; i < services_returned ; i + + ) {
2004-08-03 23:06:15 +00:00
printf ( " Type: %d, State: %d \n " , service [ i ] . status . type , service [ i ] . status . state ) ;
2004-08-02 00:24:04 +00:00
}
2008-11-14 10:18:35 +01:00
2007-08-28 12:54:27 +00:00
if ( ! test_CloseServiceHandle ( p , tctx , & h ) )
return false ;
2004-08-02 00:24:04 +00:00
2007-08-28 12:54:27 +00:00
return true ;
2004-08-02 00:24:04 +00:00
}
2008-11-14 10:18:35 +01:00
static bool test_SCManager ( struct torture_context * tctx ,
2007-08-28 12:54:27 +00:00
struct dcerpc_pipe * p )
2004-08-02 00:24:04 +00:00
{
2007-08-28 12:54:27 +00:00
struct policy_handle h ;
2004-08-02 00:24:04 +00:00
2007-08-28 12:54:27 +00:00
if ( ! test_OpenSCManager ( p , tctx , & h ) )
return false ;
2004-08-02 00:24:04 +00:00
2007-08-28 12:54:27 +00:00
if ( ! test_CloseServiceHandle ( p , tctx , & h ) )
return false ;
2004-08-02 00:24:04 +00:00
2007-08-28 12:54:27 +00:00
return true ;
}
2004-08-02 00:24:04 +00:00
2007-08-28 12:54:27 +00:00
struct torture_suite * torture_rpc_svcctl ( TALLOC_CTX * mem_ctx )
{
struct torture_suite * suite = torture_suite_create ( mem_ctx , " SVCCTL " ) ;
2007-08-28 16:24:18 +00:00
struct torture_rpc_tcase * tcase ;
2007-08-28 12:54:27 +00:00
2008-11-14 10:18:35 +01: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 ) ;
2008-11-14 11:24:52 +01:00
torture_rpc_tcase_add_test ( tcase , " QueryServiceStatusEx " ,
test_QueryServiceStatusEx ) ;
2008-11-14 11:36:47 +01:00
torture_rpc_tcase_add_test ( tcase , " QueryServiceConfig2W " ,
test_QueryServiceConfig2W ) ;
2004-08-02 00:24:04 +00:00
2007-08-28 12:54:27 +00:00
return suite ;
2004-08-02 00:24:04 +00:00
}