2013-01-15 18:23:58 +04:00
/*
Unix SMB / CIFS implementation .
test suite for iremotewinspool rpc operations
Copyright ( C ) Guenther Deschner 2013
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
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
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 .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "torture/torture.h"
# include "librpc/gen_ndr/ndr_winspool.h"
# include "librpc/gen_ndr/ndr_winspool_c.h"
2016-09-05 23:49:39 +03:00
# include "librpc/gen_ndr/ndr_spoolss_c.h"
2013-01-15 18:23:58 +04:00
# include "torture/rpc/torture_rpc.h"
# include "libcli/registry/util_reg.h"
struct test_iremotewinspool_context {
struct GUID object_uuid ;
struct dcerpc_pipe * iremotewinspool_pipe ;
struct policy_handle server_handle ;
const char * environment ;
} ;
2018-08-15 18:10:21 +03:00
enum client_os_version
{
WIN_2000 ,
WIN_VISTA ,
WIN_SERVER_2008 ,
WIN_7 ,
WIN_SERVER_2008R2 ,
WIN_8 ,
WIN_SERVER_2012 ,
WIN_10 ,
WIN_SERVER_2016
} ;
static struct spoolss_UserLevel1 test_get_client_info ( struct torture_context * tctx ,
enum client_os_version os ,
enum spoolss_MajorVersion major_number ,
enum spoolss_MinorVersion minor_number )
{
struct spoolss_UserLevel1 level1 ;
level1 . size = 28 ;
level1 . client = talloc_asprintf ( tctx , " \\ \\ %s " , " mthelena " ) ;
level1 . user = " GD " ;
level1 . processor = PROCESSOR_ARCHITECTURE_AMD64 ;
level1 . major = major_number ;
level1 . minor = minor_number ;
switch ( os ) {
case WIN_SERVER_2016 :
case WIN_10 :
level1 . build = 10586 ;
break ;
case WIN_SERVER_2012 :
case WIN_8 :
level1 . build = 9200 ;
break ;
case WIN_SERVER_2008R2 :
case WIN_7 :
level1 . build = 7007 ;
break ;
case WIN_SERVER_2008 :
case WIN_VISTA :
level1 . build = 6000 ;
break ;
case WIN_2000 :
level1 . build = 1382 ;
break ;
default :
level1 . build = 7007 ;
}
return level1 ;
}
2013-01-15 18:23:58 +04:00
static bool test_AsyncOpenPrinter_byprinter ( struct torture_context * tctx ,
struct test_iremotewinspool_context * ctx ,
struct dcerpc_pipe * p ,
const char * printer_name ,
2018-08-15 18:10:21 +03:00
struct spoolss_UserLevel1 cinfo ,
2013-01-15 18:23:58 +04:00
struct policy_handle * handle )
{
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct spoolss_UserLevelCtr client_info_ctr ;
uint32_t access_mask = SERVER_ALL_ACCESS ;
struct winspool_AsyncOpenPrinter r ;
ZERO_STRUCT ( devmode_ctr ) ;
client_info_ctr . level = 1 ;
2018-08-15 18:10:21 +03:00
client_info_ctr . user_info . level1 = & cinfo ;
2013-01-15 18:23:58 +04:00
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 ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncOpenPrinter_r ( b , tctx , & r ) ,
" AsyncOpenPrinter failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" AsyncOpenPrinter failed " ) ;
return true ;
}
static 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 ;
r . in . phPrinter = handle ;
r . out . phPrinter = handle ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncClosePrinter_r ( b , tctx , & r ) ,
" AsyncClosePrinter failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" AsyncClosePrinter failed " ) ;
return true ;
}
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 ;
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 ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncGetPrinterData_r ( b , tctx , & r ) ,
" AsyncGetPrinterData failed " ) ;
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 ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncGetPrinterData_r ( b , tctx , & r ) ,
" AsyncGetPrinterData failed " ) ;
}
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 ;
}
return true ;
}
2016-09-01 14:57:50 +03:00
static 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 )
2013-01-15 18:23:58 +04:00
{
return test_AsyncGetPrinterData_checktype ( tctx , b , handle ,
value_name ,
NULL ,
type_p , data_p , needed_p ) ;
}
static 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 ;
torture_assert ( tctx ,
2016-09-01 14:57:50 +03:00
test_AsyncGetPrinterData_args ( tctx , b , handle , " Architecture " , & type , & data , & needed ) ,
2013-01-15 18:23:58 +04:00
" failed to get Architecture " ) ;
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 ;
}
static bool torture_rpc_iremotewinspool_setup_common ( struct torture_context * tctx ,
struct test_iremotewinspool_context * t )
{
const char * printer_name ;
2018-08-15 18:10:21 +03:00
struct spoolss_UserLevel1 client_info ;
2013-01-15 18:23:58 +04:00
struct dcerpc_binding * binding ;
torture_assert_ntstatus_ok ( tctx ,
GUID_from_string ( IREMOTEWINSPOOL_OBJECT_GUID , & t - > object_uuid ) ,
" failed to parse GUID " ) ;
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_binding ( tctx , & binding ) ,
" failed to retrieve torture binding " ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_binding_set_object ( binding , t - > object_uuid ) ,
" failed to set object_uuid " ) ;
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection_with_binding ( tctx , binding , & t - > iremotewinspool_pipe , & ndr_table_iremotewinspool ) ,
" Error connecting to server " ) ;
printer_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( t - > iremotewinspool_pipe ) ) ;
2018-08-15 18:10:21 +03:00
client_info = test_get_client_info ( tctx , WIN_2000 , 3 , SPOOLSS_MINOR_VERSION_0 ) ;
2013-01-15 18:23:58 +04:00
torture_assert ( tctx ,
test_AsyncOpenPrinter_byprinter ( tctx , t ,
t - > iremotewinspool_pipe , printer_name ,
2018-08-15 18:10:21 +03:00
client_info , & t - > server_handle ) ,
2013-01-15 18:23:58 +04:00
" failed to open printserver " ) ;
torture_assert ( tctx ,
test_get_environment ( tctx ,
t - > iremotewinspool_pipe - > binding_handle ,
& t - > server_handle , & t - > environment ) ,
" failed to get environment " ) ;
return true ;
}
static bool torture_rpc_iremotewinspool_setup ( struct torture_context * tctx ,
void * * data )
{
struct test_iremotewinspool_context * t ;
* data = t = talloc_zero ( tctx , struct test_iremotewinspool_context ) ;
return torture_rpc_iremotewinspool_setup_common ( tctx , t ) ;
}
static bool torture_rpc_iremotewinspool_teardown_common ( struct torture_context * tctx ,
struct test_iremotewinspool_context * t )
{
test_AsyncClosePrinter_byhandle ( tctx , t , t - > iremotewinspool_pipe , & t - > server_handle ) ;
return true ;
}
static bool torture_rpc_iremotewinspool_teardown ( struct torture_context * tctx ,
void * data )
{
struct test_iremotewinspool_context * t = talloc_get_type ( data , struct test_iremotewinspool_context ) ;
bool ret ;
ret = torture_rpc_iremotewinspool_teardown_common ( tctx , t ) ;
talloc_free ( t ) ;
return ret ;
}
static bool test_AsyncClosePrinter ( struct torture_context * tctx ,
void * private_data )
{
struct test_iremotewinspool_context * ctx =
talloc_get_type_abort ( private_data , struct test_iremotewinspool_context ) ;
struct dcerpc_pipe * p = ctx - > iremotewinspool_pipe ;
const char * printer_name ;
2018-08-15 18:10:21 +03:00
struct spoolss_UserLevel1 client_info ;
2013-01-15 18:23:58 +04:00
struct policy_handle handle ;
printer_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2018-08-15 18:10:21 +03:00
client_info = test_get_client_info ( tctx , WIN_2000 , 3 , SPOOLSS_MINOR_VERSION_0 ) ;
2013-01-15 18:23:58 +04:00
torture_assert ( tctx ,
2018-08-15 18:10:21 +03:00
test_AsyncOpenPrinter_byprinter ( tctx , ctx , p , printer_name , client_info , & handle ) ,
2013-01-15 18:23:58 +04:00
" failed to test AsyncOpenPrinter " ) ;
torture_assert ( tctx ,
test_AsyncClosePrinter_byhandle ( tctx , ctx , p , & handle ) ,
" failed to test AsyncClosePrinter " ) ;
return true ;
}
static bool test_AsyncOpenPrinter ( struct torture_context * tctx ,
void * private_data )
{
struct test_iremotewinspool_context * ctx =
talloc_get_type_abort ( private_data , struct test_iremotewinspool_context ) ;
struct dcerpc_pipe * p = ctx - > iremotewinspool_pipe ;
const char * printer_name ;
2018-08-15 18:10:21 +03:00
struct spoolss_UserLevel1 client_info ;
2013-01-15 18:23:58 +04:00
struct policy_handle handle ;
printer_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2018-08-15 18:10:21 +03:00
client_info = test_get_client_info ( tctx , WIN_2000 , 3 , SPOOLSS_MINOR_VERSION_0 ) ;
2013-01-15 18:23:58 +04:00
torture_assert ( tctx ,
2018-08-15 18:10:21 +03:00
test_AsyncOpenPrinter_byprinter ( tctx , ctx , p , printer_name , client_info , & handle ) ,
2013-01-15 18:23:58 +04:00
" failed to test AsyncOpenPrinter " ) ;
test_AsyncClosePrinter_byhandle ( tctx , ctx , p , & handle ) ;
return true ;
}
2013-05-16 20:21:30 +04:00
static struct spoolss_NotifyOption * setup_printserver_NotifyOption ( struct torture_context * tctx )
{
struct spoolss_NotifyOption * o ;
o = talloc_zero ( tctx , struct spoolss_NotifyOption ) ;
if ( o = = NULL ) {
return NULL ;
}
o - > version = 2 ;
o - > flags = PRINTER_NOTIFY_OPTIONS_REFRESH ;
o - > count = 2 ;
o - > types = talloc_zero_array ( o , struct spoolss_NotifyOptionType , o - > count ) ;
if ( o - > types = = NULL ) {
talloc_free ( o ) ;
return NULL ;
}
o - > types [ 0 ] . type = PRINTER_NOTIFY_TYPE ;
o - > types [ 0 ] . count = 1 ;
o - > types [ 0 ] . fields = talloc_array ( o - > types , union spoolss_Field , o - > types [ 0 ] . count ) ;
if ( o - > types [ 0 ] . fields = = NULL ) {
talloc_free ( o ) ;
return NULL ;
}
o - > types [ 0 ] . fields [ 0 ] . field = PRINTER_NOTIFY_FIELD_SERVER_NAME ;
o - > types [ 1 ] . type = JOB_NOTIFY_TYPE ;
o - > types [ 1 ] . count = 1 ;
o - > types [ 1 ] . fields = talloc_array ( o - > types , union spoolss_Field , o - > types [ 1 ] . count ) ;
if ( o - > types [ 1 ] . fields = = NULL ) {
talloc_free ( o ) ;
return NULL ;
}
o - > types [ 1 ] . fields [ 0 ] . field = JOB_NOTIFY_FIELD_MACHINE_NAME ;
return o ;
}
2016-08-23 19:39:48 +03:00
static bool test_SyncUnRegisterForRemoteNotifications_args ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * notify_handle )
{
struct winspool_SyncUnRegisterForRemoteNotifications r ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
r . in . phRpcHandle = notify_handle ;
r . out . phRpcHandle = notify_handle ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_SyncUnRegisterForRemoteNotifications_r ( b , tctx , & r ) ,
" SyncUnRegisterForRemoteNotifications failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" SyncUnRegisterForRemoteNotifications failed " ) ;
return true ;
}
static bool test_SyncRegisterForRemoteNotifications_args ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * server_handle ,
struct policy_handle * notify_handle ) ;
static bool test_SyncUnRegisterForRemoteNotifications ( struct torture_context * tctx ,
void * private_data )
{
struct test_iremotewinspool_context * ctx =
talloc_get_type_abort ( private_data , struct test_iremotewinspool_context ) ;
struct policy_handle notify_handle ;
torture_assert ( tctx ,
test_SyncRegisterForRemoteNotifications_args ( tctx ,
ctx - > iremotewinspool_pipe ,
& ctx - > server_handle ,
& notify_handle ) ,
" failed to test SyncRegisterForRemoteNotifications " ) ;
torture_assert ( tctx ,
test_SyncUnRegisterForRemoteNotifications_args ( tctx ,
ctx - > iremotewinspool_pipe ,
& notify_handle ) ,
" failed to test UnSyncRegisterForRemoteNotifications " ) ;
return true ;
}
2013-05-16 20:21:30 +04:00
static bool test_SyncRegisterForRemoteNotifications_args ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * server_handle ,
struct policy_handle * notify_handle )
{
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct winspool_SyncRegisterForRemoteNotifications r ;
struct winspool_PrintPropertiesCollection NotifyFilter ;
struct winspool_PrintNamedProperty * c ;
struct spoolss_NotifyOption * options ;
ZERO_STRUCT ( NotifyFilter ) ;
options = setup_printserver_NotifyOption ( tctx ) ;
torture_assert ( tctx , options , " out of memory " ) ;
c = talloc_zero_array ( tctx , struct winspool_PrintNamedProperty , 4 ) ;
torture_assert ( tctx , c , " out of memory " ) ;
c [ 0 ] . propertyName = " RemoteNotifyFilter Flags " ;
c [ 0 ] . propertyValue . PropertyType = winspool_PropertyTypeInt32 ;
c [ 0 ] . propertyValue . value . propertyInt32 = 0xff ;
c [ 1 ] . propertyName = " RemoteNotifyFilter Options " ;
c [ 1 ] . propertyValue . PropertyType = winspool_PropertyTypeInt32 ;
c [ 1 ] . propertyValue . value . propertyInt32 = 0 ;
c [ 2 ] . propertyName = " RemoteNotifyFilter Color " ;
c [ 2 ] . propertyValue . PropertyType = winspool_PropertyTypeInt32 ;
c [ 2 ] . propertyValue . value . propertyInt32 = 0 ;
c [ 3 ] . propertyName = " RemoteNotifyFilter NotifyOptions " ;
c [ 3 ] . propertyValue . PropertyType = winspool_PropertyTypeNotificationOptions ;
c [ 3 ] . propertyValue . value . propertyOptionsContainer . pOptions = options ;
NotifyFilter . numberOfProperties = 4 ;
NotifyFilter . propertiesCollection = c ;
r . in . hPrinter = * server_handle ;
r . in . pNotifyFilter = & NotifyFilter ;
r . out . phRpcHandle = notify_handle ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_SyncRegisterForRemoteNotifications_r ( b , tctx , & r ) ,
" SyncRegisterForRemoteNotifications failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" SyncRegisterForRemoteNotifications failed " ) ;
return true ;
}
static bool test_SyncRegisterForRemoteNotifications ( struct torture_context * tctx ,
void * private_data )
{
struct test_iremotewinspool_context * ctx =
talloc_get_type_abort ( private_data , struct test_iremotewinspool_context ) ;
struct policy_handle notify_handle ;
torture_assert ( tctx ,
test_SyncRegisterForRemoteNotifications_args ( tctx ,
ctx - > iremotewinspool_pipe ,
& ctx - > server_handle ,
& notify_handle ) ,
" failed to test SyncRegisterForRemoteNotifications " ) ;
2016-08-23 19:39:48 +03:00
test_SyncUnRegisterForRemoteNotifications_args ( tctx , ctx - > iremotewinspool_pipe , & notify_handle ) ;
2013-05-16 20:21:30 +04:00
return true ;
}
2016-08-23 23:58:26 +03:00
static bool test_AsyncUploadPrinterDriverPackage ( struct torture_context * tctx ,
void * private_data )
{
struct test_iremotewinspool_context * ctx =
talloc_get_type_abort ( private_data , struct test_iremotewinspool_context ) ;
struct dcerpc_pipe * p = ctx - > iremotewinspool_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct winspool_AsyncUploadPrinterDriverPackage r ;
uint32_t pcchDestInfPath = 0 ;
r . in . pszServer = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
r . in . pszInfPath = " " ;
r . in . pszEnvironment = " " ;
r . in . dwFlags = 0 ;
r . in . pszDestInfPath = NULL ;
r . in . pcchDestInfPath = & pcchDestInfPath ;
r . out . pszDestInfPath = NULL ;
r . out . pcchDestInfPath = & pcchDestInfPath ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncUploadPrinterDriverPackage_r ( b , tctx , & r ) ,
" AsyncUploadPrinterDriverPackage failed " ) ;
torture_assert_hresult_equal ( tctx , r . out . result , HRES_E_INVALIDARG ,
" AsyncUploadPrinterDriverPackage failed " ) ;
pcchDestInfPath = 260 ;
r . in . pszDestInfPath = talloc_zero_array ( tctx , uint16_t , pcchDestInfPath ) ;
r . out . pszDestInfPath = talloc_zero_array ( tctx , uint16_t , pcchDestInfPath ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncUploadPrinterDriverPackage_r ( b , tctx , & r ) ,
" AsyncUploadPrinterDriverPackage failed " ) ;
torture_assert_werr_equal ( tctx ,
W_ERROR ( WIN32_FROM_HRESULT ( r . out . result ) ) , WERR_INVALID_ENVIRONMENT ,
" AsyncUploadPrinterDriverPackage failed " ) ;
r . in . pszEnvironment = SPOOLSS_ARCHITECTURE_x64 ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncUploadPrinterDriverPackage_r ( b , tctx , & r ) ,
" AsyncUploadPrinterDriverPackage failed " ) ;
torture_assert_werr_equal ( tctx ,
W_ERROR ( WIN32_FROM_HRESULT ( r . out . result ) ) , WERR_FILE_NOT_FOUND ,
" AsyncUploadPrinterDriverPackage failed " ) ;
r . in . pszInfPath = " \\ \\ mthelena \\ print$ \\ x64 \\ {BD443844-ED00-4D96-8CAE-95E49492312A} \\ prnbrcl1.inf " ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncUploadPrinterDriverPackage_r ( b , tctx , & r ) ,
" AsyncUploadPrinterDriverPackage failed " ) ;
torture_assert_werr_equal ( tctx ,
W_ERROR ( WIN32_FROM_HRESULT ( r . out . result ) ) , WERR_FILE_NOT_FOUND ,
" AsyncUploadPrinterDriverPackage failed " ) ;
return true ;
}
2016-08-25 18:31:47 +03:00
static bool test_AsyncEnumPrinters ( struct torture_context * tctx ,
void * private_data )
{
struct test_iremotewinspool_context * ctx =
talloc_get_type_abort ( private_data , struct test_iremotewinspool_context ) ;
struct dcerpc_pipe * p = ctx - > iremotewinspool_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct winspool_AsyncEnumPrinters r ;
uint32_t levels [ ] = { 1 , 2 , /*3,*/ 4 , 5 } ;
int i ;
uint32_t needed ;
uint32_t returned ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
r . in . Flags = PRINTER_ENUM_LOCAL ;
r . in . pName = NULL ;
r . in . Level = levels [ i ] ;
r . in . cbBuf = 0 ;
r . in . pPrinterEnum = NULL ;
r . out . pcbNeeded = & needed ;
r . out . pcReturned = & returned ;
r . out . pPrinterEnum = NULL ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncEnumPrinters_r ( b , tctx , & r ) ,
" AsyncEnumPrinters failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , WERR_INSUFFICIENT_BUFFER ,
" AsyncEnumPrinters failed " ) ;
r . in . cbBuf = needed ;
r . in . pPrinterEnum = talloc_zero_array ( tctx , uint8_t , r . in . cbBuf ) ;
r . out . pPrinterEnum = r . in . pPrinterEnum ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncEnumPrinters_r ( b , tctx , & r ) ,
" AsyncEnumPrinters failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" AsyncEnumPrinters failed " ) ;
}
return true ;
}
2016-09-01 14:57:50 +03:00
static bool test_AsyncGetPrinterData ( struct torture_context * tctx ,
void * private_data )
{
struct test_iremotewinspool_context * ctx =
talloc_get_type_abort ( private_data , struct test_iremotewinspool_context ) ;
struct dcerpc_pipe * p = ctx - > iremotewinspool_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
DATA_BLOB blob ;
const char * s ;
bool ok ;
uint32_t pType ;
uint32_t pcbNeeded ;
uint8_t * pData ;
torture_assert ( tctx ,
test_AsyncGetPrinterData_args ( tctx , b , & ctx - > server_handle ,
" MajorVersion " ,
& pType , & pData , & pcbNeeded ) ,
" failed to check for MajorVersion " ) ;
torture_assert_int_equal ( tctx , pcbNeeded , 4 , " pcbNeeded " ) ;
torture_assert_int_equal ( tctx , pType , REG_DWORD , " pType " ) ;
torture_assert_int_equal ( tctx , IVAL ( pData , 0 ) , 3 , " pData " ) ;
torture_assert ( tctx ,
test_AsyncGetPrinterData_args ( tctx , b , & ctx - > server_handle ,
" Architecture " ,
& pType , & pData , & pcbNeeded ) ,
" failed to check for Architecture " ) ;
blob = data_blob_const ( pData , pcbNeeded ) ;
torture_assert_int_equal ( tctx , pType , REG_SZ , " pType " ) ;
torture_assert ( tctx , pull_reg_sz ( tctx , & blob , & s ) , " " ) ;
ok = strequal ( s , SPOOLSS_ARCHITECTURE_x64 ) | | strequal ( s , SPOOLSS_ARCHITECTURE_NT_X86 ) ;
torture_assert ( tctx , ok , " unexpected architecture returned " ) ;
return true ;
}
2016-10-28 23:49:21 +03:00
static bool test_AsyncCorePrinterDriverInstalled ( struct torture_context * tctx ,
void * private_data )
{
struct test_iremotewinspool_context * ctx =
talloc_get_type_abort ( private_data , struct test_iremotewinspool_context ) ;
struct dcerpc_pipe * p = ctx - > iremotewinspool_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct winspool_AsyncCorePrinterDriverInstalled r ;
int32_t pbDriverInstalled ;
struct GUID guid ;
r . in . pszServer = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
r . in . pszEnvironment = " " ;
r . in . CoreDriverGUID = GUID_zero ( ) ;
r . in . ftDriverDate = 0 ;
r . in . dwlDriverVersion = 0 ;
r . out . pbDriverInstalled = & pbDriverInstalled ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncCorePrinterDriverInstalled_r ( b , tctx , & r ) ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_werr_equal ( tctx ,
W_ERROR ( WIN32_FROM_HRESULT ( r . out . result ) ) , WERR_INVALID_ENVIRONMENT ,
" AsyncCorePrinterDriverInstalled failed " ) ;
r . in . pszEnvironment = SPOOLSS_ARCHITECTURE_x64 ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncCorePrinterDriverInstalled_r ( b , tctx , & r ) ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_int_equal ( tctx , * r . out . pbDriverInstalled , false ,
" unexpected driver installed " ) ;
r . in . CoreDriverGUID = GUID_random ( ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncCorePrinterDriverInstalled_r ( b , tctx , & r ) ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_int_equal ( tctx , * r . out . pbDriverInstalled , false ,
" unexpected driver installed " ) ;
torture_assert_ntstatus_ok ( tctx ,
GUID_from_string ( SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV , & guid ) , " " ) ;
r . in . CoreDriverGUID = guid ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncCorePrinterDriverInstalled_r ( b , tctx , & r ) ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_int_equal ( tctx , * r . out . pbDriverInstalled , true ,
" xps core driver not installed? " ) ;
r . in . dwlDriverVersion = 0xffffffff ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncCorePrinterDriverInstalled_r ( b , tctx , & r ) ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_int_equal ( tctx , * r . out . pbDriverInstalled , true ,
" xps core driver not installed? " ) ;
r . in . dwlDriverVersion = 1234 ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncCorePrinterDriverInstalled_r ( b , tctx , & r ) ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_int_equal ( tctx , * r . out . pbDriverInstalled , true ,
" xps core driver not installed? " ) ;
r . in . ftDriverDate = unix_timespec_to_nt_time ( timespec_current ( ) ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncCorePrinterDriverInstalled_r ( b , tctx , & r ) ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_int_equal ( tctx , * r . out . pbDriverInstalled , false ,
" driver too old ? " ) ;
r . in . dwlDriverVersion = 0 ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncCorePrinterDriverInstalled_r ( b , tctx , & r ) ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" AsyncCorePrinterDriverInstalled failed " ) ;
torture_assert_int_equal ( tctx , * r . out . pbDriverInstalled , false ,
" unexpected driver installed " ) ;
return true ;
}
2016-11-02 14:30:58 +03:00
static bool test_get_core_printer_drivers_arch_guid ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
const char * architecture ,
const char * guid_str ,
const char * * package_id )
{
struct winspool_AsyncGetCorePrinterDrivers r ;
DATA_BLOB blob ;
const char * * s ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
s = talloc_zero_array ( tctx , const char * , 2 ) ;
s [ 0 ] = guid_str ;
torture_assert ( tctx ,
push_reg_multi_sz ( tctx , & blob , s ) ,
" push_reg_multi_sz failed " ) ;
r . in . pszServer = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
r . in . pszEnvironment = architecture ;
r . in . cchCoreDrivers = blob . length / 2 ;
r . in . pszzCoreDriverDependencies = ( uint16_t * ) blob . data ;
r . in . cCorePrinterDrivers = 1 ;
r . out . pCorePrinterDrivers = talloc_zero_array ( tctx , struct spoolss_CorePrinterDriver , r . in . cCorePrinterDrivers ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncGetCorePrinterDrivers_r ( b , tctx , & r ) ,
" winspool_AsyncCorePrinterDrivers failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" winspool_AsyncCorePrinterDrivers failed " ) ;
if ( package_id ) {
* package_id = r . out . pCorePrinterDrivers [ 0 ] . szPackageID ;
}
return true ;
}
static bool test_AsyncDeletePrintDriverPackage ( struct torture_context * tctx ,
void * private_data )
{
struct test_iremotewinspool_context * ctx =
talloc_get_type_abort ( private_data , struct test_iremotewinspool_context ) ;
struct dcerpc_pipe * p = ctx - > iremotewinspool_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct winspool_AsyncDeletePrinterDriverPackage r ;
const char * architectures [ ] = {
/* SPOOLSS_ARCHITECTURE_NT_X86, */
SPOOLSS_ARCHITECTURE_x64
} ;
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( architectures ) ; i + + ) {
const char * package_id ;
torture_assert ( tctx ,
test_get_core_printer_drivers_arch_guid ( tctx , p ,
architectures [ i ] ,
SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV ,
& package_id ) ,
" failed to get core printer driver " ) ;
r . in . pszServer = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
r . in . pszEnvironment = " " ;
r . in . pszInfPath = " " ;
torture_comment ( tctx , " Testing AsyncDeletePrinterDriverPackage(%s, %s, %s) \n " ,
r . in . pszServer , architectures [ i ] , package_id ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncDeletePrinterDriverPackage_r ( b , tctx , & r ) ,
" AsyncDeletePrinterDriverPackage failed " ) ;
torture_assert_werr_equal ( tctx ,
W_ERROR ( WIN32_FROM_HRESULT ( r . out . result ) ) , WERR_NOT_FOUND ,
" AsyncDeletePrinterDriverPackage failed " ) ;
r . in . pszInfPath = package_id ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncDeletePrinterDriverPackage_r ( b , tctx , & r ) ,
" AsyncDeletePrinterDriverPackage failed " ) ;
torture_assert_werr_equal ( tctx ,
W_ERROR ( WIN32_FROM_HRESULT ( r . out . result ) ) , WERR_INVALID_ENVIRONMENT ,
" AsyncDeletePrinterDriverPackage failed " ) ;
r . in . pszEnvironment = architectures [ i ] ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncDeletePrinterDriverPackage_r ( b , tctx , & r ) ,
" AsyncDeletePrinterDriverPackage failed " ) ;
torture_assert_hresult_equal ( tctx , r . out . result , HRES_E_ACCESSDENIED ,
" AsyncDeletePrinterDriverPackage failed " ) ;
}
return true ;
}
2016-11-08 13:32:20 +03:00
static bool test_AsyncGetPrinterDriverDirectory ( struct torture_context * tctx ,
void * private_data )
{
struct test_iremotewinspool_context * ctx =
talloc_get_type_abort ( private_data , struct test_iremotewinspool_context ) ;
struct dcerpc_pipe * p = ctx - > iremotewinspool_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct winspool_AsyncGetPrinterDriverDirectory r ;
uint32_t pcbNeeded ;
DATA_BLOB blob ;
const char * s ;
r . in . pName = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
r . in . pEnvironment = ctx - > environment ;
r . in . Level = 1 ;
r . in . cbBuf = 0x200 ;
r . in . pDriverDirectory = talloc_zero_array ( tctx , uint8_t , r . in . cbBuf ) ;
r . out . pcbNeeded = & pcbNeeded ;
r . out . pDriverDirectory = r . in . pDriverDirectory ;
torture_comment ( tctx , " Testing AsyncGetPrinterDriverDirectory(%s, %s) \n " ,
r . in . pName , r . in . pEnvironment ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_winspool_AsyncGetPrinterDriverDirectory_r ( b , tctx , & r ) ,
" AsyncGetPrinterDriverDirectory failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" AsyncGetPrinterDriverDirectory failed " ) ;
blob = data_blob_const ( r . out . pDriverDirectory , pcbNeeded ) ;
torture_assert ( tctx ,
pull_reg_sz ( tctx , & blob , & s ) ,
" failed to pull reg_sz " ) ;
torture_comment ( tctx , " got: %s \n " , s ) ;
return true ;
}
2016-09-05 23:49:39 +03:00
/*
* Test if one can close a printserver handle that has been acquired via
* winspool_AsyncOpenPrinter with a spoolss_ClosePrinter operation .
*/
static bool test_OpenPrinter ( struct torture_context * tctx ,
void * private_data )
{
struct test_iremotewinspool_context * ctx =
talloc_get_type_abort ( private_data , struct test_iremotewinspool_context ) ;
struct dcerpc_pipe * p = ctx - > iremotewinspool_pipe ;
const char * printer_name ;
struct policy_handle handle ;
struct dcerpc_pipe * s ;
struct dcerpc_binding * binding ;
2018-08-15 18:10:21 +03:00
struct spoolss_UserLevel1 client_info ;
2016-09-05 23:49:39 +03:00
struct spoolss_ClosePrinter r ;
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_binding ( tctx , & binding ) ,
" failed to get binding " ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_binding_set_transport ( binding , NCACN_NP ) ,
" failed to set ncacn_np transport " ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_binding_set_object ( binding , GUID_zero ( ) ) ,
" failed to set object uuid to zero " ) ;
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection_with_binding ( tctx , binding , & s , & ndr_table_spoolss ) ,
" failed to connect to spoolss " ) ;
printer_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2018-08-15 18:10:21 +03:00
client_info = test_get_client_info ( tctx , WIN_2000 , 3 , SPOOLSS_MINOR_VERSION_0 ) ;
2016-09-05 23:49:39 +03:00
torture_assert ( tctx ,
2018-08-15 18:10:21 +03:00
test_AsyncOpenPrinter_byprinter ( tctx , ctx , p , printer_name , client_info , & handle ) ,
2016-09-05 23:49:39 +03:00
" failed to open printserver via winspool " ) ;
r . in . handle = & handle ;
r . out . handle = & handle ;
torture_assert_ntstatus_equal ( tctx ,
dcerpc_spoolss_ClosePrinter_r ( s - > binding_handle , tctx , & r ) ,
NT_STATUS_RPC_SS_CONTEXT_MISMATCH ,
" ClosePrinter failed " ) ;
talloc_free ( s ) ;
return true ;
}
2013-01-15 18:23:58 +04:00
struct torture_suite * torture_rpc_iremotewinspool ( TALLOC_CTX * mem_ctx )
{
struct torture_suite * suite = torture_suite_create ( mem_ctx , " iremotewinspool " ) ;
struct torture_tcase * tcase = torture_suite_add_tcase ( suite , " printserver " ) ;
torture_tcase_set_fixture ( tcase ,
torture_rpc_iremotewinspool_setup ,
torture_rpc_iremotewinspool_teardown ) ;
torture_tcase_add_simple_test ( tcase , " AsyncOpenPrinter " , test_AsyncOpenPrinter ) ;
2013-05-16 20:21:30 +04:00
torture_tcase_add_simple_test ( tcase , " SyncRegisterForRemoteNotifications " , test_SyncRegisterForRemoteNotifications ) ;
2016-08-23 19:39:48 +03:00
torture_tcase_add_simple_test ( tcase , " SyncUnRegisterForRemoteNotifications " , test_SyncUnRegisterForRemoteNotifications ) ;
2013-01-15 18:23:58 +04:00
torture_tcase_add_simple_test ( tcase , " AsyncClosePrinter " , test_AsyncClosePrinter ) ;
2016-08-23 23:58:26 +03:00
torture_tcase_add_simple_test ( tcase , " AsyncUploadPrinterDriverPackage " , test_AsyncUploadPrinterDriverPackage ) ;
2016-08-25 18:31:47 +03:00
torture_tcase_add_simple_test ( tcase , " AsyncEnumPrinters " , test_AsyncEnumPrinters ) ;
2016-09-01 14:57:50 +03:00
torture_tcase_add_simple_test ( tcase , " AsyncGetPrinterData " , test_AsyncGetPrinterData ) ;
2016-10-28 23:49:21 +03:00
torture_tcase_add_simple_test ( tcase , " AsyncCorePrinterDriverInstalled " , test_AsyncCorePrinterDriverInstalled ) ;
2016-11-02 14:30:58 +03:00
torture_tcase_add_simple_test ( tcase , " AsyncDeletePrintDriverPackage " , test_AsyncDeletePrintDriverPackage ) ;
2016-11-08 13:32:20 +03:00
torture_tcase_add_simple_test ( tcase , " AsyncGetPrinterDriverDirectory " , test_AsyncGetPrinterDriverDirectory ) ;
2013-01-15 18:23:58 +04:00
2016-09-05 23:49:39 +03:00
tcase = torture_suite_add_tcase ( suite , " handles " ) ;
torture_tcase_set_fixture ( tcase ,
torture_rpc_iremotewinspool_setup ,
torture_rpc_iremotewinspool_teardown ) ;
torture_tcase_add_simple_test ( tcase , " OpenPrinter " , test_OpenPrinter ) ;
2013-01-15 18:23:58 +04:00
return suite ;
}