2018-08-23 20:16:40 +03:00
# include "includes.h"
# include "torture/torture.h"
# include "librpc/gen_ndr/ndr_winspool.h"
# include "librpc/gen_ndr/ndr_winspool_c.h"
# include "librpc/gen_ndr/ndr_spoolss_c.h"
# include "torture/rpc/torture_rpc.h"
# include "libcli/registry/util_reg.h"
# include "torture/rpc/iremotewinspool_common.h"
2018-10-15 20:28:01 +03:00
# include "lib/printer_driver/printer_driver.h"
2018-08-23 20:16:40 +03:00
2018-10-16 00:01:21 +03:00
void init_winreg_String ( struct winreg_String * name , const char * s )
{
name - > name = s ;
if ( s ! = NULL ) {
name - > name_len = 2 * ( strlen_m ( s ) + 1 ) ;
name - > name_size = name - > name_len ;
} else {
name - > name_len = 0 ;
name - > name_size = 0 ;
}
}
2018-08-23 20:16:40 +03:00
struct spoolss_UserLevel1 test_get_client_info ( struct torture_context * tctx ,
enum client_os_version os ,
enum spoolss_MajorVersion major_number ,
2018-09-21 16:45:33 +03:00
enum spoolss_MinorVersion minor_number ,
const char * machine ,
const char * user )
2018-08-23 20:16:40 +03:00
{
struct spoolss_UserLevel1 level1 ;
level1 . size = 28 ;
2018-09-21 16:45:33 +03:00
level1 . client = talloc_asprintf ( tctx , " \\ \\ %s " , machine ) ;
level1 . user = user ;
2018-08-23 20:16:40 +03:00
level1 . processor = PROCESSOR_ARCHITECTURE_AMD64 ;
level1 . major = major_number ;
level1 . minor = minor_number ;
if ( os = = WIN_SERVER_2016 | | os = = WIN_10 ) {
level1 . build = 10586 ;
} else if ( os = = WIN_SERVER_2012 | | os = = WIN_8 ) {
level1 . build = 9200 ;
} else if ( os = = WIN_SERVER_2008R2 | | os = = WIN_7 ) {
level1 . build = 7007 ;
} else if ( os = = WIN_SERVER_2008 | | os = = WIN_VISTA ) {
level1 . build = 6000 ;
} else if ( os = = WIN_2000 ) {
level1 . build = 1382 ;
}
return level1 ;
}
2023-09-25 21:28:52 +03:00
bool test_AsyncOpenPrinter_byprinter_expect ( struct torture_context * tctx ,
2018-08-23 20:16:40 +03:00
struct test_iremotewinspool_context * ctx ,
struct dcerpc_pipe * p ,
const char * printer_name ,
2023-09-25 21:28:52 +03:00
uint32_t access_mask ,
2018-08-23 20:16:40 +03:00
struct spoolss_UserLevel1 cinfo ,
2023-09-25 21:28:52 +03:00
NTSTATUS expected_status ,
WERROR expected_result ,
2018-08-23 20:16:40 +03:00
struct policy_handle * handle )
{
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct spoolss_UserLevelCtr client_info_ctr ;
struct winspool_AsyncOpenPrinter r ;
2018-08-24 16:36:55 +03:00
NTSTATUS status ;
bool ok = true ;
2018-08-23 20:16:40 +03:00
2023-09-25 21:28:52 +03:00
ZERO_STRUCT ( r ) ;
2018-08-23 20:16:40 +03:00
ZERO_STRUCT ( devmode_ctr ) ;
client_info_ctr . level = 1 ;
client_info_ctr . user_info . level1 = & cinfo ;
r . in . pPrinterName = printer_name ;
r . in . pDatatype = NULL ;
r . in . pDevModeContainer = & devmode_ctr ;
r . in . AccessRequired = access_mask ;
r . in . pClientInfo = & client_info_ctr ;
r . out . pHandle = handle ;
2018-08-24 16:36:55 +03:00
status = dcerpc_winspool_AsyncOpenPrinter_r ( b , tctx , & r ) ;
2023-09-25 21:28:52 +03:00
torture_assert_ntstatus_equal ( tctx , status , expected_status , " AsyncOpenPrinter failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , expected_result ,
2018-08-23 20:16:40 +03:00
" AsyncOpenPrinter failed " ) ;
2018-08-24 16:36:55 +03:00
return ok ;
2018-08-23 20:16:40 +03:00
}
2023-09-25 21:28:52 +03:00
bool test_AsyncOpenPrinter_byprinter ( struct torture_context * tctx ,
struct test_iremotewinspool_context * ctx ,
struct dcerpc_pipe * p ,
const char * printer_name ,
struct spoolss_UserLevel1 cinfo ,
struct policy_handle * handle )
{
return test_AsyncOpenPrinter_byprinter_expect ( tctx ,
ctx ,
p ,
printer_name ,
SERVER_ALL_ACCESS ,
cinfo ,
NT_STATUS_OK ,
WERR_OK ,
handle ) ;
}
2018-08-23 20:16:40 +03:00
bool test_get_environment ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * * architecture )
{
DATA_BLOB blob ;
enum winreg_Type type ;
uint8_t * data ;
uint32_t needed ;
2018-08-24 16:36:55 +03:00
bool ok ;
2018-08-23 20:16:40 +03:00
2018-08-24 16:36:55 +03:00
ok = test_AsyncGetPrinterData_args ( tctx , b , handle , " Architecture " , & type , & data , & needed ) ;
torture_assert ( tctx , ok , " failed to get Architecture " ) ;
2018-08-23 20:16:40 +03:00
torture_assert_int_equal ( tctx , type , REG_SZ , " unexpected type " ) ;
blob = data_blob_const ( data , needed ) ;
torture_assert ( tctx ,
pull_reg_sz ( tctx , & blob , architecture ) ,
" failed to pull environment " ) ;
return true ;
}
bool test_AsyncClosePrinter_byhandle ( struct torture_context * tctx ,
struct test_iremotewinspool_context * ctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle )
{
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct winspool_AsyncClosePrinter r ;
2018-08-24 16:36:55 +03:00
NTSTATUS status ;
bool ok = true ;
2018-08-23 20:16:40 +03:00
r . in . phPrinter = handle ;
r . out . phPrinter = handle ;
2018-08-24 16:36:55 +03:00
status = dcerpc_winspool_AsyncClosePrinter_r ( b , tctx , & r ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done , " AsyncClosePrinter failed " ) ;
2018-08-23 20:16:40 +03:00
torture_assert_werr_ok ( tctx , r . out . result ,
" AsyncClosePrinter failed " ) ;
2018-08-24 16:36:55 +03:00
done :
return ok ;
2018-08-23 20:16:40 +03:00
}
static bool test_AsyncGetPrinterData_checktype ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * value_name ,
enum winreg_Type * expected_type ,
enum winreg_Type * type_p ,
uint8_t * * data_p ,
uint32_t * needed_p )
{
struct winspool_AsyncGetPrinterData r ;
enum winreg_Type type ;
uint32_t needed ;
2018-08-24 16:36:55 +03:00
NTSTATUS status ;
bool ok = true ;
2018-08-23 20:16:40 +03:00
r . in . hPrinter = * handle ;
r . in . pValueName = value_name ;
r . in . nSize = 0 ;
r . out . pType = & type ;
r . out . pData = talloc_zero_array ( tctx , uint8_t , r . in . nSize ) ;
r . out . pcbNeeded = & needed ;
torture_comment ( tctx , " Testing AsyncGetPrinterData(%s) \n " ,
r . in . pValueName ) ;
2018-08-24 16:36:55 +03:00
status = dcerpc_winspool_AsyncGetPrinterData_r ( b , tctx , & r ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done , " AsyncGetPrinterData failed " ) ;
2018-08-23 20:16:40 +03:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_MORE_DATA ) ) {
if ( expected_type ) {
torture_assert_int_equal ( tctx , type , * expected_type , " unexpected type " ) ;
}
r . in . nSize = needed ;
r . out . pData = talloc_zero_array ( tctx , uint8_t , r . in . nSize ) ;
2018-08-24 16:36:55 +03:00
status = dcerpc_winspool_AsyncGetPrinterData_r ( b , tctx , & r ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done , " AsyncGetPrinterData failed " ) ;
2018-08-23 20:16:40 +03:00
}
torture_assert_werr_ok ( tctx , r . out . result ,
" AsyncGetPrinterData failed " ) ;
if ( type_p ) {
* type_p = type ;
}
if ( data_p ) {
* data_p = r . out . pData ;
}
if ( needed_p ) {
* needed_p = needed ;
}
2018-08-24 16:36:55 +03:00
done :
return ok ;
2018-08-23 20:16:40 +03:00
}
bool test_AsyncGetPrinterData_args ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * value_name ,
enum winreg_Type * type_p ,
uint8_t * * data_p ,
uint32_t * needed_p )
{
return test_AsyncGetPrinterData_checktype ( tctx , b , handle ,
value_name ,
NULL ,
type_p , data_p , needed_p ) ;
}
2018-10-15 20:28:01 +03:00
/* Parse a driver inf file */
bool parse_inf_driver ( struct torture_context * tctx ,
const char * driver_name ,
const char * abs_inf_path ,
const char * driver_arch ,
const char * core_driver_inf ,
struct spoolss_AddDriverInfo8 * * _parsed_dinfo )
{
struct spoolss_AddDriverInfo8 * drv_info ;
const char * source_disk_name = NULL ;
NTSTATUS status ;
bool ok = true ;
drv_info = talloc_zero ( tctx , struct spoolss_AddDriverInfo8 ) ;
torture_assert_not_null_goto ( tctx , drv_info , ok , done , " Cannot allocate memory " ) ;
status = driver_inf_parse ( tctx ,
core_driver_inf ,
abs_inf_path ,
driver_arch ,
driver_name ,
drv_info ,
& source_disk_name ) ;
if ( NT_STATUS_EQUAL ( status , NT_STATUS_DRIVER_INTERNAL_ERROR ) ) {
torture_comment ( tctx , " --- Verify the correct torture option:driver_name is provided \n " ) ;
}
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done , " Failed to parse driver inf \n " ) ;
* _parsed_dinfo = drv_info ;
done :
return ok ;
}