2009-06-30 13:38:41 +04:00
/*
2003-11-15 08:42:49 +03:00
Unix SMB / CIFS implementation .
test suite for spoolss rpc operations
Copyright ( C ) Tim Potter 2003
2005-04-02 10:51:54 +04:00
Copyright ( C ) Stefan Metzmacher 2005
2007-09-03 17:13:25 +04:00
Copyright ( C ) Jelmer Vernooij 2007
2013-01-23 13:33:21 +04:00
Copyright ( C ) Guenther Deschner 2009 - 2011 , 2013
2009-06-30 13:38:41 +04:00
2003-11-15 08:42:49 +03: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
2003-11-15 08:42:49 +03:00
( at your option ) any later version .
2009-06-30 13:38:41 +04:00
2003-11-15 08:42:49 +03: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 .
2009-06-30 13:38:41 +04:00
2003-11-15 08:42:49 +03: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/>.
2003-11-15 08:42:49 +03:00
*/
# include "includes.h"
2006-01-03 16:41:17 +03:00
# include "torture/torture.h"
2009-11-20 18:33:29 +03:00
# include "librpc/gen_ndr/ndr_misc.h"
2009-12-12 03:51:13 +03:00
# include "librpc/gen_ndr/ndr_spoolss.h"
2006-03-15 02:35:30 +03:00
# include "librpc/gen_ndr/ndr_spoolss_c.h"
2010-03-05 16:42:10 +03:00
# include "librpc/gen_ndr/ndr_winreg_c.h"
2010-02-13 04:11:31 +03:00
# include "librpc/gen_ndr/ndr_security.h"
# include "libcli/security/security.h"
2010-04-14 00:06:51 +04:00
# include "torture/rpc/torture_rpc.h"
2009-11-20 18:33:29 +03:00
# include "param/param.h"
2010-03-01 16:35:59 +03:00
# include "lib/registry/registry.h"
2010-04-22 20:47:27 +04:00
# include "libcli/libcli.h"
# include "libcli/raw/raw_proto.h"
# include "libcli/resolve/resolve.h"
2012-06-21 19:12:23 +04:00
# include "libcli/smb2/smb2.h"
# include "libcli/smb2/smb2_calls.h"
2010-04-22 20:47:27 +04:00
# include "lib/cmdline/popt_common.h"
# include "system/filesys.h"
2010-06-30 01:35:45 +04:00
# include "torture/ndr/ndr.h"
2012-06-21 19:12:23 +04:00
# include "torture/smb2/proto.h"
2003-11-15 08:42:49 +03:00
2009-07-03 11:56:28 +04:00
# define TORTURE_WELLKNOWN_PRINTER "torture_wkn_printer"
# define TORTURE_PRINTER "torture_printer"
# define TORTURE_WELLKNOWN_PRINTER_EX "torture_wkn_printer_ex"
# define TORTURE_PRINTER_EX "torture_printer_ex"
2009-07-02 23:49:15 +04:00
# define TORTURE_DRIVER "torture_driver"
2017-08-08 12:25:48 +03:00
# define TORTURE_DRIVER_ADD "torture_driver_add"
2009-07-02 23:49:15 +04:00
# define TORTURE_DRIVER_EX "torture_driver_ex"
2010-11-29 17:09:52 +03:00
# define TORTURE_DRIVER_ADOBE "torture_driver_adobe"
# define TORTURE_DRIVER_EX_ADOBE "torture_driver_ex_adobe"
2010-11-29 19:50:05 +03:00
# define TORTURE_DRIVER_ADOBE_CUPSADDSMB "torture_driver_adobe_cupsaddsmb"
2010-12-24 01:50:23 +03:00
# define TORTURE_DRIVER_TIMESTAMPS "torture_driver_timestamps"
2012-01-16 19:30:17 +04:00
# define TORTURE_DRIVER_DELETER "torture_driver_deleter"
2016-11-15 20:34:22 +03:00
# define TORTURE_DRIVER_COPY_DIR "torture_driver_copy_from_directory"
2012-01-17 20:07:01 +04:00
# define TORTURE_DRIVER_DELETERIN "torture_driver_deleterin"
2012-06-22 20:49:50 +04:00
# define TORTURE_PRINTER_STATIC1 "print1"
2009-07-03 11:56:28 +04:00
2010-04-06 15:23:22 +04:00
# define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
# define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
# define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
# define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
2010-04-08 17:00:34 +04:00
# define TOP_LEVEL_CONTROL_PRINTERS_KEY TOP_LEVEL_CONTROL_KEY "\\Printers"
2010-04-20 21:50:37 +04:00
# define TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY TOP_LEVEL_CONTROL_KEY "\\Environments"
2010-03-13 00:45:33 +03:00
2005-04-02 10:51:54 +04:00
struct test_spoolss_context {
2010-05-19 01:40:43 +04:00
struct dcerpc_pipe * spoolss_pipe ;
/* server environment */
const char * environment ;
2005-04-04 19:19:27 +04:00
/* print server handle */
struct policy_handle server_handle ;
2005-04-02 10:51:54 +04:00
/* for EnumPorts */
uint32_t port_count [ 3 ] ;
2005-05-31 02:44:17 +04:00
union spoolss_PortInfo * ports [ 3 ] ;
2005-04-02 10:51:54 +04:00
/* for EnumPrinterDrivers */
2014-02-28 19:50:21 +04:00
uint32_t driver_count [ 9 ] ;
union spoolss_DriverInfo * drivers [ 9 ] ;
2005-04-02 10:51:54 +04:00
/* for EnumMonitors */
uint32_t monitor_count [ 3 ] ;
2005-05-31 02:44:17 +04:00
union spoolss_MonitorInfo * monitors [ 3 ] ;
2005-04-02 10:51:54 +04:00
/* for EnumPrintProcessors */
uint32_t print_processor_count [ 2 ] ;
2005-05-31 02:44:17 +04:00
union spoolss_PrintProcessorInfo * print_processors [ 2 ] ;
2005-04-02 10:51:54 +04:00
/* for EnumPrinters */
uint32_t printer_count [ 6 ] ;
2005-05-31 02:44:17 +04:00
union spoolss_PrinterInfo * printers [ 6 ] ;
2005-04-02 10:51:54 +04:00
} ;
2009-07-02 23:49:15 +04:00
struct torture_driver_context {
struct {
const char * driver_directory ;
const char * environment ;
} local ;
struct {
const char * driver_directory ;
2016-11-15 20:34:22 +03:00
const char * driver_upload_directory ;
2009-07-02 23:49:15 +04:00
const char * environment ;
} remote ;
struct spoolss_AddDriverInfo8 info8 ;
2010-04-23 03:58:02 +04:00
bool ex ;
2009-07-02 23:49:15 +04:00
} ;
2010-04-27 13:30:35 +04:00
struct torture_printer_context {
2010-06-03 23:39:51 +04:00
struct dcerpc_pipe * spoolss_pipe ;
2010-04-27 13:30:35 +04:00
struct spoolss_SetPrinterInfo2 info2 ;
struct torture_driver_context driver ;
bool ex ;
bool wellknown ;
bool added_driver ;
bool have_driver ;
2010-04-28 19:00:53 +04:00
struct spoolss_DeviceMode * devmode ;
2010-06-03 23:39:51 +04:00
struct policy_handle handle ;
2010-04-27 13:30:35 +04:00
} ;
static bool upload_printer_driver ( struct torture_context * tctx ,
const char * server_name ,
struct torture_driver_context * d ) ;
static bool remove_printer_driver ( struct torture_context * tctx ,
const char * server_name ,
struct torture_driver_context * d ) ;
static bool fillup_printserver_info ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct torture_driver_context * d ) ;
static bool test_AddPrinterDriver_args_level_3 ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server_name ,
struct spoolss_AddDriverInfo8 * r ,
uint32_t flags ,
2010-12-15 19:44:56 +03:00
bool ex ,
const char * remote_driver_dir ) ;
2010-04-27 13:30:35 +04:00
2007-09-03 17:13:25 +04:00
# define COMPARE_STRING(tctx, c,r,e) \
torture_assert_str_equal ( tctx , c . e , r . e , " invalid value " )
2005-04-02 10:51:54 +04:00
2007-07-03 20:27:35 +04:00
/* not every compiler supports __typeof__() */
# if (__GNUC__ >= 3)
2006-08-24 14:38:06 +04:00
# define _CHECK_FIELD_SIZE(c,r,e,type) do {\
if ( sizeof ( __typeof__ ( c . e ) ) ! = sizeof ( type ) ) { \
2007-09-03 17:13:25 +04:00
torture_fail ( tctx , # c " . " # e " field is not " # type " \n " ) ; \
2006-08-24 14:38:06 +04:00
} \
if ( sizeof ( __typeof__ ( r . e ) ) ! = sizeof ( type ) ) { \
2007-09-03 17:13:25 +04:00
torture_fail ( tctx , # r " . " # e " field is not " # type " \n " ) ; \
2006-08-24 14:38:06 +04:00
} \
} while ( 0 )
2007-07-03 20:27:35 +04:00
# else
# define _CHECK_FIELD_SIZE(c,r,e,type) do {} while(0)
# endif
2006-08-24 14:38:06 +04:00
2007-09-03 17:13:25 +04:00
# define COMPARE_UINT32(tctx, c, r, e) do {\
2007-10-01 22:52:55 +04:00
_CHECK_FIELD_SIZE ( c , r , e , uint32_t ) ; \
2007-09-03 17:13:25 +04:00
torture_assert_int_equal ( tctx , c . e , r . e , " invalid value " ) ; \
2005-04-02 10:51:54 +04:00
} while ( 0 )
2009-12-07 21:26:45 +03:00
# define COMPARE_UINT64(tctx, c, r, e) do {\
_CHECK_FIELD_SIZE ( c , r , e , uint64_t ) ; \
torture_assert_int_equal ( tctx , c . e , r . e , " invalid value " ) ; \
} while ( 0 )
# define COMPARE_NTTIME(tctx, c, r, e) do {\
_CHECK_FIELD_SIZE ( c , r , e , NTTIME ) ; \
torture_assert_int_equal ( tctx , c . e , r . e , " invalid value " ) ; \
} while ( 0 )
2009-12-08 12:21:28 +03:00
# define COMPARE_STRING_ARRAY(tctx, c,r,e) do {\
int __i ; \
if ( ! c . e & & ! r . e ) { \
break ; \
} \
if ( c . e & & ! r . e ) { \
torture_fail ( tctx , # r " . " # e " field is NULL and " # c " . " # e " is not \n " ) ; \
} \
if ( ! c . e & & r . e ) { \
torture_fail ( tctx , # c " . " # e " field is NULL and " # r " . " # e " is not \n " ) ; \
} \
for ( __i = 0 ; c . e [ __i ] ! = NULL ; __i + + ) { \
torture_assert_str_equal ( tctx , c . e [ __i ] , r . e [ __i ] , " invalid value " ) ; \
} \
} while ( 0 )
2005-04-02 10:51:54 +04:00
2009-12-12 03:51:13 +03:00
# define CHECK_ALIGN(size, n) do {\
if ( size % n ) { \
torture_warning ( tctx , " %d is *NOT* %d byte aligned, should be %d " , \
size , n , size + n - ( size % n ) ) ; \
} \
} while ( 0 )
# define DO_ROUND(size, n) (((size)+((n)-1)) & ~((n)-1))
2010-05-09 19:20:01 +04:00
# define CHECK_NEEDED_SIZE_ENUM_LEVEL(fn, info, level, count, needed, align) do { \
2010-02-19 16:25:19 +03:00
if ( torture_setting_bool ( tctx , " spoolss_check_size " , false ) ) { \
2010-05-09 19:20:01 +04:00
uint32_t size = ndr_size_ # # fn # # _info ( tctx , level , count , info ) ; \
2009-12-12 03:51:13 +03:00
uint32_t round_size = DO_ROUND ( size , align ) ; \
if ( round_size ! = needed ) { \
torture_warning ( tctx , __location__ " : " # fn " level %d (count: %d) got unexpected needed size: %d, we calculated: %d " , level , count , needed , round_size ) ; \
CHECK_ALIGN ( size , align ) ; \
} \
2010-02-19 16:25:19 +03:00
} \
2009-12-12 03:51:13 +03:00
} while ( 0 )
2010-05-09 19:20:01 +04:00
# define CHECK_NEEDED_SIZE_ENUM(fn, info, count, needed, align) do { \
2010-02-19 16:25:19 +03:00
if ( torture_setting_bool ( tctx , " spoolss_check_size " , false ) ) { \
2010-05-09 19:20:01 +04:00
uint32_t size = ndr_size_ # # fn # # _info ( tctx , count , info ) ; \
2009-12-12 03:51:13 +03:00
uint32_t round_size = DO_ROUND ( size , align ) ; \
if ( round_size ! = needed ) { \
torture_warning ( tctx , __location__ " : " # fn " (count: %d) got unexpected needed size: %d, we calculated: %d " , count , needed , round_size ) ; \
CHECK_ALIGN ( size , align ) ; \
} \
2010-02-19 16:25:19 +03:00
} \
2009-12-12 03:51:13 +03:00
} while ( 0 )
2010-05-09 19:20:01 +04:00
# define CHECK_NEEDED_SIZE_LEVEL(fn, info, level, needed, align) do { \
2010-02-19 16:25:19 +03:00
if ( torture_setting_bool ( tctx , " spoolss_check_size " , false ) ) { \
2010-05-09 19:20:01 +04:00
uint32_t size = ndr_size_ # # fn ( info , level , 0 ) ; \
2009-12-12 03:51:13 +03:00
uint32_t round_size = DO_ROUND ( size , align ) ; \
if ( round_size ! = needed ) { \
torture_warning ( tctx , __location__ " : " # fn " level %d got unexpected needed size: %d, we calculated: %d " , level , needed , round_size ) ; \
CHECK_ALIGN ( size , align ) ; \
} \
2010-02-19 16:25:19 +03:00
} \
2009-12-12 03:51:13 +03:00
} while ( 0 )
2010-03-15 14:38:17 +03:00
static bool PrinterInfo_to_SetPrinterInfo ( struct torture_context * tctx ,
const union spoolss_PrinterInfo * i ,
uint32_t level ,
union spoolss_SetPrinterInfo * s )
{
switch ( level ) {
case 0 :
s - > info0 = talloc ( tctx , struct spoolss_SetPrinterInfo0 ) ;
break ;
case 2 :
s - > info2 = talloc ( tctx , struct spoolss_SetPrinterInfo2 ) ;
s - > info2 - > servername = i - > info2 . servername ;
s - > info2 - > printername = i - > info2 . printername ;
s - > info2 - > sharename = i - > info2 . sharename ;
s - > info2 - > portname = i - > info2 . portname ;
s - > info2 - > drivername = i - > info2 . drivername ;
s - > info2 - > comment = i - > info2 . comment ;
s - > info2 - > location = i - > info2 . location ;
2016-11-11 18:29:20 +03:00
s - > info2 - > devmode_ptr = 0 ;
2010-03-15 14:38:17 +03:00
s - > info2 - > sepfile = i - > info2 . sepfile ;
s - > info2 - > printprocessor = i - > info2 . printprocessor ;
s - > info2 - > datatype = i - > info2 . datatype ;
s - > info2 - > parameters = i - > info2 . parameters ;
2016-11-11 18:29:20 +03:00
s - > info2 - > secdesc_ptr = 0 ;
2010-03-15 14:38:17 +03:00
s - > info2 - > attributes = i - > info2 . attributes ;
s - > info2 - > priority = i - > info2 . priority ;
s - > info2 - > defaultpriority = i - > info2 . defaultpriority ;
s - > info2 - > starttime = i - > info2 . starttime ;
s - > info2 - > untiltime = i - > info2 . untiltime ;
s - > info2 - > status = i - > info2 . status ;
s - > info2 - > cjobs = i - > info2 . cjobs ;
s - > info2 - > averageppm = i - > info2 . averageppm ;
break ;
case 3 :
case 4 :
case 5 :
case 6 :
case 7 :
case 8 :
case 9 :
default :
return false ;
}
return true ;
}
2009-07-14 16:33:08 +04:00
static bool test_OpenPrinter_server ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * server_handle )
2005-04-04 19:19:27 +04:00
{
NTSTATUS status ;
struct spoolss_OpenPrinter op ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2005-04-04 19:19:27 +04:00
2009-07-14 16:33:08 +04:00
op . in . printername = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2005-04-04 19:19:27 +04:00
op . in . datatype = NULL ;
op . in . devmode_ctr . devmode = NULL ;
2016-09-10 12:07:06 +03:00
op . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
2009-07-14 16:33:08 +04:00
op . out . handle = server_handle ;
2005-04-04 19:19:27 +04:00
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing OpenPrinter(%s) \n " , op . in . printername ) ;
2005-04-04 19:19:27 +04:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_OpenPrinter_r ( b , tctx , & op ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_OpenPrinter failed " ) ;
2009-06-30 13:38:41 +04:00
torture_assert_werr_ok ( tctx , op . out . result , " dcerpc_spoolss_OpenPrinter failed " ) ;
2005-04-04 19:19:27 +04:00
2007-09-03 17:13:25 +04:00
return true ;
2005-04-04 19:19:27 +04:00
}
2009-06-30 13:38:41 +04:00
static bool test_EnumPorts ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2005-04-02 10:51:54 +04:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
2005-04-02 10:51:54 +04:00
NTSTATUS status ;
struct spoolss_EnumPorts r ;
uint16_t levels [ ] = { 1 , 2 } ;
int i , j ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
DATA_BLOB blob ;
2009-02-06 19:09:30 +03:00
uint32_t needed ;
2009-02-16 18:42:21 +03:00
uint32_t count ;
2009-03-02 19:32:24 +03:00
union spoolss_PortInfo * info ;
2005-04-02 10:51:54 +04:00
r . in . servername = " " ;
r . in . level = level ;
r . in . buffer = NULL ;
2005-06-14 19:52:31 +04:00
r . in . offered = 0 ;
2009-02-06 19:09:30 +03:00
r . out . needed = & needed ;
2009-02-16 18:42:21 +03:00
r . out . count = & count ;
2009-03-02 19:32:24 +03:00
r . out . info = & info ;
2005-04-02 10:51:54 +04:00
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing EnumPorts level %u \n " , r . in . level ) ;
2005-04-02 10:51:54 +04:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EnumPorts_r ( b , ctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_EnumPorts failed " ) ;
2005-06-07 18:31:45 +04:00
if ( W_ERROR_IS_OK ( r . out . result ) ) {
/* TODO: do some more checks here */
continue ;
}
2009-06-30 13:38:41 +04:00
torture_assert_werr_equal ( tctx , r . out . result , WERR_INSUFFICIENT_BUFFER ,
2007-09-03 17:13:25 +04:00
" EnumPorts unexpected return code " ) ;
2005-04-02 10:51:54 +04:00
2010-04-08 13:56:27 +04:00
blob = data_blob_talloc_zero ( ctx , needed ) ;
2005-04-02 10:51:54 +04:00
r . in . buffer = & blob ;
2009-02-06 19:09:30 +03:00
r . in . offered = needed ;
2005-04-02 10:51:54 +04:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EnumPorts_r ( b , ctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_EnumPorts failed " ) ;
2005-04-02 10:51:54 +04:00
2007-09-03 17:13:25 +04:00
torture_assert_werr_ok ( tctx , r . out . result , " EnumPorts failed " ) ;
2005-04-02 10:51:54 +04:00
2009-03-06 14:24:23 +03:00
torture_assert ( tctx , info , " EnumPorts returned no info " ) ;
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_ENUM_LEVEL ( spoolss_EnumPorts , info , r . in . level , count , needed , 4 ) ;
2009-12-12 03:51:13 +03:00
2009-02-16 18:42:21 +03:00
ctx - > port_count [ level ] = count ;
2009-03-02 19:32:24 +03:00
ctx - > ports [ level ] = info ;
2005-04-02 10:51:54 +04:00
}
for ( i = 1 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
int old_level = levels [ i - 1 ] ;
2009-06-30 13:38:41 +04:00
torture_assert_int_equal ( tctx , ctx - > port_count [ level ] , ctx - > port_count [ old_level ] ,
2007-09-03 17:13:25 +04:00
" EnumPorts invalid value " ) ;
2005-04-02 10:51:54 +04:00
}
/* if the array sizes are not the same we would maybe segfault in the following code */
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
for ( j = 0 ; j < ctx - > port_count [ level ] ; j + + ) {
2005-05-31 02:44:17 +04:00
union spoolss_PortInfo * cur = & ctx - > ports [ level ] [ j ] ;
union spoolss_PortInfo * ref = & ctx - > ports [ 2 ] [ j ] ;
2005-04-02 10:51:54 +04:00
switch ( level ) {
case 1 :
2007-09-03 17:13:25 +04:00
COMPARE_STRING ( tctx , cur - > info1 , ref - > info2 , port_name ) ;
2005-04-02 10:51:54 +04:00
break ;
case 2 :
/* level 2 is our reference, and it makes no sense to compare it to itself */
break ;
}
}
}
2007-09-03 17:13:25 +04:00
return true ;
2005-04-02 10:51:54 +04:00
}
2009-02-25 18:17:44 +03:00
static bool test_GetPrintProcessorDirectory ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2009-02-25 18:17:44 +03:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
2009-02-25 18:17:44 +03:00
NTSTATUS status ;
2010-05-19 01:40:43 +04:00
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-02-25 18:17:44 +03:00
struct spoolss_GetPrintProcessorDirectory r ;
struct {
uint16_t level ;
const char * server ;
} levels [ ] = { {
. level = 1 ,
. server = NULL
} , {
. level = 1 ,
. server = " "
} , {
. level = 78 ,
. server = " "
} , {
. level = 1 ,
2010-04-07 02:38:02 +04:00
. server = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) )
2009-02-25 18:17:44 +03:00
} , {
. level = 1024 ,
2010-04-07 02:38:02 +04:00
. server = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) )
2009-02-25 18:17:44 +03:00
}
} ;
int i ;
uint32_t needed ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] . level ;
DATA_BLOB blob ;
r . in . server = levels [ i ] . server ;
2010-05-19 01:40:43 +04:00
r . in . environment = ctx - > environment ;
2009-02-25 18:17:44 +03:00
r . in . level = level ;
r . in . buffer = NULL ;
r . in . offered = 0 ;
r . out . needed = & needed ;
torture_comment ( tctx , " Testing GetPrintProcessorDirectory level %u \n " , r . in . level ) ;
2010-04-07 02:38:02 +04:00
status = dcerpc_spoolss_GetPrintProcessorDirectory_r ( b , tctx , & r ) ;
2009-02-25 18:17:44 +03:00
torture_assert_ntstatus_ok ( tctx , status ,
" dcerpc_spoolss_GetPrintProcessorDirectory failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , WERR_INSUFFICIENT_BUFFER ,
" GetPrintProcessorDirectory unexpected return code " ) ;
2010-04-08 13:56:27 +04:00
blob = data_blob_talloc_zero ( tctx , needed ) ;
2009-02-25 18:17:44 +03:00
r . in . buffer = & blob ;
r . in . offered = needed ;
2010-04-07 02:38:02 +04:00
status = dcerpc_spoolss_GetPrintProcessorDirectory_r ( b , tctx , & r ) ;
2009-02-25 18:17:44 +03:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_GetPrintProcessorDirectory failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " GetPrintProcessorDirectory failed " ) ;
2009-12-12 03:51:13 +03:00
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_LEVEL ( spoolss_PrintProcessorDirectoryInfo , r . out . info , r . in . level , needed , 2 ) ;
2009-02-25 18:17:44 +03:00
}
return true ;
}
2009-06-30 13:38:41 +04:00
static bool test_GetPrinterDriverDirectory ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2005-06-14 22:44:22 +04:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
2005-06-14 22:44:22 +04:00
NTSTATUS status ;
2010-05-19 01:40:43 +04:00
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2005-06-14 22:44:22 +04:00
struct spoolss_GetPrinterDriverDirectory r ;
struct {
uint16_t level ;
const char * server ;
} levels [ ] = { {
2005-06-16 20:46:42 +04:00
. level = 1 ,
. server = NULL
} , {
2005-06-14 22:44:22 +04:00
. level = 1 ,
. server = " "
} , {
. level = 78 ,
. server = " "
} , {
. level = 1 ,
2010-04-07 02:38:02 +04:00
. server = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) )
2005-06-14 22:44:22 +04:00
} , {
. level = 1024 ,
2010-04-07 02:38:02 +04:00
. server = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) )
2005-06-14 22:44:22 +04:00
}
} ;
int i ;
2009-02-06 14:32:57 +03:00
uint32_t needed ;
2005-06-14 22:44:22 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] . level ;
DATA_BLOB blob ;
r . in . server = levels [ i ] . server ;
2010-05-19 01:40:43 +04:00
r . in . environment = ctx - > environment ;
2005-06-14 22:44:22 +04:00
r . in . level = level ;
r . in . buffer = NULL ;
r . in . offered = 0 ;
2009-02-06 14:32:57 +03:00
r . out . needed = & needed ;
2005-06-14 22:44:22 +04:00
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing GetPrinterDriverDirectory level %u \n " , r . in . level ) ;
2005-06-14 22:44:22 +04:00
2010-04-07 02:38:02 +04:00
status = dcerpc_spoolss_GetPrinterDriverDirectory_r ( b , tctx , & r ) ;
2009-06-30 13:38:41 +04:00
torture_assert_ntstatus_ok ( tctx , status ,
2007-09-03 17:13:25 +04:00
" dcerpc_spoolss_GetPrinterDriverDirectory failed " ) ;
2009-06-30 13:38:41 +04:00
torture_assert_werr_equal ( tctx , r . out . result , WERR_INSUFFICIENT_BUFFER ,
2007-09-03 17:13:25 +04:00
" GetPrinterDriverDirectory unexpected return code " ) ;
2005-06-14 22:44:22 +04:00
2010-04-08 13:56:27 +04:00
blob = data_blob_talloc_zero ( tctx , needed ) ;
2005-06-14 22:44:22 +04:00
r . in . buffer = & blob ;
2009-02-06 14:32:57 +03:00
r . in . offered = needed ;
2005-06-14 22:44:22 +04:00
2010-04-07 02:38:02 +04:00
status = dcerpc_spoolss_GetPrinterDriverDirectory_r ( b , tctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_GetPrinterDriverDirectory failed " ) ;
2005-06-14 22:44:22 +04:00
2007-09-03 17:13:25 +04:00
torture_assert_werr_ok ( tctx , r . out . result , " GetPrinterDriverDirectory failed " ) ;
2009-12-12 03:51:13 +03:00
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_LEVEL ( spoolss_DriverDirectoryInfo , r . out . info , r . in . level , needed , 2 ) ;
2005-06-14 22:44:22 +04:00
}
2007-09-03 17:13:25 +04:00
return true ;
2005-06-14 22:44:22 +04:00
}
2014-03-20 18:56:13 +04:00
static bool test_EnumPrinterDrivers_buffers ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server_name ,
const char * environment ,
uint32_t level ,
uint32_t offered ,
uint32_t * count_p ,
union spoolss_DriverInfo * * info_p )
2010-04-21 17:08:40 +04:00
{
struct spoolss_EnumPrinterDrivers r ;
uint32_t needed ;
uint32_t count ;
union spoolss_DriverInfo * info ;
2014-03-20 18:56:13 +04:00
DATA_BLOB buffer ;
if ( offered > 0 ) {
buffer = data_blob_talloc_zero ( tctx , offered ) ;
}
2010-04-21 17:08:40 +04:00
r . in . server = server_name ;
r . in . environment = environment ;
r . in . level = level ;
2014-03-20 18:56:13 +04:00
r . in . buffer = offered ? & buffer : NULL ;
r . in . offered = offered ;
2010-04-21 17:08:40 +04:00
r . out . needed = & needed ;
r . out . count = & count ;
r . out . info = & info ;
2014-03-20 18:56:13 +04:00
torture_comment ( tctx , " Testing EnumPrinterDrivers(%s) level %u, offered: %u \n " ,
r . in . environment , r . in . level , r . in . offered ) ;
2010-04-21 17:08:40 +04:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_EnumPrinterDrivers_r ( b , tctx , & r ) ,
" EnumPrinterDrivers failed " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
r . in . buffer = & blob ;
r . in . offered = needed ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_EnumPrinterDrivers_r ( b , tctx , & r ) ,
" EnumPrinterDrivers failed " ) ;
}
torture_assert_werr_ok ( tctx , r . out . result ,
" EnumPrinterDrivers failed " ) ;
if ( count_p ) {
* count_p = count ;
}
if ( info_p ) {
* info_p = info ;
}
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_ENUM_LEVEL ( spoolss_EnumPrinterDrivers , info , r . in . level , count , needed , 4 ) ;
2010-04-21 17:08:40 +04:00
return true ;
}
2014-03-20 18:56:13 +04:00
static bool test_EnumPrinterDrivers_args ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server_name ,
const char * environment ,
uint32_t level ,
uint32_t * count_p ,
union spoolss_DriverInfo * * info_p )
{
return test_EnumPrinterDrivers_buffers ( tctx , b , server_name ,
environment , level , 0 ,
count_p , info_p ) ;
}
2010-04-21 17:08:40 +04:00
static bool test_EnumPrinterDrivers_findone ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server_name ,
const char * environment ,
uint32_t level ,
2010-12-15 19:44:56 +03:00
const char * driver_name ,
union spoolss_DriverInfo * info_p )
2010-04-21 17:08:40 +04:00
{
uint32_t count ;
union spoolss_DriverInfo * info ;
int i ;
2010-12-13 17:46:05 +03:00
const char * environment_ret = NULL ;
2010-04-21 17:08:40 +04:00
torture_assert ( tctx ,
test_EnumPrinterDrivers_args ( tctx , b , server_name , environment , level , & count , & info ) ,
" failed to enumerate printer drivers " ) ;
for ( i = 0 ; i < count ; i + + ) {
2013-12-04 17:01:51 +04:00
const char * driver_name_ret = " " ;
2010-04-21 17:08:40 +04:00
switch ( level ) {
case 1 :
2010-04-23 05:03:59 +04:00
driver_name_ret = info [ i ] . info1 . driver_name ;
2010-04-21 17:08:40 +04:00
break ;
case 2 :
2010-04-23 05:03:59 +04:00
driver_name_ret = info [ i ] . info2 . driver_name ;
2010-12-13 17:46:05 +03:00
environment_ret = info [ i ] . info2 . architecture ;
2010-04-21 17:08:40 +04:00
break ;
case 3 :
2010-04-23 05:03:59 +04:00
driver_name_ret = info [ i ] . info3 . driver_name ;
2010-12-13 17:46:05 +03:00
environment_ret = info [ i ] . info3 . architecture ;
2010-04-21 17:08:40 +04:00
break ;
case 4 :
2010-04-23 05:03:59 +04:00
driver_name_ret = info [ i ] . info4 . driver_name ;
2010-12-13 17:46:05 +03:00
environment_ret = info [ i ] . info4 . architecture ;
2010-04-21 17:08:40 +04:00
break ;
case 5 :
2010-04-23 05:03:59 +04:00
driver_name_ret = info [ i ] . info5 . driver_name ;
2010-12-13 17:46:05 +03:00
environment_ret = info [ i ] . info5 . architecture ;
2010-04-21 17:08:40 +04:00
break ;
case 6 :
2010-04-23 05:03:59 +04:00
driver_name_ret = info [ i ] . info6 . driver_name ;
2010-12-13 17:46:05 +03:00
environment_ret = info [ i ] . info6 . architecture ;
2010-04-21 17:08:40 +04:00
break ;
case 7 :
2010-04-23 05:03:59 +04:00
driver_name_ret = info [ i ] . info7 . driver_name ;
2010-04-21 17:08:40 +04:00
break ;
case 8 :
2010-04-23 05:03:59 +04:00
driver_name_ret = info [ i ] . info8 . driver_name ;
2010-12-13 17:46:05 +03:00
environment_ret = info [ i ] . info8 . architecture ;
2010-04-21 17:08:40 +04:00
break ;
default :
break ;
}
2010-12-13 17:46:05 +03:00
if ( environment_ret ) {
torture_assert_str_equal ( tctx , environment , environment_ret , " architecture mismatch " ) ;
}
2010-04-21 17:08:40 +04:00
if ( strequal ( driver_name , driver_name_ret ) ) {
2010-12-15 19:44:56 +03:00
if ( info_p ) {
* info_p = info [ i ] ;
}
2010-04-21 17:08:40 +04:00
return true ;
}
}
return false ;
}
2009-06-30 13:38:41 +04:00
static bool test_EnumPrinterDrivers ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2005-04-02 10:51:54 +04:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-12-07 21:26:45 +03:00
uint16_t levels [ ] = { 1 , 2 , 3 , 4 , 5 , 6 , 8 } ;
2014-03-20 18:57:10 +04:00
uint16_t buffer_sizes [ ] = { 0 , 1024 , 6040 , 0xffff } ;
2010-05-19 01:40:43 +04:00
int i , j , a ;
2005-04-02 10:51:54 +04:00
2010-04-21 17:08:40 +04:00
/* FIXME: gd, come back and fix "" as server, and handle
* priority of returned error codes in torture test and samba 3
* server */
const char * server_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2010-05-19 01:40:43 +04:00
const char * environments [ 2 ] ;
environments [ 0 ] = SPOOLSS_ARCHITECTURE_ALL ;
environments [ 1 ] = ctx - > environment ;
for ( a = 0 ; a < ARRAY_SIZE ( environments ) ; a + + ) {
2010-04-21 17:08:40 +04:00
2014-03-20 18:57:10 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( buffer_sizes ) ; i + + ) {
torture_assert ( tctx ,
test_EnumPrinterDrivers_buffers ( tctx , b , server_name ,
environments [ a ] , 3 ,
buffer_sizes [ i ] ,
NULL , NULL ) ,
" failed to enumerate drivers " ) ;
}
2005-04-02 10:51:54 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
2009-02-16 18:42:21 +03:00
uint32_t count ;
2009-03-02 19:32:24 +03:00
union spoolss_DriverInfo * info ;
2005-04-02 10:51:54 +04:00
2010-04-21 17:08:40 +04:00
torture_assert ( tctx ,
2010-05-19 01:40:43 +04:00
test_EnumPrinterDrivers_args ( tctx , b , server_name , environments [ a ] , level , & count , & info ) ,
2010-04-21 17:08:40 +04:00
" failed to enumerate drivers " ) ;
2009-12-12 03:51:13 +03:00
2009-02-16 18:42:21 +03:00
ctx - > driver_count [ level ] = count ;
2009-03-02 19:32:24 +03:00
ctx - > drivers [ level ] = info ;
2005-04-02 10:51:54 +04:00
}
for ( i = 1 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
int old_level = levels [ i - 1 ] ;
2009-05-13 17:35:25 +04:00
2007-09-03 17:13:25 +04:00
torture_assert_int_equal ( tctx , ctx - > driver_count [ level ] , ctx - > driver_count [ old_level ] ,
" EnumPrinterDrivers invalid value " ) ;
2005-04-02 10:51:54 +04:00
}
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
2009-05-13 17:35:25 +04:00
2013-02-19 12:32:30 +04:00
for ( j = 0 ; j < ctx - > driver_count [ level - 1 ] ; j + + ) {
union spoolss_DriverInfo * cur = & ctx - > drivers [ level - 1 ] [ j ] ;
2016-11-11 18:32:20 +03:00
union spoolss_DriverInfo * ref = & ctx - > drivers [ 8 ] [ j ] ;
2009-12-07 21:26:45 +03:00
2005-04-02 10:51:54 +04:00
switch ( level ) {
case 1 :
2009-12-07 21:26:45 +03:00
COMPARE_STRING ( tctx , cur - > info1 , ref - > info8 , driver_name ) ;
2005-04-02 10:51:54 +04:00
break ;
case 2 :
2009-12-07 21:26:45 +03:00
COMPARE_UINT32 ( tctx , cur - > info2 , ref - > info8 , version ) ;
COMPARE_STRING ( tctx , cur - > info2 , ref - > info8 , driver_name ) ;
COMPARE_STRING ( tctx , cur - > info2 , ref - > info8 , architecture ) ;
COMPARE_STRING ( tctx , cur - > info2 , ref - > info8 , driver_path ) ;
COMPARE_STRING ( tctx , cur - > info2 , ref - > info8 , data_file ) ;
COMPARE_STRING ( tctx , cur - > info2 , ref - > info8 , config_file ) ;
2005-04-02 10:51:54 +04:00
break ;
case 3 :
2009-12-07 21:26:45 +03:00
COMPARE_UINT32 ( tctx , cur - > info3 , ref - > info8 , version ) ;
COMPARE_STRING ( tctx , cur - > info3 , ref - > info8 , driver_name ) ;
COMPARE_STRING ( tctx , cur - > info3 , ref - > info8 , architecture ) ;
COMPARE_STRING ( tctx , cur - > info3 , ref - > info8 , driver_path ) ;
COMPARE_STRING ( tctx , cur - > info3 , ref - > info8 , data_file ) ;
COMPARE_STRING ( tctx , cur - > info3 , ref - > info8 , config_file ) ;
COMPARE_STRING ( tctx , cur - > info3 , ref - > info8 , help_file ) ;
COMPARE_STRING_ARRAY ( tctx , cur - > info3 , ref - > info8 , dependent_files ) ;
COMPARE_STRING ( tctx , cur - > info3 , ref - > info8 , monitor_name ) ;
COMPARE_STRING ( tctx , cur - > info3 , ref - > info8 , default_datatype ) ;
2005-04-02 10:51:54 +04:00
break ;
case 4 :
2009-12-07 21:26:45 +03:00
COMPARE_UINT32 ( tctx , cur - > info4 , ref - > info8 , version ) ;
COMPARE_STRING ( tctx , cur - > info4 , ref - > info8 , driver_name ) ;
COMPARE_STRING ( tctx , cur - > info4 , ref - > info8 , architecture ) ;
COMPARE_STRING ( tctx , cur - > info4 , ref - > info8 , driver_path ) ;
COMPARE_STRING ( tctx , cur - > info4 , ref - > info8 , data_file ) ;
COMPARE_STRING ( tctx , cur - > info4 , ref - > info8 , config_file ) ;
COMPARE_STRING ( tctx , cur - > info4 , ref - > info8 , help_file ) ;
COMPARE_STRING_ARRAY ( tctx , cur - > info4 , ref - > info8 , dependent_files ) ;
COMPARE_STRING ( tctx , cur - > info4 , ref - > info8 , monitor_name ) ;
COMPARE_STRING ( tctx , cur - > info4 , ref - > info8 , default_datatype ) ;
COMPARE_STRING_ARRAY ( tctx , cur - > info4 , ref - > info8 , previous_names ) ;
2005-04-02 10:51:54 +04:00
break ;
case 5 :
2009-12-07 21:26:45 +03:00
COMPARE_UINT32 ( tctx , cur - > info5 , ref - > info8 , version ) ;
COMPARE_STRING ( tctx , cur - > info5 , ref - > info8 , driver_name ) ;
COMPARE_STRING ( tctx , cur - > info5 , ref - > info8 , architecture ) ;
COMPARE_STRING ( tctx , cur - > info5 , ref - > info8 , driver_path ) ;
COMPARE_STRING ( tctx , cur - > info5 , ref - > info8 , data_file ) ;
COMPARE_STRING ( tctx , cur - > info5 , ref - > info8 , config_file ) ;
/*COMPARE_UINT32(tctx, cur->info5, ref->info8, driver_attributes);*/
/*COMPARE_UINT32(tctx, cur->info5, ref->info8, config_version);*/
/*TODO: ! COMPARE_UINT32(tctx, cur->info5, ref->info8, driver_version); */
2005-04-02 10:51:54 +04:00
break ;
case 6 :
2009-12-07 21:26:45 +03:00
COMPARE_UINT32 ( tctx , cur - > info6 , ref - > info8 , version ) ;
COMPARE_STRING ( tctx , cur - > info6 , ref - > info8 , driver_name ) ;
COMPARE_STRING ( tctx , cur - > info6 , ref - > info8 , architecture ) ;
COMPARE_STRING ( tctx , cur - > info6 , ref - > info8 , driver_path ) ;
COMPARE_STRING ( tctx , cur - > info6 , ref - > info8 , data_file ) ;
COMPARE_STRING ( tctx , cur - > info6 , ref - > info8 , config_file ) ;
COMPARE_STRING ( tctx , cur - > info6 , ref - > info8 , help_file ) ;
COMPARE_STRING_ARRAY ( tctx , cur - > info6 , ref - > info8 , dependent_files ) ;
COMPARE_STRING ( tctx , cur - > info6 , ref - > info8 , monitor_name ) ;
COMPARE_STRING ( tctx , cur - > info6 , ref - > info8 , default_datatype ) ;
COMPARE_STRING_ARRAY ( tctx , cur - > info6 , ref - > info8 , previous_names ) ;
COMPARE_NTTIME ( tctx , cur - > info6 , ref - > info8 , driver_date ) ;
COMPARE_UINT64 ( tctx , cur - > info6 , ref - > info8 , driver_version ) ;
COMPARE_STRING ( tctx , cur - > info6 , ref - > info8 , manufacturer_name ) ;
COMPARE_STRING ( tctx , cur - > info6 , ref - > info8 , manufacturer_url ) ;
COMPARE_STRING ( tctx , cur - > info6 , ref - > info8 , hardware_id ) ;
COMPARE_STRING ( tctx , cur - > info6 , ref - > info8 , provider ) ;
break ;
case 8 :
/* level 8 is our reference, and it makes no sense to compare it to itself */
2005-04-02 10:51:54 +04:00
break ;
}
}
}
2010-05-19 01:40:43 +04:00
}
2005-04-02 10:51:54 +04:00
2007-09-03 17:13:25 +04:00
return true ;
2005-04-02 10:51:54 +04:00
}
2009-06-30 13:38:41 +04:00
static bool test_EnumMonitors ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2005-04-02 10:51:54 +04:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
2005-04-02 10:51:54 +04:00
NTSTATUS status ;
struct spoolss_EnumMonitors r ;
uint16_t levels [ ] = { 1 , 2 } ;
int i , j ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
DATA_BLOB blob ;
2009-02-06 19:09:30 +03:00
uint32_t needed ;
2009-02-16 18:42:21 +03:00
uint32_t count ;
2009-03-02 19:32:24 +03:00
union spoolss_MonitorInfo * info ;
2005-04-02 10:51:54 +04:00
r . in . servername = " " ;
r . in . level = level ;
r . in . buffer = NULL ;
2005-06-14 19:52:31 +04:00
r . in . offered = 0 ;
2009-02-06 19:09:30 +03:00
r . out . needed = & needed ;
2009-02-16 18:42:21 +03:00
r . out . count = & count ;
2009-03-02 19:32:24 +03:00
r . out . info = & info ;
2005-04-02 10:51:54 +04:00
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing EnumMonitors level %u \n " , r . in . level ) ;
2005-04-02 10:51:54 +04:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EnumMonitors_r ( b , ctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_EnumMonitors failed " ) ;
2005-06-07 18:31:45 +04:00
if ( W_ERROR_IS_OK ( r . out . result ) ) {
/* TODO: do some more checks here */
continue ;
}
2009-06-30 13:38:41 +04:00
torture_assert_werr_equal ( tctx , r . out . result , WERR_INSUFFICIENT_BUFFER ,
2007-09-03 17:13:25 +04:00
" EnumMonitors failed " ) ;
2005-04-02 10:51:54 +04:00
2010-04-08 13:56:27 +04:00
blob = data_blob_talloc_zero ( ctx , needed ) ;
2005-04-02 10:51:54 +04:00
r . in . buffer = & blob ;
2009-02-06 19:09:30 +03:00
r . in . offered = needed ;
2005-04-02 10:51:54 +04:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EnumMonitors_r ( b , ctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_EnumMonitors failed " ) ;
2005-04-02 10:51:54 +04:00
2007-09-03 17:13:25 +04:00
torture_assert_werr_ok ( tctx , r . out . result , " EnumMonitors failed " ) ;
2005-04-02 10:51:54 +04:00
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_ENUM_LEVEL ( spoolss_EnumMonitors , info , r . in . level , count , needed , 4 ) ;
2009-12-12 03:51:13 +03:00
2009-02-16 18:42:21 +03:00
ctx - > monitor_count [ level ] = count ;
2009-03-02 19:32:24 +03:00
ctx - > monitors [ level ] = info ;
2005-04-02 10:51:54 +04:00
}
for ( i = 1 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
int old_level = levels [ i - 1 ] ;
2009-06-30 13:38:41 +04:00
torture_assert_int_equal ( tctx , ctx - > monitor_count [ level ] , ctx - > monitor_count [ old_level ] ,
2007-09-03 17:13:25 +04:00
" EnumMonitors invalid value " ) ;
2005-04-02 10:51:54 +04:00
}
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
for ( j = 0 ; j < ctx - > monitor_count [ level ] ; j + + ) {
2005-05-31 02:44:17 +04:00
union spoolss_MonitorInfo * cur = & ctx - > monitors [ level ] [ j ] ;
union spoolss_MonitorInfo * ref = & ctx - > monitors [ 2 ] [ j ] ;
2005-04-02 10:51:54 +04:00
switch ( level ) {
case 1 :
2007-09-03 17:13:25 +04:00
COMPARE_STRING ( tctx , cur - > info1 , ref - > info2 , monitor_name ) ;
2005-04-02 10:51:54 +04:00
break ;
case 2 :
2016-11-21 14:44:54 +03:00
torture_assert_str_equal ( tctx , ref - > info2 . environment , ctx - > environment , " invalid environment " ) ;
2005-04-02 10:51:54 +04:00
/* level 2 is our reference, and it makes no sense to compare it to itself */
break ;
}
}
}
2007-09-03 17:13:25 +04:00
return true ;
2005-04-02 10:51:54 +04:00
}
2010-06-03 15:01:16 +04:00
static bool test_EnumPrintProcessors_level ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * environment ,
uint32_t level ,
uint32_t * count_p ,
2010-09-28 01:33:52 +04:00
union spoolss_PrintProcessorInfo * * info_p ,
WERROR expected_result )
2010-06-03 15:01:16 +04:00
{
struct spoolss_EnumPrintProcessors r ;
DATA_BLOB blob ;
uint32_t needed ;
uint32_t count ;
union spoolss_PrintProcessorInfo * info ;
r . in . servername = " " ;
r . in . environment = environment ;
r . in . level = level ;
r . in . buffer = NULL ;
r . in . offered = 0 ;
r . out . needed = & needed ;
r . out . count = & count ;
r . out . info = & info ;
2010-09-28 01:33:52 +04:00
torture_comment ( tctx , " Testing EnumPrintProcessors(%s) level %u \n " ,
r . in . environment , r . in . level ) ;
2010-06-03 15:01:16 +04:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_EnumPrintProcessors_r ( b , tctx , & r ) ,
" EnumPrintProcessors failed " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
blob = data_blob_talloc_zero ( tctx , needed ) ;
r . in . buffer = & blob ;
r . in . offered = needed ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_EnumPrintProcessors_r ( b , tctx , & r ) ,
" EnumPrintProcessors failed " ) ;
}
2010-09-28 01:33:52 +04:00
torture_assert_werr_equal ( tctx , r . out . result , expected_result ,
2010-06-03 15:01:16 +04:00
" EnumPrintProcessors failed " ) ;
CHECK_NEEDED_SIZE_ENUM_LEVEL ( spoolss_EnumPrintProcessors , info , level , count , needed , 4 ) ;
if ( count_p ) {
* count_p = count ;
}
if ( info_p ) {
* info_p = info ;
}
return true ;
}
2009-06-30 13:38:41 +04:00
static bool test_EnumPrintProcessors ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2005-04-02 10:51:54 +04:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
2010-09-28 01:33:52 +04:00
uint16_t levels [ ] = { 0 , 1 , 2 , 3 , 32 , 256 } ;
uint16_t ok [ ] = { 0 , 1 , 0 , 0 , 0 , 0 } ;
int i ;
2010-05-19 01:40:43 +04:00
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
2005-04-02 10:51:54 +04:00
2010-09-28 01:33:52 +04:00
torture_assert ( tctx ,
test_EnumPrintProcessors_level ( tctx , b , " phantasy " , 1 , NULL , NULL , WERR_INVALID_ENVIRONMENT ) ,
" test_EnumPrintProcessors_level failed " ) ;
2005-04-02 10:51:54 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
2009-03-02 19:32:24 +03:00
union spoolss_PrintProcessorInfo * info ;
2010-06-03 15:01:16 +04:00
uint32_t count ;
2010-09-28 01:33:52 +04:00
WERROR expected_result = ok [ i ] ? WERR_OK : WERR_INVALID_LEVEL ;
2005-04-02 10:51:54 +04:00
2010-06-03 15:01:16 +04:00
torture_assert ( tctx ,
2010-09-28 01:33:52 +04:00
test_EnumPrintProcessors_level ( tctx , b , ctx - > environment , levels [ i ] , & count , & info , expected_result ) ,
2010-06-03 15:01:16 +04:00
" test_EnumPrintProcessors_level failed " ) ;
2005-04-02 10:51:54 +04:00
}
2007-09-03 17:13:25 +04:00
return true ;
2005-04-02 10:51:54 +04:00
}
2016-08-26 02:05:20 +03:00
static bool test_EnumPrintProcessorDataTypes_level ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * print_processor_name ,
uint32_t level ,
uint32_t * count_p ,
union spoolss_PrintProcDataTypesInfo * * info_p ,
WERROR expected_result )
{
struct spoolss_EnumPrintProcessorDataTypes r ;
2010-09-28 02:10:31 +04:00
DATA_BLOB blob ;
uint32_t needed ;
uint32_t count ;
union spoolss_PrintProcDataTypesInfo * info ;
r . in . servername = " " ;
r . in . print_processor_name = print_processor_name ;
r . in . level = level ;
r . in . buffer = NULL ;
r . in . offered = 0 ;
r . out . needed = & needed ;
r . out . count = & count ;
r . out . info = & info ;
2016-08-26 02:05:20 +03:00
torture_comment ( tctx , " Testing EnumPrintProcessorDataTypes(%s) level %u \n " ,
2010-09-28 02:10:31 +04:00
r . in . print_processor_name , r . in . level ) ;
torture_assert_ntstatus_ok ( tctx ,
2016-08-26 02:05:20 +03:00
dcerpc_spoolss_EnumPrintProcessorDataTypes_r ( b , tctx , & r ) ,
" EnumPrintProcessorDataTypes failed " ) ;
2010-09-28 02:10:31 +04:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
blob = data_blob_talloc_zero ( tctx , needed ) ;
r . in . buffer = & blob ;
r . in . offered = needed ;
torture_assert_ntstatus_ok ( tctx ,
2016-08-26 02:05:20 +03:00
dcerpc_spoolss_EnumPrintProcessorDataTypes_r ( b , tctx , & r ) ,
" EnumPrintProcessorDataTypes failed " ) ;
2010-09-28 02:10:31 +04:00
}
torture_assert_werr_equal ( tctx , r . out . result , expected_result ,
2016-08-26 02:05:20 +03:00
" EnumPrintProcessorDataTypes failed " ) ;
2010-09-28 02:10:31 +04:00
2016-08-26 02:05:20 +03:00
CHECK_NEEDED_SIZE_ENUM_LEVEL ( spoolss_EnumPrintProcessorDataTypes , info , level , count , needed , 4 ) ;
2010-09-28 02:10:31 +04:00
if ( count_p ) {
* count_p = count ;
}
if ( info_p ) {
* info_p = info ;
}
return true ;
}
2016-08-26 02:05:20 +03:00
static bool test_EnumPrintProcessorDataTypes ( struct torture_context * tctx ,
void * private_data )
2009-03-06 23:50:15 +03:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
2010-09-28 02:10:31 +04:00
uint16_t levels [ ] = { 0 , 1 , 2 , 3 , 32 , 256 } ;
uint16_t ok [ ] = { 0 , 1 , 0 , 0 , 0 , 0 } ;
2009-03-14 03:36:01 +03:00
int i ;
2010-05-19 01:40:43 +04:00
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-03-06 23:50:15 +03:00
2010-09-28 02:10:31 +04:00
torture_assert ( tctx ,
2016-08-26 02:05:20 +03:00
test_EnumPrintProcessorDataTypes_level ( tctx , b , NULL , 1 , NULL , NULL , WERR_UNKNOWN_PRINTPROCESSOR ) ,
" test_EnumPrintProcessorDataTypes_level failed " ) ;
2010-09-28 02:10:31 +04:00
torture_assert ( tctx ,
2016-08-26 02:05:20 +03:00
test_EnumPrintProcessorDataTypes_level ( tctx , b , " nonexisting " , 1 , NULL , NULL , WERR_UNKNOWN_PRINTPROCESSOR ) ,
" test_EnumPrintProcessorDataTypes_level failed " ) ;
2010-09-28 02:10:31 +04:00
2009-03-06 23:50:15 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
uint32_t count ;
union spoolss_PrintProcDataTypesInfo * info ;
2010-09-28 02:10:31 +04:00
WERROR expected_result = ok [ i ] ? WERR_OK : WERR_INVALID_LEVEL ;
2009-03-06 23:50:15 +03:00
2010-09-28 02:10:31 +04:00
torture_assert ( tctx ,
2016-08-26 02:05:20 +03:00
test_EnumPrintProcessorDataTypes_level ( tctx , b , " winprint " , level , & count , & info , expected_result ) ,
" test_EnumPrintProcessorDataTypes_level failed " ) ;
2010-09-28 02:10:31 +04:00
}
2009-03-06 23:50:15 +03:00
2010-09-28 02:10:31 +04:00
{
union spoolss_PrintProcessorInfo * info ;
uint32_t count ;
2009-12-12 03:51:13 +03:00
2010-09-28 02:10:31 +04:00
torture_assert ( tctx ,
test_EnumPrintProcessors_level ( tctx , b , ctx - > environment , 1 , & count , & info , WERR_OK ) ,
" test_EnumPrintProcessors_level failed " ) ;
2009-12-12 03:51:13 +03:00
2010-09-28 02:10:31 +04:00
for ( i = 0 ; i < count ; i + + ) {
torture_assert ( tctx ,
2016-08-26 02:05:20 +03:00
test_EnumPrintProcessorDataTypes_level ( tctx , b , info [ i ] . info1 . print_processor_name , 1 , NULL , NULL , WERR_OK ) ,
" test_EnumPrintProcessorDataTypes_level failed " ) ;
2010-09-28 02:10:31 +04:00
}
2009-03-06 23:50:15 +03:00
}
2010-09-28 02:10:31 +04:00
2009-03-06 23:50:15 +03:00
return true ;
}
2009-06-30 13:38:41 +04:00
static bool test_EnumPrinters ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2005-04-02 10:51:54 +04:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
2005-04-02 10:51:54 +04:00
struct spoolss_EnumPrinters r ;
NTSTATUS status ;
uint16_t levels [ ] = { 0 , 1 , 2 , 4 , 5 } ;
int i , j ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
DATA_BLOB blob ;
2009-02-06 19:09:30 +03:00
uint32_t needed ;
2009-02-16 18:42:21 +03:00
uint32_t count ;
2009-03-02 19:32:24 +03:00
union spoolss_PrinterInfo * info ;
2005-04-02 10:51:54 +04:00
r . in . flags = PRINTER_ENUM_LOCAL ;
r . in . server = " " ;
r . in . level = level ;
r . in . buffer = NULL ;
2005-06-14 19:52:31 +04:00
r . in . offered = 0 ;
2009-02-06 19:09:30 +03:00
r . out . needed = & needed ;
2009-02-16 18:42:21 +03:00
r . out . count = & count ;
2009-03-02 19:32:24 +03:00
r . out . info = & info ;
2005-04-02 10:51:54 +04:00
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing EnumPrinters level %u \n " , r . in . level ) ;
2005-04-02 10:51:54 +04:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EnumPrinters_r ( b , ctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_EnumPrinters failed " ) ;
2005-06-07 18:31:45 +04:00
if ( W_ERROR_IS_OK ( r . out . result ) ) {
/* TODO: do some more checks here */
continue ;
}
2009-06-30 13:38:41 +04:00
torture_assert_werr_equal ( tctx , r . out . result , WERR_INSUFFICIENT_BUFFER ,
2007-09-03 17:13:25 +04:00
" EnumPrinters unexpected return code " ) ;
2005-04-02 10:51:54 +04:00
2010-04-08 13:56:27 +04:00
blob = data_blob_talloc_zero ( ctx , needed ) ;
2005-04-02 10:51:54 +04:00
r . in . buffer = & blob ;
2009-02-06 19:09:30 +03:00
r . in . offered = needed ;
2005-06-14 19:52:31 +04:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EnumPrinters_r ( b , ctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_EnumPrinters failed " ) ;
2005-04-02 10:51:54 +04:00
2007-09-03 17:13:25 +04:00
torture_assert_werr_ok ( tctx , r . out . result , " EnumPrinters failed " ) ;
2005-04-02 10:51:54 +04:00
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_ENUM_LEVEL ( spoolss_EnumPrinters , info , r . in . level , count , needed , 4 ) ;
2009-12-12 03:51:13 +03:00
2009-02-16 18:42:21 +03:00
ctx - > printer_count [ level ] = count ;
2009-03-02 19:32:24 +03:00
ctx - > printers [ level ] = info ;
2005-04-02 10:51:54 +04:00
}
for ( i = 1 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
int old_level = levels [ i - 1 ] ;
2007-09-03 17:13:25 +04:00
torture_assert_int_equal ( tctx , ctx - > printer_count [ level ] , ctx - > printer_count [ old_level ] ,
" EnumPrinters invalid value " ) ;
2005-04-02 10:51:54 +04:00
}
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
int level = levels [ i ] ;
for ( j = 0 ; j < ctx - > printer_count [ level ] ; j + + ) {
2005-05-31 02:44:17 +04:00
union spoolss_PrinterInfo * cur = & ctx - > printers [ level ] [ j ] ;
union spoolss_PrinterInfo * ref = & ctx - > printers [ 2 ] [ j ] ;
2005-04-02 10:51:54 +04:00
switch ( level ) {
case 0 :
2007-09-03 17:13:25 +04:00
COMPARE_STRING ( tctx , cur - > info0 , ref - > info2 , printername ) ;
COMPARE_STRING ( tctx , cur - > info0 , ref - > info2 , servername ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , cjobs ) ;
/*COMPARE_UINT32(tctx, cur->info0, ref->info2, total_jobs);
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , total_bytes ) ;
2009-06-30 13:38:41 +04:00
COMPARE_SPOOLSS_TIME ( cur - > info0 , ref - > info2 , spoolss_Time time ) ;
2007-09-03 17:13:25 +04:00
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , global_counter ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , total_pages ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , version ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , unknown10 ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , unknown11 ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , unknown12 ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , session_counter ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , unknown14 ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , printer_errors ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , unknown16 ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , unknown17 ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , unknown18 ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , unknown19 ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , change_id ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , unknown21 ) ; */
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , status ) ;
/*COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown23);
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , c_setprinter ) ;
2005-04-02 10:51:54 +04:00
COMPARE_UINT16 ( cur - > info0 , ref - > info2 , unknown25 ) ;
COMPARE_UINT16 ( cur - > info0 , ref - > info2 , unknown26 ) ;
2007-09-03 17:13:25 +04:00
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , unknown27 ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , unknown28 ) ;
COMPARE_UINT32 ( tctx , cur - > info0 , ref - > info2 , unknown29 ) ; */
2005-04-02 10:51:54 +04:00
break ;
case 1 :
2007-09-03 17:13:25 +04:00
/*COMPARE_UINT32(tctx, cur->info1, ref->info2, flags);*/
/*COMPARE_STRING(tctx, cur->info1, ref->info2, name);*/
/*COMPARE_STRING(tctx, cur->info1, ref->info2, description);*/
COMPARE_STRING ( tctx , cur - > info1 , ref - > info2 , comment ) ;
2005-04-02 10:51:54 +04:00
break ;
case 2 :
/* level 2 is our reference, and it makes no sense to compare it to itself */
break ;
case 4 :
2007-09-03 17:13:25 +04:00
COMPARE_STRING ( tctx , cur - > info4 , ref - > info2 , printername ) ;
COMPARE_STRING ( tctx , cur - > info4 , ref - > info2 , servername ) ;
COMPARE_UINT32 ( tctx , cur - > info4 , ref - > info2 , attributes ) ;
2005-04-02 10:51:54 +04:00
break ;
case 5 :
2007-09-03 17:13:25 +04:00
COMPARE_STRING ( tctx , cur - > info5 , ref - > info2 , printername ) ;
COMPARE_STRING ( tctx , cur - > info5 , ref - > info2 , portname ) ;
COMPARE_UINT32 ( tctx , cur - > info5 , ref - > info2 , attributes ) ;
/*COMPARE_UINT32(tctx, cur->info5, ref->info2, device_not_selected_timeout);
COMPARE_UINT32 ( tctx , cur - > info5 , ref - > info2 , transmission_retry_timeout ) ; */
2005-04-02 10:51:54 +04:00
break ;
}
}
}
/* TODO:
* - verify that the port of a printer was in the list returned by EnumPorts
*/
2007-09-03 17:13:25 +04:00
return true ;
2005-04-02 10:51:54 +04:00
}
2009-12-16 00:26:39 +03:00
static bool test_GetPrinterDriver2 ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-12-16 00:26:39 +03:00
struct policy_handle * handle ,
2010-02-25 21:06:39 +03:00
const char * driver_name ,
const char * environment ) ;
2009-12-16 00:26:39 +03:00
2016-09-09 17:00:38 +03:00
bool test_GetPrinter_level_exp ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
uint32_t level ,
WERROR expected_werror ,
union spoolss_PrinterInfo * info )
2003-11-17 07:56:59 +03:00
{
struct spoolss_GetPrinter r ;
2009-02-06 14:22:35 +03:00
uint32_t needed ;
2009-06-30 13:38:41 +04:00
2010-01-06 19:51:34 +03:00
r . in . handle = handle ;
r . in . level = level ;
r . in . buffer = NULL ;
r . in . offered = 0 ;
r . out . needed = & needed ;
2003-11-17 07:56:59 +03:00
2010-01-06 19:51:34 +03:00
torture_comment ( tctx , " Testing GetPrinter level %u \n " , r . in . level ) ;
2003-11-17 07:56:59 +03:00
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_GetPrinter_r ( b , tctx , & r ) ,
2010-01-06 19:51:34 +03:00
" GetPrinter failed " ) ;
2009-06-30 13:38:41 +04:00
2010-01-06 19:51:34 +03:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
2010-04-08 13:56:27 +04:00
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
2010-01-06 19:51:34 +03:00
r . in . buffer = & blob ;
r . in . offered = needed ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_GetPrinter_r ( b , tctx , & r ) ,
2010-01-06 19:51:34 +03:00
" GetPrinter failed " ) ;
}
2016-09-09 17:00:38 +03:00
torture_assert_werr_equal ( tctx ,
r . out . result , expected_werror ,
" GetPrinter failed " ) ;
2010-01-06 19:51:34 +03:00
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_LEVEL ( spoolss_PrinterInfo , r . out . info , r . in . level , needed , 4 ) ;
2010-01-06 19:51:34 +03:00
if ( info & & r . out . info ) {
* info = * r . out . info ;
}
return true ;
}
2016-09-09 17:00:38 +03:00
bool test_GetPrinter_level ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
uint32_t level ,
union spoolss_PrinterInfo * info )
{
return test_GetPrinter_level_exp ( tctx , b , handle , level , WERR_OK , info ) ;
}
2010-01-06 19:51:34 +03:00
static bool test_GetPrinter ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-02-25 21:06:39 +03:00
struct policy_handle * handle ,
const char * environment )
2010-01-06 19:51:34 +03:00
{
uint32_t levels [ ] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 } ;
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
2009-06-30 13:38:41 +04:00
2010-01-06 19:51:34 +03:00
union spoolss_PrinterInfo info ;
2005-06-14 19:52:31 +04:00
2010-01-06 19:51:34 +03:00
ZERO_STRUCT ( info ) ;
2009-12-12 03:51:13 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , levels [ i ] , & info ) ,
2010-01-06 19:51:34 +03:00
" failed to call GetPrinter " ) ;
2009-12-16 00:26:39 +03:00
2010-01-06 19:51:34 +03:00
if ( ( levels [ i ] = = 2 ) & & info . info2 . drivername & & strlen ( info . info2 . drivername ) ) {
2009-12-16 00:26:39 +03:00
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_GetPrinterDriver2 ( tctx , b , handle , info . info2 . drivername , environment ) ,
2009-12-16 00:26:39 +03:00
" failed to call test_GetPrinterDriver2 " ) ;
}
2003-11-17 07:56:59 +03:00
}
2007-09-03 17:13:25 +04:00
return true ;
2003-11-17 07:56:59 +03:00
}
2010-01-06 21:33:39 +03:00
static bool test_SetPrinter ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-01-06 21:33:39 +03:00
struct policy_handle * handle ,
struct spoolss_SetPrinterInfoCtr * info_ctr ,
struct spoolss_DevmodeContainer * devmode_ctr ,
struct sec_desc_buf * secdesc_ctr ,
enum spoolss_PrinterControl command )
{
struct spoolss_SetPrinter r ;
r . in . handle = handle ;
r . in . info_ctr = info_ctr ;
r . in . devmode_ctr = devmode_ctr ;
r . in . secdesc_ctr = secdesc_ctr ;
r . in . command = command ;
2010-02-15 23:55:06 +03:00
torture_comment ( tctx , " Testing SetPrinter level %d \n " , r . in . info_ctr - > level ) ;
2010-01-06 21:33:39 +03:00
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_SetPrinter_r ( b , tctx , & r ) ,
2010-01-06 21:33:39 +03:00
" failed to call SetPrinter " ) ;
2013-05-29 12:43:35 +04:00
torture_assert ( tctx , ( W_ERROR_EQUAL ( r . out . result , WERR_OK )
| | W_ERROR_EQUAL ( r . out . result , WERR_IO_PENDING ) ) ,
" SetPrinter failed " ) ;
2010-01-06 21:33:39 +03:00
return true ;
}
2009-07-02 21:38:12 +04:00
static bool test_SetPrinter_errors ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-07-02 21:38:12 +04:00
struct policy_handle * handle )
{
struct spoolss_SetPrinter r ;
uint16_t levels [ ] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } ;
int i ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
info_ctr . level = 0 ;
info_ctr . info . info0 = NULL ;
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
r . in . handle = handle ;
r . in . info_ctr = & info_ctr ;
r . in . devmode_ctr = & devmode_ctr ;
r . in . secdesc_ctr = & secdesc_ctr ;
r . in . command = 0 ;
torture_comment ( tctx , " Testing SetPrinter all zero \n " ) ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_SetPrinter_r ( b , tctx , & r ) ,
2009-07-02 21:38:12 +04:00
" failed to call SetPrinter " ) ;
2015-12-03 17:24:27 +03:00
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_PARAMETER ,
2009-07-02 21:38:12 +04:00
" failed to call SetPrinter " ) ;
again :
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
struct spoolss_SetPrinterInfo0 info0 ;
struct spoolss_SetPrinterInfo1 info1 ;
struct spoolss_SetPrinterInfo2 info2 ;
struct spoolss_SetPrinterInfo3 info3 ;
struct spoolss_SetPrinterInfo4 info4 ;
struct spoolss_SetPrinterInfo5 info5 ;
struct spoolss_SetPrinterInfo6 info6 ;
struct spoolss_SetPrinterInfo7 info7 ;
2009-12-16 12:33:41 +03:00
struct spoolss_SetPrinterInfo8 info8 ;
struct spoolss_SetPrinterInfo9 info9 ;
2009-07-02 21:38:12 +04:00
info_ctr . level = levels [ i ] ;
switch ( levels [ i ] ) {
case 0 :
ZERO_STRUCT ( info0 ) ;
info_ctr . info . info0 = & info0 ;
break ;
case 1 :
ZERO_STRUCT ( info1 ) ;
info_ctr . info . info1 = & info1 ;
break ;
case 2 :
ZERO_STRUCT ( info2 ) ;
info_ctr . info . info2 = & info2 ;
break ;
case 3 :
ZERO_STRUCT ( info3 ) ;
info_ctr . info . info3 = & info3 ;
break ;
case 4 :
ZERO_STRUCT ( info4 ) ;
info_ctr . info . info4 = & info4 ;
break ;
case 5 :
ZERO_STRUCT ( info5 ) ;
info_ctr . info . info5 = & info5 ;
break ;
case 6 :
ZERO_STRUCT ( info6 ) ;
info_ctr . info . info6 = & info6 ;
break ;
case 7 :
ZERO_STRUCT ( info7 ) ;
info_ctr . info . info7 = & info7 ;
break ;
case 8 :
ZERO_STRUCT ( info8 ) ;
info_ctr . info . info8 = & info8 ;
break ;
case 9 :
ZERO_STRUCT ( info9 ) ;
info_ctr . info . info9 = & info9 ;
break ;
}
torture_comment ( tctx , " Testing SetPrinter level %d, command %d \n " ,
info_ctr . level , r . in . command ) ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_SetPrinter_r ( b , tctx , & r ) ,
2009-07-02 21:38:12 +04:00
" failed to call SetPrinter " ) ;
switch ( r . in . command ) {
case SPOOLSS_PRINTER_CONTROL_UNPAUSE : /* 0 */
/* is ignored for all levels other then 0 */
if ( info_ctr . level > 0 ) {
/* ignored then */
break ;
}
2017-07-26 18:41:26 +03:00
FALL_THROUGH ;
2009-07-02 21:38:12 +04:00
case SPOOLSS_PRINTER_CONTROL_PAUSE : /* 1 */
case SPOOLSS_PRINTER_CONTROL_RESUME : /* 2 */
case SPOOLSS_PRINTER_CONTROL_PURGE : /* 3 */
if ( info_ctr . level > 0 ) {
/* is invalid for all levels other then 0 */
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_PRINTER_COMMAND ,
" unexpected error code returned " ) ;
continue ;
} else {
torture_assert_werr_ok ( tctx , r . out . result ,
" failed to call SetPrinter with non 0 command " ) ;
continue ;
}
break ;
case SPOOLSS_PRINTER_CONTROL_SET_STATUS : /* 4 */
/* FIXME: gd needs further investigation */
default :
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_PRINTER_COMMAND ,
" unexpected error code returned " ) ;
continue ;
}
switch ( info_ctr . level ) {
case 1 :
2015-12-03 17:24:43 +03:00
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_LEVEL ,
2009-07-02 21:38:12 +04:00
" unexpected error code returned " ) ;
break ;
case 2 :
torture_assert_werr_equal ( tctx , r . out . result , WERR_UNKNOWN_PRINTER_DRIVER ,
" unexpected error code returned " ) ;
break ;
case 3 :
case 4 :
case 5 :
case 7 :
2015-12-03 17:24:27 +03:00
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_PARAMETER ,
2009-07-02 21:38:12 +04:00
" unexpected error code returned " ) ;
break ;
case 9 :
torture_assert_werr_equal ( tctx , r . out . result , WERR_NOT_SUPPORTED ,
" unexpected error code returned " ) ;
break ;
default :
torture_assert_werr_ok ( tctx , r . out . result ,
" failed to call SetPrinter " ) ;
break ;
}
}
if ( r . in . command < 5 ) {
r . in . command + + ;
goto again ;
}
return true ;
}
static void clear_info2 ( struct spoolss_SetPrinterInfoCtr * r )
{
if ( ( r - > level = = 2 ) & & ( r - > info . info2 ) ) {
2016-11-11 18:29:20 +03:00
r - > info . info2 - > secdesc_ptr = 0 ;
r - > info . info2 - > devmode_ptr = 0 ;
2009-07-02 21:38:12 +04:00
}
}
static bool test_PrinterInfo ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-07-02 21:38:12 +04:00
struct policy_handle * handle )
{
NTSTATUS status ;
struct spoolss_SetPrinter s ;
struct spoolss_GetPrinter q ;
struct spoolss_GetPrinter q0 ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
union spoolss_PrinterInfo info ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
uint32_t needed ;
bool ret = true ;
int i ;
uint32_t status_list [ ] = {
/* these do not stick
PRINTER_STATUS_PAUSED ,
PRINTER_STATUS_ERROR ,
PRINTER_STATUS_PENDING_DELETION , */
PRINTER_STATUS_PAPER_JAM ,
PRINTER_STATUS_PAPER_OUT ,
PRINTER_STATUS_MANUAL_FEED ,
PRINTER_STATUS_PAPER_PROBLEM ,
PRINTER_STATUS_OFFLINE ,
PRINTER_STATUS_IO_ACTIVE ,
PRINTER_STATUS_BUSY ,
PRINTER_STATUS_PRINTING ,
PRINTER_STATUS_OUTPUT_BIN_FULL ,
PRINTER_STATUS_NOT_AVAILABLE ,
PRINTER_STATUS_WAITING ,
PRINTER_STATUS_PROCESSING ,
PRINTER_STATUS_INITIALIZING ,
PRINTER_STATUS_WARMING_UP ,
PRINTER_STATUS_TONER_LOW ,
PRINTER_STATUS_NO_TONER ,
PRINTER_STATUS_PAGE_PUNT ,
PRINTER_STATUS_USER_INTERVENTION ,
PRINTER_STATUS_OUT_OF_MEMORY ,
PRINTER_STATUS_DOOR_OPEN ,
PRINTER_STATUS_SERVER_UNKNOWN ,
PRINTER_STATUS_POWER_SAVE ,
/* these do not stick
0x02000000 ,
0x04000000 ,
0x08000000 ,
0x10000000 ,
0x20000000 ,
0x40000000 ,
0x80000000 */
} ;
uint32_t default_attribute = PRINTER_ATTRIBUTE_LOCAL ;
uint32_t attribute_list [ ] = {
PRINTER_ATTRIBUTE_QUEUED ,
/* fails with WERR_INVALID_DATATYPE:
PRINTER_ATTRIBUTE_DIRECT , */
/* does not stick
PRINTER_ATTRIBUTE_DEFAULT , */
PRINTER_ATTRIBUTE_SHARED ,
/* does not stick
PRINTER_ATTRIBUTE_NETWORK , */
PRINTER_ATTRIBUTE_HIDDEN ,
PRINTER_ATTRIBUTE_LOCAL ,
PRINTER_ATTRIBUTE_ENABLE_DEVQ ,
PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS ,
PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST ,
PRINTER_ATTRIBUTE_WORK_OFFLINE ,
/* does not stick
PRINTER_ATTRIBUTE_ENABLE_BIDI , */
/* fails with WERR_INVALID_DATATYPE:
PRINTER_ATTRIBUTE_RAW_ONLY , */
/* these do not stick
PRINTER_ATTRIBUTE_PUBLISHED ,
PRINTER_ATTRIBUTE_FAX ,
PRINTER_ATTRIBUTE_TS ,
0x00010000 ,
0x00020000 ,
0x00040000 ,
0x00080000 ,
0x00100000 ,
0x00200000 ,
0x00400000 ,
0x00800000 ,
0x01000000 ,
0x02000000 ,
0x04000000 ,
0x08000000 ,
0x10000000 ,
0x20000000 ,
0x40000000 ,
0x80000000 */
} ;
2013-12-04 17:01:51 +04:00
torture_skip ( tctx , " Printer Info test is currently broken, skipping " ) ;
2009-07-02 21:38:12 +04:00
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
s . in . handle = handle ;
s . in . command = 0 ;
s . in . info_ctr = & info_ctr ;
s . in . devmode_ctr = & devmode_ctr ;
s . in . secdesc_ctr = & secdesc_ctr ;
q . in . handle = handle ;
q . out . info = & info ;
q0 = q ;
# define TESTGETCALL(call, r) \
r . in . buffer = NULL ; \
r . in . offered = 0 ; \
r . out . needed = & needed ; \
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_ # # call # # _r ( b , tctx , & r ) ; \
2009-07-02 21:38:12 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) { \
torture_comment ( tctx , # call " level %u failed - %s (%s) \n " , \
r . in . level , nt_errstr ( status ) , __location__ ) ; \
ret = false ; \
break ; \
} \
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) { \
2010-04-08 13:56:27 +04:00
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ; \
2009-07-02 21:38:12 +04:00
r . in . buffer = & blob ; \
r . in . offered = needed ; \
} \
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_ # # call # # _r ( b , tctx , & r ) ; \
2009-07-02 21:38:12 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) { \
torture_comment ( tctx , # call " level %u failed - %s (%s) \n " , \
r . in . level , nt_errstr ( status ) , __location__ ) ; \
ret = false ; \
break ; \
} \
if ( ! W_ERROR_IS_OK ( r . out . result ) ) { \
torture_comment ( tctx , # call " level %u failed - %s (%s) \n " , \
r . in . level , win_errstr ( r . out . result ) , __location__ ) ; \
ret = false ; \
break ; \
}
# define TESTSETCALL_EXP(call, r, err) \
clear_info2 ( & info_ctr ) ; \
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_ # # call # # _r ( b , tctx , & r ) ; \
2009-07-02 21:38:12 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) { \
torture_comment ( tctx , # call " level %u failed - %s (%s) \n " , \
r . in . info_ctr - > level , nt_errstr ( status ) , __location__ ) ; \
ret = false ; \
break ; \
} \
if ( ! W_ERROR_IS_OK ( err ) ) { \
if ( ! W_ERROR_EQUAL ( err , r . out . result ) ) { \
torture_comment ( tctx , # call " level %u failed - %s, expected %s (%s) \n " , \
r . in . info_ctr - > level , win_errstr ( r . out . result ) , win_errstr ( err ) , __location__ ) ; \
ret = false ; \
} \
break ; \
} \
if ( ! W_ERROR_IS_OK ( r . out . result ) ) { \
torture_comment ( tctx , # call " level %u failed - %s (%s) \n " , \
r . in . info_ctr - > level , win_errstr ( r . out . result ) , __location__ ) ; \
ret = false ; \
break ; \
}
# define TESTSETCALL(call, r) \
TESTSETCALL_EXP ( call , r , WERR_OK )
# define STRING_EQUAL(s1, s2, field) \
if ( ( s1 & & ! s2 ) | | ( s2 & & ! s1 ) | | strcmp ( s1 , s2 ) ) { \
torture_comment ( tctx , " Failed to set %s to '%s' (%s) \n " , \
# field, s2, __location__); \
ret = false ; \
break ; \
}
# define MEM_EQUAL(s1, s2, length, field) \
if ( ( s1 & & ! s2 ) | | ( s2 & & ! s1 ) | | memcmp ( s1 , s2 , length ) ) { \
torture_comment ( tctx , " Failed to set %s to '%s' (%s) \n " , \
# field, (const char *)s2, __location__); \
ret = false ; \
break ; \
}
# define INT_EQUAL(i1, i2, field) \
if ( i1 ! = i2 ) { \
torture_comment ( tctx , " Failed to set %s to 0x%llx - got 0x%llx (%s) \n " , \
# field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
ret = false ; \
break ; \
}
2010-02-13 04:11:31 +03:00
# define SD_EQUAL(sd1, sd2, field) \
if ( ! security_descriptor_equal ( sd1 , sd2 ) ) { \
torture_comment ( tctx , " Failed to set %s (%s) \n " , \
# field, __location__); \
ret = false ; \
break ; \
}
2009-07-02 21:38:12 +04:00
# define TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, err) do { \
2014-02-04 12:52:49 +04:00
void * p ; \
2009-07-02 21:38:12 +04:00
torture_comment ( tctx , " field test %d/%s vs %d/%s \n " , lvl1 , # field1 , lvl2 , # field2 ) ; \
q . in . level = lvl1 ; \
TESTGETCALL ( GetPrinter , q ) \
info_ctr . level = lvl1 ; \
2014-02-04 12:52:49 +04:00
p = ( void * ) & q . out . info - > info # # lvl1 ; \
info_ctr . info . info # # lvl1 = ( struct spoolss_SetPrinterInfo # # lvl1 * ) p ; \
2009-07-02 21:38:12 +04:00
info_ctr . info . info # # lvl1 - > field1 = value ; \
TESTSETCALL_EXP ( SetPrinter , s , err ) \
info_ctr . info . info # # lvl1 - > field1 = " " ; \
TESTGETCALL ( GetPrinter , q ) \
info_ctr . info . info # # lvl1 - > field1 = value ; \
STRING_EQUAL ( info_ctr . info . info # # lvl1 - > field1 , value , field1 ) ; \
q . in . level = lvl2 ; \
TESTGETCALL ( GetPrinter , q ) \
2014-02-04 12:52:49 +04:00
p = ( void * ) & q . out . info - > info # # lvl2 ; \
info_ctr . info . info # # lvl2 = ( struct spoolss_SetPrinterInfo # # lvl2 * ) p ; \
2009-07-02 21:38:12 +04:00
STRING_EQUAL ( info_ctr . info . info # # lvl2 - > field2 , value , field2 ) ; \
} while ( 0 )
# define TEST_PRINTERINFO_STRING(lvl1, field1, lvl2, field2, value) do { \
TEST_PRINTERINFO_STRING_EXP_ERR ( lvl1 , field1 , lvl2 , field2 , value , WERR_OK ) ; \
} while ( 0 ) ;
# define TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value) do { \
2014-02-04 12:52:49 +04:00
void * p ; \
2009-07-02 21:38:12 +04:00
torture_comment ( tctx , " field test %d/%s vs %d/%s \n " , lvl1 , # field1 , lvl2 , # field2 ) ; \
q . in . level = lvl1 ; \
TESTGETCALL ( GetPrinter , q ) \
info_ctr . level = lvl1 ; \
2014-02-04 12:52:49 +04:00
p = ( void * ) & q . out . info - > info # # lvl1 ; \
info_ctr . info . info # # lvl1 = ( struct spoolss_SetPrinterInfo # # lvl1 * ) p ; \
2009-07-02 21:38:12 +04:00
info_ctr . info . info # # lvl1 - > field1 = value ; \
TESTSETCALL ( SetPrinter , s ) \
info_ctr . info . info # # lvl1 - > field1 = 0 ; \
TESTGETCALL ( GetPrinter , q ) \
2014-02-04 12:52:49 +04:00
p = ( void * ) & q . out . info - > info # # lvl1 ; \
info_ctr . info . info # # lvl1 = ( struct spoolss_SetPrinterInfo # # lvl1 * ) p ; \
2009-07-02 21:38:12 +04:00
INT_EQUAL ( info_ctr . info . info # # lvl1 - > field1 , exp_value , field1 ) ; \
q . in . level = lvl2 ; \
TESTGETCALL ( GetPrinter , q ) \
2014-02-04 12:52:49 +04:00
p = ( void * ) & q . out . info - > info # # lvl2 ; \
info_ctr . info . info # # lvl2 = ( struct spoolss_SetPrinterInfo # # lvl2 * ) p ; \
2009-07-02 21:38:12 +04:00
INT_EQUAL ( info_ctr . info . info # # lvl2 - > field2 , exp_value , field1 ) ; \
} while ( 0 )
# define TEST_PRINTERINFO_INT(lvl1, field1, lvl2, field2, value) do { \
TEST_PRINTERINFO_INT_EXP ( lvl1 , field1 , lvl2 , field2 , value , value ) ; \
} while ( 0 )
q0 . in . level = 0 ;
do { TESTGETCALL ( GetPrinter , q0 ) } while ( 0 ) ;
TEST_PRINTERINFO_STRING ( 2 , comment , 1 , comment , " xx2-1 comment " ) ;
TEST_PRINTERINFO_STRING ( 2 , comment , 2 , comment , " xx2-2 comment " ) ;
/* level 0 printername does not stick */
/* TEST_PRINTERINFO_STRING(2, printername, 0, printername, "xx2-0 printer"); */
TEST_PRINTERINFO_STRING ( 2 , printername , 1 , name , " xx2-1 printer " ) ;
TEST_PRINTERINFO_STRING ( 2 , printername , 2 , printername , " xx2-2 printer " ) ;
TEST_PRINTERINFO_STRING ( 2 , printername , 4 , printername , " xx2-4 printer " ) ;
TEST_PRINTERINFO_STRING ( 2 , printername , 5 , printername , " xx2-5 printer " ) ;
/* TEST_PRINTERINFO_STRING(4, printername, 0, printername, "xx4-0 printer"); */
TEST_PRINTERINFO_STRING ( 4 , printername , 1 , name , " xx4-1 printer " ) ;
TEST_PRINTERINFO_STRING ( 4 , printername , 2 , printername , " xx4-2 printer " ) ;
TEST_PRINTERINFO_STRING ( 4 , printername , 4 , printername , " xx4-4 printer " ) ;
TEST_PRINTERINFO_STRING ( 4 , printername , 5 , printername , " xx4-5 printer " ) ;
/* TEST_PRINTERINFO_STRING(5, printername, 0, printername, "xx5-0 printer"); */
TEST_PRINTERINFO_STRING ( 5 , printername , 1 , name , " xx5-1 printer " ) ;
TEST_PRINTERINFO_STRING ( 5 , printername , 2 , printername , " xx5-2 printer " ) ;
TEST_PRINTERINFO_STRING ( 5 , printername , 4 , printername , " xx5-4 printer " ) ;
TEST_PRINTERINFO_STRING ( 5 , printername , 5 , printername , " xx5-5 printer " ) ;
/* servername can be set but does not stick
TEST_PRINTERINFO_STRING ( 2 , servername , 0 , servername , " xx2-0 servername " ) ;
TEST_PRINTERINFO_STRING ( 2 , servername , 2 , servername , " xx2-2 servername " ) ;
TEST_PRINTERINFO_STRING ( 2 , servername , 4 , servername , " xx2-4 servername " ) ;
*/
/* passing an invalid port will result in WERR_UNKNOWN_PORT */
TEST_PRINTERINFO_STRING_EXP_ERR ( 2 , portname , 2 , portname , " xx2-2 portname " , WERR_UNKNOWN_PORT ) ;
TEST_PRINTERINFO_STRING_EXP_ERR ( 2 , portname , 5 , portname , " xx2-5 portname " , WERR_UNKNOWN_PORT ) ;
TEST_PRINTERINFO_STRING_EXP_ERR ( 5 , portname , 2 , portname , " xx5-2 portname " , WERR_UNKNOWN_PORT ) ;
TEST_PRINTERINFO_STRING_EXP_ERR ( 5 , portname , 5 , portname , " xx5-5 portname " , WERR_UNKNOWN_PORT ) ;
TEST_PRINTERINFO_STRING ( 2 , sharename , 2 , sharename , " xx2-2 sharename " ) ;
/* passing an invalid driver will result in WERR_UNKNOWN_PRINTER_DRIVER */
TEST_PRINTERINFO_STRING_EXP_ERR ( 2 , drivername , 2 , drivername , " xx2-2 drivername " , WERR_UNKNOWN_PRINTER_DRIVER ) ;
TEST_PRINTERINFO_STRING ( 2 , location , 2 , location , " xx2-2 location " ) ;
/* passing an invalid sepfile will result in WERR_INVALID_SEPARATOR_FILE */
TEST_PRINTERINFO_STRING_EXP_ERR ( 2 , sepfile , 2 , sepfile , " xx2-2 sepfile " , WERR_INVALID_SEPARATOR_FILE ) ;
/* passing an invalid printprocessor will result in WERR_UNKNOWN_PRINTPROCESSOR */
TEST_PRINTERINFO_STRING_EXP_ERR ( 2 , printprocessor , 2 , printprocessor , " xx2-2 printprocessor " , WERR_UNKNOWN_PRINTPROCESSOR ) ;
TEST_PRINTERINFO_STRING ( 2 , datatype , 2 , datatype , " xx2-2 datatype " ) ;
TEST_PRINTERINFO_STRING ( 2 , parameters , 2 , parameters , " xx2-2 parameters " ) ;
for ( i = 0 ; i < ARRAY_SIZE ( attribute_list ) ; i + + ) {
/* TEST_PRINTERINFO_INT_EXP(2, attributes, 1, flags,
attribute_list [ i ] ,
( attribute_list [ i ] | default_attribute )
) ; */
TEST_PRINTERINFO_INT_EXP ( 2 , attributes , 2 , attributes ,
attribute_list [ i ] ,
( attribute_list [ i ] | default_attribute )
) ;
TEST_PRINTERINFO_INT_EXP ( 2 , attributes , 4 , attributes ,
attribute_list [ i ] ,
( attribute_list [ i ] | default_attribute )
) ;
TEST_PRINTERINFO_INT_EXP ( 2 , attributes , 5 , attributes ,
attribute_list [ i ] ,
( attribute_list [ i ] | default_attribute )
) ;
/* TEST_PRINTERINFO_INT_EXP(4, attributes, 1, flags,
attribute_list [ i ] ,
( attribute_list [ i ] | default_attribute )
) ; */
TEST_PRINTERINFO_INT_EXP ( 4 , attributes , 2 , attributes ,
attribute_list [ i ] ,
( attribute_list [ i ] | default_attribute )
) ;
TEST_PRINTERINFO_INT_EXP ( 4 , attributes , 4 , attributes ,
attribute_list [ i ] ,
( attribute_list [ i ] | default_attribute )
) ;
TEST_PRINTERINFO_INT_EXP ( 4 , attributes , 5 , attributes ,
attribute_list [ i ] ,
( attribute_list [ i ] | default_attribute )
) ;
/* TEST_PRINTERINFO_INT_EXP(5, attributes, 1, flags,
attribute_list [ i ] ,
( attribute_list [ i ] | default_attribute )
) ; */
TEST_PRINTERINFO_INT_EXP ( 5 , attributes , 2 , attributes ,
attribute_list [ i ] ,
( attribute_list [ i ] | default_attribute )
) ;
TEST_PRINTERINFO_INT_EXP ( 5 , attributes , 4 , attributes ,
attribute_list [ i ] ,
( attribute_list [ i ] | default_attribute )
) ;
TEST_PRINTERINFO_INT_EXP ( 5 , attributes , 5 , attributes ,
attribute_list [ i ] ,
( attribute_list [ i ] | default_attribute )
) ;
}
for ( i = 0 ; i < ARRAY_SIZE ( status_list ) ; i + + ) {
/* level 2 sets do not stick
TEST_PRINTERINFO_INT ( 2 , status , 0 , status , status_list [ i ] ) ;
TEST_PRINTERINFO_INT ( 2 , status , 2 , status , status_list [ i ] ) ;
TEST_PRINTERINFO_INT ( 2 , status , 6 , status , status_list [ i ] ) ; */
TEST_PRINTERINFO_INT ( 6 , status , 0 , status , status_list [ i ] ) ;
TEST_PRINTERINFO_INT ( 6 , status , 2 , status , status_list [ i ] ) ;
TEST_PRINTERINFO_INT ( 6 , status , 6 , status , status_list [ i ] ) ;
}
/* priorities need to be between 0 and 99
passing an invalid priority will result in WERR_INVALID_PRIORITY */
TEST_PRINTERINFO_INT ( 2 , priority , 2 , priority , 0 ) ;
TEST_PRINTERINFO_INT ( 2 , priority , 2 , priority , 1 ) ;
TEST_PRINTERINFO_INT ( 2 , priority , 2 , priority , 99 ) ;
/* TEST_PRINTERINFO_INT(2, priority, 2, priority, 100); */
TEST_PRINTERINFO_INT ( 2 , defaultpriority , 2 , defaultpriority , 0 ) ;
TEST_PRINTERINFO_INT ( 2 , defaultpriority , 2 , defaultpriority , 1 ) ;
TEST_PRINTERINFO_INT ( 2 , defaultpriority , 2 , defaultpriority , 99 ) ;
/* TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 100); */
TEST_PRINTERINFO_INT ( 2 , starttime , 2 , starttime , __LINE__ ) ;
TEST_PRINTERINFO_INT ( 2 , untiltime , 2 , untiltime , __LINE__ ) ;
/* does not stick
TEST_PRINTERINFO_INT ( 2 , cjobs , 2 , cjobs , __LINE__ ) ;
TEST_PRINTERINFO_INT ( 2 , averageppm , 2 , averageppm , __LINE__ ) ; */
/* does not stick
TEST_PRINTERINFO_INT ( 5 , device_not_selected_timeout , 5 , device_not_selected_timeout , __LINE__ ) ;
TEST_PRINTERINFO_INT ( 5 , transmission_retry_timeout , 5 , transmission_retry_timeout , __LINE__ ) ; */
/* FIXME: gd also test devmode and secdesc behavior */
{
/* verify composition of level 1 description field */
const char * description ;
const char * tmp ;
q0 . in . level = 1 ;
do { TESTGETCALL ( GetPrinter , q0 ) } while ( 0 ) ;
description = talloc_strdup ( tctx , q0 . out . info - > info1 . description ) ;
q0 . in . level = 2 ;
do { TESTGETCALL ( GetPrinter , q0 ) } while ( 0 ) ;
tmp = talloc_asprintf ( tctx , " %s,%s,%s " ,
q0 . out . info - > info2 . printername ,
q0 . out . info - > info2 . drivername ,
q0 . out . info - > info2 . location ) ;
do { STRING_EQUAL ( description , tmp , " description " ) } while ( 0 ) ;
}
return ret ;
}
2010-02-13 04:11:31 +03:00
static bool test_security_descriptor_equal ( struct torture_context * tctx ,
const struct security_descriptor * sd1 ,
const struct security_descriptor * sd2 )
{
if ( sd1 = = sd2 ) {
return true ;
}
if ( ! sd1 | | ! sd2 ) {
torture_comment ( tctx , " %s \n " , __location__ ) ;
return false ;
}
torture_assert_int_equal ( tctx , sd1 - > revision , sd2 - > revision , " revision mismatch " ) ;
torture_assert_int_equal ( tctx , sd1 - > type , sd2 - > type , " type mismatch " ) ;
torture_assert_sid_equal ( tctx , sd1 - > owner_sid , sd2 - > owner_sid , " owner mismatch " ) ;
torture_assert_sid_equal ( tctx , sd1 - > group_sid , sd2 - > group_sid , " group mismatch " ) ;
if ( ! security_acl_equal ( sd1 - > sacl , sd2 - > sacl ) ) {
torture_comment ( tctx , " %s: sacl mismatch \n " , __location__ ) ;
NDR_PRINT_DEBUG ( security_acl , sd1 - > sacl ) ;
NDR_PRINT_DEBUG ( security_acl , sd2 - > sacl ) ;
return false ;
}
if ( ! security_acl_equal ( sd1 - > dacl , sd2 - > dacl ) ) {
torture_comment ( tctx , " %s: dacl mismatch \n " , __location__ ) ;
NDR_PRINT_DEBUG ( security_acl , sd1 - > dacl ) ;
NDR_PRINT_DEBUG ( security_acl , sd2 - > dacl ) ;
return false ;
}
return true ;
}
static bool test_sd_set_level ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-02-13 04:11:31 +03:00
struct policy_handle * handle ,
uint32_t level ,
struct security_descriptor * sd )
{
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
2010-03-15 14:38:17 +03:00
union spoolss_SetPrinterInfo sinfo ;
2014-02-28 20:30:52 +04:00
union spoolss_PrinterInfo info ;
struct spoolss_SetPrinterInfo3 info3 ;
2010-02-13 04:11:31 +03:00
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
switch ( level ) {
case 2 : {
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) , " " ) ;
2010-03-15 14:38:17 +03:00
torture_assert ( tctx , PrinterInfo_to_SetPrinterInfo ( tctx , & info , 2 , & sinfo ) , " " ) ;
2010-02-13 04:11:31 +03:00
info_ctr . level = 2 ;
2010-03-15 14:38:17 +03:00
info_ctr . info = sinfo ;
2010-02-13 04:11:31 +03:00
break ;
}
case 3 : {
2016-11-11 18:29:20 +03:00
info3 . sec_desc_ptr = 0 ;
2010-02-13 04:11:31 +03:00
info_ctr . level = 3 ;
info_ctr . info . info3 = & info3 ;
break ;
}
default :
return false ;
}
secdesc_ctr . sd = sd ;
2010-02-15 23:55:06 +03:00
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_SetPrinter ( tctx , b , handle , & info_ctr , & devmode_ctr , & secdesc_ctr , 0 ) , " " ) ;
2010-02-13 04:11:31 +03:00
return true ;
}
static bool test_PrinterInfo_SDs ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-02-13 04:11:31 +03:00
struct policy_handle * handle )
{
union spoolss_PrinterInfo info ;
struct security_descriptor * sd1 , * sd2 ;
int i ;
2010-02-16 00:06:42 +03:00
/* just compare level 2 and level 3 */
2010-02-13 04:11:31 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) , " " ) ;
2010-02-13 04:11:31 +03:00
2010-02-16 00:06:42 +03:00
sd1 = info . info2 . secdesc ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 3 , & info ) , " " ) ;
2010-02-16 00:06:42 +03:00
sd2 = info . info3 . secdesc ;
2010-02-19 16:27:31 +03:00
torture_assert ( tctx , test_security_descriptor_equal ( tctx , sd1 , sd2 ) ,
" SD level 2 != SD level 3 " ) ;
2010-02-16 00:06:42 +03:00
/* query level 2, set level 2, query level 2 */
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) , " " ) ;
2010-02-16 00:06:42 +03:00
sd1 = info . info2 . secdesc ;
2010-02-13 04:11:31 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_sd_set_level ( tctx , b , handle , 2 , sd1 ) , " " ) ;
2010-02-13 04:11:31 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) , " " ) ;
2010-02-13 04:11:31 +03:00
2010-02-16 00:06:42 +03:00
sd2 = info . info2 . secdesc ;
2010-02-16 12:45:29 +03:00
if ( sd1 - > type & SEC_DESC_DACL_DEFAULTED ) {
torture_comment ( tctx , " removing SEC_DESC_DACL_DEFAULTED \n " ) ;
sd1 - > type & = ~ SEC_DESC_DACL_DEFAULTED ;
}
2010-02-16 00:06:42 +03:00
2010-02-19 16:27:31 +03:00
torture_assert ( tctx , test_security_descriptor_equal ( tctx , sd1 , sd2 ) ,
" SD level 2 != SD level 2 after SD has been set via level 2 " ) ;
2010-02-13 04:11:31 +03:00
2010-02-16 00:06:42 +03:00
/* query level 2, set level 3, query level 2 */
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) , " " ) ;
2010-02-16 00:06:42 +03:00
sd1 = info . info2 . secdesc ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_sd_set_level ( tctx , b , handle , 3 , sd1 ) , " " ) ;
2010-02-16 00:06:42 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) , " " ) ;
2010-02-16 00:06:42 +03:00
sd2 = info . info2 . secdesc ;
2010-02-13 04:11:31 +03:00
2010-02-19 16:27:31 +03:00
torture_assert ( tctx , test_security_descriptor_equal ( tctx , sd1 , sd2 ) ,
" SD level 2 != SD level 2 after SD has been set via level 3 " ) ;
2010-02-13 04:11:31 +03:00
2010-02-16 00:06:42 +03:00
/* set modified sd level 3, query level 2 */
2010-02-13 04:11:31 +03:00
for ( i = 0 ; i < 93 ; i + + ) {
struct security_ace a ;
const char * sid_string = talloc_asprintf ( tctx , " S-1-5-32-9999%i " , i ) ;
a . type = SEC_ACE_TYPE_ACCESS_ALLOWED ;
a . flags = 0 ;
a . size = 0 ; /* autogenerated */
a . access_mask = 0 ;
a . trustee = * dom_sid_parse_talloc ( tctx , sid_string ) ;
torture_assert_ntstatus_ok ( tctx , security_descriptor_dacl_add ( sd1 , & a ) , " " ) ;
}
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_sd_set_level ( tctx , b , handle , 3 , sd1 ) , " " ) ;
2010-02-13 04:11:31 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) , " " ) ;
2010-02-16 00:06:42 +03:00
sd2 = info . info2 . secdesc ;
if ( sd1 - > type & SEC_DESC_DACL_DEFAULTED ) {
torture_comment ( tctx , " removing SEC_DESC_DACL_DEFAULTED \n " ) ;
sd1 - > type & = ~ SEC_DESC_DACL_DEFAULTED ;
}
2010-02-13 04:11:31 +03:00
2010-02-19 16:27:31 +03:00
torture_assert ( tctx , test_security_descriptor_equal ( tctx , sd1 , sd2 ) ,
" modified SD level 2 != SD level 2 after SD has been set via level 3 " ) ;
2010-02-13 04:11:31 +03:00
return true ;
}
/*
* wrapper call that saves original sd , runs tests , and restores sd
*/
static bool test_PrinterInfo_SD ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-02-13 04:11:31 +03:00
struct policy_handle * handle )
{
union spoolss_PrinterInfo info ;
struct security_descriptor * sd ;
bool ret = true ;
2010-03-16 15:52:48 +03:00
torture_comment ( tctx , " Testing Printer Security Descriptors \n " ) ;
2010-02-19 16:14:18 +03:00
2010-02-13 04:11:31 +03:00
/* save original sd */
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) ,
2010-02-19 16:14:18 +03:00
" failed to get initial security descriptor " ) ;
2010-02-13 04:11:31 +03:00
sd = security_descriptor_copy ( tctx , info . info2 . secdesc ) ;
/* run tests */
2010-03-16 13:45:51 +03:00
ret = test_PrinterInfo_SDs ( tctx , b , handle ) ;
2010-02-13 04:11:31 +03:00
/* restore original sd */
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_sd_set_level ( tctx , b , handle , 3 , sd ) ,
2010-02-19 16:14:18 +03:00
" failed to restore initial security descriptor " ) ;
2010-02-13 04:11:31 +03:00
2010-03-16 15:52:48 +03:00
torture_comment ( tctx , " Printer Security Descriptors test %s \n \n " ,
2010-02-19 16:14:18 +03:00
ret ? " succeeded " : " failed " ) ;
2010-02-13 04:11:31 +03:00
return ret ;
}
2003-11-17 07:56:59 +03:00
2010-02-16 19:42:19 +03:00
static bool test_devmode_set_level ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-02-16 19:42:19 +03:00
struct policy_handle * handle ,
uint32_t level ,
struct spoolss_DeviceMode * devmode )
{
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
2010-03-15 14:38:17 +03:00
union spoolss_SetPrinterInfo sinfo ;
2010-02-16 19:42:19 +03:00
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
switch ( level ) {
case 2 : {
union spoolss_PrinterInfo info ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) , " " ) ;
2010-03-15 14:38:17 +03:00
torture_assert ( tctx , PrinterInfo_to_SetPrinterInfo ( tctx , & info , 2 , & sinfo ) , " " ) ;
2010-02-16 19:42:19 +03:00
info_ctr . level = 2 ;
2010-03-15 14:38:17 +03:00
info_ctr . info = sinfo ;
2010-02-16 19:42:19 +03:00
break ;
}
case 8 : {
struct spoolss_SetPrinterInfo8 info8 ;
2016-11-11 18:29:20 +03:00
info8 . devmode_ptr = 0 ;
2010-02-16 19:42:19 +03:00
info_ctr . level = 8 ;
info_ctr . info . info8 = & info8 ;
break ;
}
default :
return false ;
}
devmode_ctr . devmode = devmode ;
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_SetPrinter ( tctx , b , handle , & info_ctr , & devmode_ctr , & secdesc_ctr , 0 ) , " " ) ;
2010-02-16 19:42:19 +03:00
return true ;
}
2010-02-16 00:16:25 +03:00
static bool test_devicemode_equal ( struct torture_context * tctx ,
const struct spoolss_DeviceMode * d1 ,
const struct spoolss_DeviceMode * d2 )
{
if ( d1 = = d2 ) {
return true ;
}
if ( ! d1 | | ! d2 ) {
torture_comment ( tctx , " %s \n " , __location__ ) ;
return false ;
}
torture_assert_str_equal ( tctx , d1 - > devicename , d2 - > devicename , " devicename mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > specversion , d2 - > specversion , " specversion mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > driverversion , d2 - > driverversion , " driverversion mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > size , d2 - > size , " size mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > __driverextra_length , d2 - > __driverextra_length , " __driverextra_length mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > fields , d2 - > fields , " fields mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > orientation , d2 - > orientation , " orientation mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > papersize , d2 - > papersize , " papersize mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > paperlength , d2 - > paperlength , " paperlength mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > paperwidth , d2 - > paperwidth , " paperwidth mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > scale , d2 - > scale , " scale mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > copies , d2 - > copies , " copies mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > defaultsource , d2 - > defaultsource , " defaultsource mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > printquality , d2 - > printquality , " printquality mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > color , d2 - > color , " color mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > duplex , d2 - > duplex , " duplex mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > yresolution , d2 - > yresolution , " yresolution mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > ttoption , d2 - > ttoption , " ttoption mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > collate , d2 - > collate , " collate mismatch " ) ;
torture_assert_str_equal ( tctx , d1 - > formname , d2 - > formname , " formname mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > logpixels , d2 - > logpixels , " logpixels mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > bitsperpel , d2 - > bitsperpel , " bitsperpel mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > pelswidth , d2 - > pelswidth , " pelswidth mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > pelsheight , d2 - > pelsheight , " pelsheight mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > displayflags , d2 - > displayflags , " displayflags mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > displayfrequency , d2 - > displayfrequency , " displayfrequency mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > icmmethod , d2 - > icmmethod , " icmmethod mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > icmintent , d2 - > icmintent , " icmintent mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > mediatype , d2 - > mediatype , " mediatype mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > dithertype , d2 - > dithertype , " dithertype mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > reserved1 , d2 - > reserved1 , " reserved1 mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > reserved2 , d2 - > reserved2 , " reserved2 mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > panningwidth , d2 - > panningwidth , " panningwidth mismatch " ) ;
torture_assert_int_equal ( tctx , d1 - > panningheight , d2 - > panningheight , " panningheight mismatch " ) ;
torture_assert_data_blob_equal ( tctx , d1 - > driverextra_data , d2 - > driverextra_data , " driverextra_data mismatch " ) ;
return true ;
}
2010-02-25 15:11:47 +03:00
static bool test_devicemode_full ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-02-25 15:11:47 +03:00
struct policy_handle * handle )
{
struct spoolss_SetPrinter s ;
struct spoolss_GetPrinter q ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_SetPrinterInfo8 info8 ;
union spoolss_PrinterInfo info ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
uint32_t needed ;
bool ret = true ;
NTSTATUS status ;
2011-01-19 15:44:46 +03:00
# define TEST_DEVMODE_INT_EXP_RESULT(lvl1, field1, lvl2, field2, value, exp_value, expected_result) do { \
2010-02-25 15:11:47 +03:00
torture_comment ( tctx , " field test %d/%s vs %d/%s \n " , lvl1 , # field1 , lvl2 , # field2 ) ; \
q . in . level = lvl1 ; \
TESTGETCALL ( GetPrinter , q ) \
info_ctr . level = lvl1 ; \
if ( lvl1 = = 2 ) { \
2014-02-04 12:52:49 +04:00
void * p = ( void * ) & q . out . info - > info # # lvl1 ; \
info_ctr . info . info # # lvl1 = ( struct spoolss_SetPrinterInfo # # lvl1 * ) p ; \
2010-02-25 15:11:47 +03:00
} else if ( lvl1 = = 8 ) { \
info_ctr . info . info # # lvl1 = & info8 ; \
} \
devmode_ctr . devmode = q . out . info - > info # # lvl1 . devmode ; \
devmode_ctr . devmode - > field1 = value ; \
2011-01-19 15:44:46 +03:00
TESTSETCALL_EXP ( SetPrinter , s , expected_result ) \
if ( W_ERROR_IS_OK ( expected_result ) ) { \
TESTGETCALL ( GetPrinter , q ) \
INT_EQUAL ( q . out . info - > info # # lvl1 . devmode - > field1 , exp_value , field1 ) ; \
q . in . level = lvl2 ; \
TESTGETCALL ( GetPrinter , q ) \
INT_EQUAL ( q . out . info - > info # # lvl2 . devmode - > field2 , exp_value , field1 ) ; \
} \
2010-02-25 15:11:47 +03:00
} while ( 0 )
2011-01-19 15:44:46 +03:00
# define TEST_DEVMODE_INT_EXP(lvl1, field1, lvl2, field2, value, expected_result) do { \
TEST_DEVMODE_INT_EXP_RESULT ( lvl1 , field1 , lvl2 , field2 , value , value , expected_result ) ; \
} while ( 0 )
2010-02-25 15:11:47 +03:00
# define TEST_DEVMODE_INT(lvl1, field1, lvl2, field2, value) do { \
2011-01-19 15:44:46 +03:00
TEST_DEVMODE_INT_EXP_RESULT ( lvl1 , field1 , lvl2 , field2 , value , value , WERR_OK ) ; \
2010-02-25 15:11:47 +03:00
} while ( 0 )
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
ZERO_STRUCT ( info8 ) ;
s . in . handle = handle ;
s . in . command = 0 ;
s . in . info_ctr = & info_ctr ;
s . in . devmode_ctr = & devmode_ctr ;
s . in . secdesc_ctr = & secdesc_ctr ;
q . in . handle = handle ;
q . out . info = & info ;
#if 0
const char * devicename ; /* [charset(UTF16)] */
enum spoolss_DeviceModeSpecVersion specversion ;
uint16_t driverversion ;
uint16_t __driverextra_length ; /* [value(r->driverextra_data.length)] */
uint32_t fields ;
# endif
2015-12-03 17:24:27 +03:00
TEST_DEVMODE_INT_EXP ( 8 , size , 8 , size , __LINE__ , WERR_INVALID_PARAMETER ) ;
TEST_DEVMODE_INT_EXP ( 8 , size , 8 , size , 0 , WERR_INVALID_PARAMETER ) ;
TEST_DEVMODE_INT_EXP ( 8 , size , 8 , size , 0xffff , WERR_INVALID_PARAMETER ) ;
TEST_DEVMODE_INT_EXP ( 8 , size , 8 , size , ndr_size_spoolss_DeviceMode ( devmode_ctr . devmode , 0 ) , ( devmode_ctr . devmode - > __driverextra_length > 0 ) ? WERR_INVALID_PARAMETER : WERR_OK ) ;
2011-01-19 16:39:36 +03:00
TEST_DEVMODE_INT ( 8 , size , 8 , size , ndr_size_spoolss_DeviceMode ( devmode_ctr . devmode , 0 ) - devmode_ctr . devmode - > __driverextra_length ) ;
devmode_ctr . devmode - > driverextra_data = data_blob_string_const ( " foobar " ) ;
torture_assert ( tctx ,
test_devmode_set_level ( tctx , b , handle , 8 , devmode_ctr . devmode ) ,
" failed to set devmode " ) ;
2015-12-03 17:24:27 +03:00
TEST_DEVMODE_INT_EXP ( 8 , size , 8 , size , ndr_size_spoolss_DeviceMode ( devmode_ctr . devmode , 0 ) , ( devmode_ctr . devmode - > __driverextra_length > 0 ) ? WERR_INVALID_PARAMETER : WERR_OK ) ;
2011-01-19 15:48:17 +03:00
TEST_DEVMODE_INT ( 8 , size , 8 , size , ndr_size_spoolss_DeviceMode ( devmode_ctr . devmode , 0 ) - devmode_ctr . devmode - > __driverextra_length ) ;
2011-01-19 16:39:36 +03:00
2010-02-25 15:11:47 +03:00
TEST_DEVMODE_INT ( 8 , orientation , 8 , orientation , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , papersize , 8 , papersize , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , paperlength , 8 , paperlength , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , paperwidth , 8 , paperwidth , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , scale , 8 , scale , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , copies , 8 , copies , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , defaultsource , 8 , defaultsource , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , printquality , 8 , printquality , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , color , 8 , color , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , duplex , 8 , duplex , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , yresolution , 8 , yresolution , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , ttoption , 8 , ttoption , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , collate , 8 , collate , __LINE__ ) ;
#if 0
const char * formname ; /* [charset(UTF16)] */
# endif
TEST_DEVMODE_INT ( 8 , logpixels , 8 , logpixels , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , bitsperpel , 8 , bitsperpel , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , pelswidth , 8 , pelswidth , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , pelsheight , 8 , pelsheight , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , displayflags , 8 , displayflags , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , displayfrequency , 8 , displayfrequency , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , icmmethod , 8 , icmmethod , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , icmintent , 8 , icmintent , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , mediatype , 8 , mediatype , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , dithertype , 8 , dithertype , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , reserved1 , 8 , reserved1 , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , reserved2 , 8 , reserved2 , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , panningwidth , 8 , panningwidth , __LINE__ ) ;
TEST_DEVMODE_INT ( 8 , panningheight , 8 , panningheight , __LINE__ ) ;
return ret ;
}
2010-02-16 05:28:43 +03:00
static bool call_OpenPrinterEx ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
const char * name ,
struct spoolss_DeviceMode * devmode ,
struct policy_handle * handle ) ;
2010-02-16 00:16:25 +03:00
static bool test_PrinterInfo_DevModes ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
2010-02-16 05:28:43 +03:00
struct policy_handle * handle ,
const char * name )
2010-02-16 00:16:25 +03:00
{
union spoolss_PrinterInfo info ;
struct spoolss_DeviceMode * devmode ;
struct spoolss_DeviceMode * devmode2 ;
2010-02-16 05:28:43 +03:00
struct policy_handle handle_devmode ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-02-16 05:28:43 +03:00
/* simply compare level8 and level2 devmode */
2010-02-16 00:16:25 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 8 , & info ) , " " ) ;
2010-02-16 00:16:25 +03:00
devmode = info . info8 . devmode ;
2011-01-19 02:15:09 +03:00
if ( devmode & & devmode - > size = = 0 ) {
torture_fail ( tctx ,
" devmode of zero size! " ) ;
}
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) , " " ) ;
2010-02-16 00:16:25 +03:00
devmode2 = info . info2 . devmode ;
2011-01-19 02:15:09 +03:00
if ( devmode2 & & devmode2 - > size = = 0 ) {
torture_fail ( tctx ,
" devmode of zero size! " ) ;
}
2010-02-19 16:27:31 +03:00
torture_assert ( tctx , test_devicemode_equal ( tctx , devmode , devmode2 ) ,
" DM level 8 != DM level 2 " ) ;
2010-02-16 00:16:25 +03:00
2010-02-16 05:28:43 +03:00
2010-02-16 19:42:19 +03:00
/* set devicemode level 8 and see if it persists */
2010-02-16 05:28:43 +03:00
devmode - > copies = 93 ;
devmode - > formname = talloc_strdup ( tctx , " Legal " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_devmode_set_level ( tctx , b , handle , 8 , devmode ) , " " ) ;
2010-02-16 05:28:43 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 8 , & info ) , " " ) ;
2010-02-16 05:28:43 +03:00
devmode2 = info . info8 . devmode ;
2010-02-19 16:27:31 +03:00
torture_assert ( tctx , test_devicemode_equal ( tctx , devmode , devmode2 ) ,
" modified DM level 8 != DM level 8 after DM has been set via level 8 " ) ;
2010-02-16 05:28:43 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) , " " ) ;
2010-02-16 05:28:43 +03:00
devmode2 = info . info2 . devmode ;
2010-02-19 16:27:31 +03:00
torture_assert ( tctx , test_devicemode_equal ( tctx , devmode , devmode2 ) ,
" modified DM level 8 != DM level 2 " ) ;
2010-02-16 05:28:43 +03:00
2010-02-16 19:42:58 +03:00
/* set devicemode level 2 and see if it persists */
devmode - > copies = 39 ;
2010-02-19 17:25:42 +03:00
devmode - > formname = talloc_strdup ( tctx , " Executive " ) ;
2010-02-16 19:42:58 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_devmode_set_level ( tctx , b , handle , 2 , devmode ) , " " ) ;
2010-02-16 19:42:58 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 8 , & info ) , " " ) ;
2010-02-16 19:42:58 +03:00
devmode2 = info . info8 . devmode ;
2010-02-19 16:27:31 +03:00
torture_assert ( tctx , test_devicemode_equal ( tctx , devmode , devmode2 ) ,
" modified DM level 8 != DM level 8 after DM has been set via level 2 " ) ;
2010-02-16 19:42:58 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) , " " ) ;
2010-02-16 19:42:58 +03:00
devmode2 = info . info2 . devmode ;
2010-02-19 16:27:31 +03:00
torture_assert ( tctx , test_devicemode_equal ( tctx , devmode , devmode2 ) ,
" modified DM level 8 != DM level 2 " ) ;
2010-02-16 19:42:58 +03:00
2010-02-25 15:11:47 +03:00
/* check every single bit in public part of devicemode */
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_devicemode_full ( tctx , b , handle ) ,
2010-02-25 15:11:47 +03:00
" failed to set every single devicemode component " ) ;
2010-02-19 17:25:42 +03:00
/* change formname upon open and see if it persists in getprinter calls */
devmode - > formname = talloc_strdup ( tctx , " A4 " ) ;
devmode - > copies = 42 ;
torture_assert ( tctx , call_OpenPrinterEx ( tctx , p , name , devmode , & handle_devmode ) ,
" failed to open printer handle " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , & handle_devmode , 8 , & info ) , " " ) ;
2010-02-19 17:25:42 +03:00
devmode2 = info . info8 . devmode ;
if ( strequal ( devmode - > devicename , devmode2 - > devicename ) ) {
2010-03-13 04:26:59 +03:00
torture_warning ( tctx , " devicenames are the same \n " ) ;
2010-02-19 17:25:42 +03:00
} else {
torture_comment ( tctx , " devicename passed in for open: %s \n " , devmode - > devicename ) ;
torture_comment ( tctx , " devicename after level 8 get: %s \n " , devmode2 - > devicename ) ;
}
if ( strequal ( devmode - > formname , devmode2 - > formname ) ) {
torture_warning ( tctx , " formname are the same \n " ) ;
} else {
torture_comment ( tctx , " formname passed in for open: %s \n " , devmode - > formname ) ;
torture_comment ( tctx , " formname after level 8 get: %s \n " , devmode2 - > formname ) ;
}
if ( devmode - > copies = = devmode2 - > copies ) {
torture_warning ( tctx , " copies are the same \n " ) ;
} else {
torture_comment ( tctx , " copies passed in for open: %d \n " , devmode - > copies ) ;
torture_comment ( tctx , " copies after level 8 get: %d \n " , devmode2 - > copies ) ;
}
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , & handle_devmode , 2 , & info ) , " " ) ;
2010-02-19 17:25:42 +03:00
devmode2 = info . info2 . devmode ;
if ( strequal ( devmode - > devicename , devmode2 - > devicename ) ) {
2010-03-13 04:26:59 +03:00
torture_warning ( tctx , " devicenames are the same \n " ) ;
2010-02-19 17:25:42 +03:00
} else {
torture_comment ( tctx , " devicename passed in for open: %s \n " , devmode - > devicename ) ;
torture_comment ( tctx , " devicename after level 2 get: %s \n " , devmode2 - > devicename ) ;
}
if ( strequal ( devmode - > formname , devmode2 - > formname ) ) {
torture_warning ( tctx , " formname is the same \n " ) ;
} else {
torture_comment ( tctx , " formname passed in for open: %s \n " , devmode - > formname ) ;
torture_comment ( tctx , " formname after level 2 get: %s \n " , devmode2 - > formname ) ;
}
if ( devmode - > copies = = devmode2 - > copies ) {
torture_warning ( tctx , " copies are the same \n " ) ;
} else {
torture_comment ( tctx , " copies passed in for open: %d \n " , devmode - > copies ) ;
torture_comment ( tctx , " copies after level 2 get: %d \n " , devmode2 - > copies ) ;
}
2010-03-16 13:45:51 +03:00
test_ClosePrinter ( tctx , b , & handle_devmode ) ;
2010-02-19 17:25:42 +03:00
2010-02-16 00:16:25 +03:00
return true ;
}
/*
* wrapper call that saves original devmode , runs tests , and restores devmode
*/
static bool test_PrinterInfo_DevMode ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
2010-02-16 05:28:43 +03:00
struct policy_handle * handle ,
2010-04-28 19:00:53 +04:00
const char * name ,
struct spoolss_DeviceMode * addprinter_devmode )
2010-02-16 00:16:25 +03:00
{
union spoolss_PrinterInfo info ;
struct spoolss_DeviceMode * devmode ;
bool ret = true ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-02-16 00:16:25 +03:00
2010-03-16 15:52:48 +03:00
torture_comment ( tctx , " Testing Printer Devicemodes \n " ) ;
2010-02-19 16:14:18 +03:00
2010-02-16 00:16:25 +03:00
/* save original devmode */
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 8 , & info ) ,
2010-02-18 03:41:46 +03:00
" failed to get initial global devicemode " ) ;
2010-02-16 00:16:25 +03:00
devmode = info . info8 . devmode ;
2011-01-19 02:15:09 +03:00
if ( devmode & & devmode - > size = = 0 ) {
torture_fail ( tctx ,
" devmode of zero size! " ) ;
}
2010-04-28 19:00:53 +04:00
if ( addprinter_devmode ) {
if ( ! test_devicemode_equal ( tctx , devmode , addprinter_devmode ) ) {
torture_warning ( tctx , " current global DM is != DM provided in addprinter " ) ;
}
}
2010-02-16 00:16:25 +03:00
/* run tests */
2010-02-16 05:28:43 +03:00
ret = test_PrinterInfo_DevModes ( tctx , p , handle , name ) ;
2010-02-16 00:16:25 +03:00
/* restore original devmode */
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_devmode_set_level ( tctx , b , handle , 8 , devmode ) ,
2010-02-18 03:41:46 +03:00
" failed to restore initial global device mode " ) ;
2010-02-16 00:16:25 +03:00
2010-03-16 15:52:48 +03:00
torture_comment ( tctx , " Printer Devicemodes test %s \n \n " ,
2010-02-19 16:14:18 +03:00
ret ? " succeeded " : " failed " ) ;
2010-02-16 00:16:25 +03:00
return ret ;
}
2010-06-04 21:02:17 +04:00
bool test_ClosePrinter ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle )
2003-11-17 07:56:59 +03:00
{
NTSTATUS status ;
struct spoolss_ClosePrinter r ;
r . in . handle = handle ;
r . out . handle = handle ;
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing ClosePrinter \n " ) ;
2003-11-17 07:56:59 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_ClosePrinter_r ( b , tctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " ClosePrinter failed " ) ;
2009-12-04 00:38:38 +03:00
torture_assert_werr_ok ( tctx , r . out . result , " ClosePrinter failed " ) ;
2003-11-17 07:56:59 +03:00
2007-09-03 17:13:25 +04:00
return true ;
2003-11-17 07:56:59 +03:00
}
2010-04-06 15:23:22 +04:00
static bool test_GetForm_args ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * form_name ,
uint32_t level ,
union spoolss_FormInfo * info_p )
2003-11-26 09:26:18 +03:00
{
NTSTATUS status ;
struct spoolss_GetForm r ;
2009-02-06 15:09:22 +03:00
uint32_t needed ;
2003-11-26 09:26:18 +03:00
r . in . handle = handle ;
2005-04-04 19:19:27 +04:00
r . in . form_name = form_name ;
2009-02-25 23:10:44 +03:00
r . in . level = level ;
2003-11-26 09:26:18 +03:00
r . in . buffer = NULL ;
2005-06-14 19:52:31 +04:00
r . in . offered = 0 ;
2009-02-06 15:09:22 +03:00
r . out . needed = & needed ;
2003-11-26 09:26:18 +03:00
2010-04-06 15:23:22 +04:00
torture_comment ( tctx , " Testing GetForm(%s) level %d \n " , form_name , r . in . level ) ;
2003-11-26 09:26:18 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_GetForm_r ( b , tctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " GetForm failed " ) ;
2003-11-26 09:26:18 +03:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
2010-04-08 13:56:27 +04:00
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
2003-11-26 09:26:18 +03:00
r . in . buffer = & blob ;
2009-02-06 15:09:22 +03:00
r . in . offered = needed ;
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_GetForm_r ( b , tctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " GetForm failed " ) ;
2005-07-01 13:05:10 +04:00
2007-09-03 17:13:25 +04:00
torture_assert_werr_ok ( tctx , r . out . result , " GetForm failed " ) ;
2003-11-26 09:26:18 +03:00
2007-09-03 17:13:25 +04:00
torture_assert ( tctx , r . out . info , " No form info returned " ) ;
2003-11-26 09:26:18 +03:00
}
2007-09-03 17:13:25 +04:00
torture_assert_werr_ok ( tctx , r . out . result , " GetForm failed " ) ;
2005-07-01 13:05:10 +04:00
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_LEVEL ( spoolss_FormInfo , r . out . info , r . in . level , needed , 4 ) ;
2009-12-12 03:51:13 +03:00
2010-04-06 15:23:22 +04:00
if ( info_p ) {
* info_p = * r . out . info ;
}
2007-09-03 17:13:25 +04:00
return true ;
2003-11-26 09:26:18 +03:00
}
2010-04-06 15:23:22 +04:00
static bool test_GetForm ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * form_name ,
uint32_t level )
{
return test_GetForm_args ( tctx , b , handle , form_name , level , NULL ) ;
}
2009-06-30 13:38:41 +04:00
static bool test_EnumForms ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-04-06 15:23:22 +04:00
struct policy_handle * handle ,
bool print_server ,
uint32_t level ,
uint32_t * count_p ,
union spoolss_FormInfo * * info_p )
2003-11-26 09:26:18 +03:00
{
struct spoolss_EnumForms r ;
2009-02-06 19:09:30 +03:00
uint32_t needed ;
2009-02-16 18:42:21 +03:00
uint32_t count ;
2010-04-06 15:23:22 +04:00
union spoolss_FormInfo * info ;
2003-11-26 09:26:18 +03:00
2010-04-06 15:23:22 +04:00
r . in . handle = handle ;
r . in . level = level ;
r . in . buffer = NULL ;
r . in . offered = 0 ;
r . out . needed = & needed ;
r . out . count = & count ;
r . out . info = & info ;
2003-11-26 09:26:18 +03:00
2010-04-06 15:23:22 +04:00
torture_comment ( tctx , " Testing EnumForms level %d \n " , r . in . level ) ;
2009-03-02 19:32:24 +03:00
2010-04-06 15:23:22 +04:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_EnumForms_r ( b , tctx , & r ) ,
" EnumForms failed " ) ;
2003-11-26 09:26:18 +03:00
2015-12-03 17:24:43 +03:00
if ( ( r . in . level = = 2 ) & & ( W_ERROR_EQUAL ( r . out . result , WERR_INVALID_LEVEL ) ) ) {
2010-04-06 15:23:22 +04:00
torture_skip ( tctx , " EnumForms level 2 not supported " ) ;
}
2003-11-26 09:26:18 +03:00
2015-12-03 17:24:13 +03:00
if ( print_server & & W_ERROR_EQUAL ( r . out . result , WERR_INVALID_HANDLE ) ) {
2010-04-06 15:23:22 +04:00
torture_fail ( tctx , " EnumForms on the PrintServer isn't supported by test server (NT4) " ) ;
}
2005-06-16 20:46:42 +04:00
2010-04-06 15:23:22 +04:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
2010-04-08 13:56:27 +04:00
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
2010-04-06 15:23:22 +04:00
r . in . buffer = & blob ;
r . in . offered = needed ;
2003-11-26 09:26:18 +03:00
2010-04-06 15:23:22 +04:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_EnumForms_r ( b , tctx , & r ) ,
" EnumForms failed " ) ;
2009-02-25 23:10:44 +03:00
2010-04-06 15:23:22 +04:00
torture_assert ( tctx , info , " No forms returned " ) ;
}
torture_assert_werr_ok ( tctx , r . out . result , " EnumForms failed " ) ;
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_ENUM_LEVEL ( spoolss_EnumForms , info , r . in . level , count , needed , 4 ) ;
2010-04-06 15:23:22 +04:00
if ( info_p ) {
* info_p = info ;
}
if ( count_p ) {
* count_p = count ;
}
return true ;
}
static bool test_EnumForms_all ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
bool print_server )
{
uint32_t levels [ ] = { 1 , 2 } ;
int i , j ;
2009-02-25 23:10:44 +03:00
2010-04-06 15:23:22 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
2003-11-26 09:26:18 +03:00
2010-04-06 15:23:22 +04:00
uint32_t count = 0 ;
union spoolss_FormInfo * info = NULL ;
2003-11-26 09:26:18 +03:00
2010-04-06 15:23:22 +04:00
torture_assert ( tctx ,
test_EnumForms ( tctx , b , handle , print_server , levels [ i ] , & count , & info ) ,
" failed to enum forms " ) ;
for ( j = 0 ; j < count ; j + + ) {
if ( ! print_server ) {
torture_assert ( tctx ,
test_GetForm ( tctx , b , handle , info [ j ] . info1 . form_name , levels [ i ] ) ,
" failed to get form " ) ;
2009-02-25 23:10:44 +03:00
}
2005-02-21 16:54:06 +03:00
}
2010-04-06 15:23:22 +04:00
}
2003-11-26 09:26:18 +03:00
2010-04-06 15:23:22 +04:00
return true ;
}
2005-02-25 08:39:01 +03:00
2010-04-06 15:23:22 +04:00
static bool test_EnumForms_find_one ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
bool print_server ,
const char * form_name )
{
2017-08-09 09:23:29 +03:00
union spoolss_FormInfo * info = NULL ;
uint32_t count = 0 ;
2010-04-06 15:23:22 +04:00
bool found = false ;
int i ;
torture_assert ( tctx ,
test_EnumForms ( tctx , b , handle , print_server , 1 , & count , & info ) ,
" failed to enumerate forms " ) ;
2009-12-12 03:51:13 +03:00
2010-04-06 15:23:22 +04:00
for ( i = 0 ; i < count ; i + + ) {
if ( strequal ( form_name , info [ i ] . info1 . form_name ) ) {
found = true ;
break ;
}
2009-02-25 23:10:44 +03:00
}
2003-11-26 09:26:18 +03:00
2010-04-06 15:23:22 +04:00
return found ;
2003-11-26 09:26:18 +03:00
}
2009-06-30 13:38:41 +04:00
static bool test_DeleteForm ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-06-30 13:38:41 +04:00
struct policy_handle * handle ,
2010-04-07 16:37:30 +04:00
const char * form_name ,
WERROR expected_result )
2003-11-27 12:50:25 +03:00
{
struct spoolss_DeleteForm r ;
r . in . handle = handle ;
2005-04-04 19:19:27 +04:00
r . in . form_name = form_name ;
2003-11-27 12:50:25 +03:00
2010-04-06 15:23:22 +04:00
torture_comment ( tctx , " Testing DeleteForm(%s) \n " , form_name ) ;
2005-02-25 08:39:01 +03:00
2010-04-06 15:23:22 +04:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_DeleteForm_r ( b , tctx , & r ) ,
" DeleteForm failed " ) ;
2010-04-07 16:37:30 +04:00
torture_assert_werr_equal ( tctx , r . out . result , expected_result ,
" DeleteForm gave unexpected result " ) ;
if ( W_ERROR_IS_OK ( r . out . result ) ) {
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_DeleteForm_r ( b , tctx , & r ) ,
" 2nd DeleteForm failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_FORM_NAME ,
" 2nd DeleteForm failed " ) ;
}
2003-11-27 12:50:25 +03:00
2007-09-03 17:13:25 +04:00
return true ;
2003-11-27 12:50:25 +03:00
}
2009-06-30 13:38:41 +04:00
static bool test_AddForm ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-04-06 15:23:22 +04:00
struct policy_handle * handle ,
uint32_t level ,
2010-04-07 16:37:30 +04:00
union spoolss_AddFormInfo * info ,
WERROR expected_result )
2003-11-27 12:50:25 +03:00
{
struct spoolss_AddForm r ;
2013-01-16 04:15:49 +04:00
struct spoolss_AddFormInfoCtr info_ctr ;
info_ctr . level = level ;
info_ctr . info = * info ;
2010-04-06 15:23:22 +04:00
if ( level ! = 1 ) {
torture_skip ( tctx , " only level 1 supported " ) ;
}
2003-11-27 12:50:25 +03:00
2005-04-04 19:19:27 +04:00
r . in . handle = handle ;
2013-01-16 04:15:49 +04:00
r . in . info_ctr = & info_ctr ;
2005-04-04 19:19:27 +04:00
2010-04-07 16:37:30 +04:00
torture_comment ( tctx , " Testing AddForm(%s) level %d, type %d \n " ,
2013-01-16 04:15:49 +04:00
r . in . info_ctr - > info . info1 - > form_name , level ,
r . in . info_ctr - > info . info1 - > flags ) ;
2003-11-27 12:50:25 +03:00
2010-04-06 15:23:22 +04:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_AddForm_r ( b , tctx , & r ) ,
" AddForm failed " ) ;
2010-04-07 16:37:30 +04:00
torture_assert_werr_equal ( tctx , r . out . result , expected_result ,
" AddForm gave unexpected result " ) ;
2003-11-27 23:55:13 +03:00
2010-04-06 15:23:22 +04:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_AddForm_r ( b , tctx , & r ) ,
" 2nd AddForm failed " ) ;
2015-12-03 17:24:27 +03:00
if ( W_ERROR_EQUAL ( expected_result , WERR_INVALID_PARAMETER ) ) {
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_PARAMETER ,
2010-04-07 16:56:07 +04:00
" 2nd AddForm gave unexpected result " ) ;
} else {
torture_assert_werr_equal ( tctx , r . out . result , WERR_FILE_EXISTS ,
" 2nd AddForm gave unexpected result " ) ;
}
2005-07-01 13:05:10 +04:00
2010-04-06 15:23:22 +04:00
return true ;
}
2005-04-04 19:19:27 +04:00
2010-04-06 15:23:22 +04:00
static bool test_SetForm ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * form_name ,
uint32_t level ,
union spoolss_AddFormInfo * info )
{
struct spoolss_SetForm r ;
2013-01-16 16:41:28 +04:00
struct spoolss_AddFormInfoCtr info_ctr ;
info_ctr . level = level ;
info_ctr . info = * info ;
2003-11-27 23:55:13 +03:00
2010-04-06 15:23:22 +04:00
r . in . handle = handle ;
r . in . form_name = form_name ;
2013-01-16 16:41:28 +04:00
r . in . info_ctr = & info_ctr ;
2003-11-27 23:55:13 +03:00
2010-04-06 15:23:22 +04:00
torture_comment ( tctx , " Testing SetForm(%s) level %d \n " ,
2013-01-16 16:41:28 +04:00
form_name , level ) ;
2003-11-27 23:55:13 +03:00
2010-04-06 15:23:22 +04:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_SetForm_r ( b , tctx , & r ) ,
" SetForm failed " ) ;
2005-02-25 08:39:01 +03:00
2010-04-06 15:23:22 +04:00
torture_assert_werr_ok ( tctx , r . out . result ,
" SetForm failed " ) ;
2003-11-27 12:50:25 +03:00
2010-04-06 15:23:22 +04:00
return true ;
}
2005-07-01 13:05:10 +04:00
2010-04-06 15:23:22 +04:00
static bool test_GetForm_winreg ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * key_name ,
const char * form_name ,
enum winreg_Type * w_type ,
uint32_t * w_size ,
uint32_t * w_length ,
uint8_t * * w_data ) ;
2009-06-30 15:11:16 +04:00
2010-04-07 16:37:30 +04:00
static bool test_Forms_args ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
bool print_server ,
const char * printer_name ,
struct dcerpc_binding_handle * winreg_handle ,
struct policy_handle * hive_handle ,
const char * form_name ,
struct spoolss_AddFormInfo1 * info1 ,
WERROR expected_add_result ,
WERROR expected_delete_result )
2010-04-06 15:23:22 +04:00
{
union spoolss_FormInfo info ;
union spoolss_AddFormInfo add_info ;
2009-06-30 15:11:16 +04:00
2010-04-06 15:23:22 +04:00
enum winreg_Type w_type ;
uint32_t w_size ;
uint32_t w_length ;
uint8_t * w_data ;
2009-06-30 15:11:16 +04:00
2010-04-07 16:37:30 +04:00
add_info . info1 = info1 ;
2009-06-30 15:11:16 +04:00
2010-04-06 15:23:22 +04:00
torture_assert ( tctx ,
2010-04-07 16:37:30 +04:00
test_AddForm ( tctx , b , handle , 1 , & add_info , expected_add_result ) ,
2010-04-06 15:23:22 +04:00
" failed to add form " ) ;
2009-06-30 15:11:16 +04:00
2010-04-07 16:37:30 +04:00
if ( winreg_handle & & hive_handle & & W_ERROR_IS_OK ( expected_add_result ) ) {
2009-06-30 15:11:16 +04:00
2010-09-14 17:23:45 +04:00
struct spoolss_FormInfo1 i1 ;
2010-04-06 15:23:22 +04:00
torture_assert ( tctx ,
test_GetForm_winreg ( tctx , winreg_handle , hive_handle , TOP_LEVEL_CONTROL_FORMS_KEY , form_name , & w_type , & w_size , & w_length , & w_data ) ,
" failed to get form via winreg " ) ;
2010-09-14 17:23:45 +04:00
i1 . size . width = IVAL ( w_data , 0 ) ;
i1 . size . height = IVAL ( w_data , 4 ) ;
i1 . area . left = IVAL ( w_data , 8 ) ;
i1 . area . top = IVAL ( w_data , 12 ) ;
i1 . area . right = IVAL ( w_data , 16 ) ;
i1 . area . bottom = IVAL ( w_data , 20 ) ;
/* skip index here */
i1 . flags = IVAL ( w_data , 28 ) ;
2010-04-06 15:23:22 +04:00
torture_assert_int_equal ( tctx , w_type , REG_BINARY , " unexpected type " ) ;
torture_assert_int_equal ( tctx , w_size , 0x20 , " unexpected size " ) ;
torture_assert_int_equal ( tctx , w_length , 0x20 , " unexpected length " ) ;
2010-09-14 17:23:45 +04:00
torture_assert_int_equal ( tctx , i1 . size . width , add_info . info1 - > size . width , " width mismatch " ) ;
torture_assert_int_equal ( tctx , i1 . size . height , add_info . info1 - > size . height , " height mismatch " ) ;
torture_assert_int_equal ( tctx , i1 . area . left , add_info . info1 - > area . left , " left mismatch " ) ;
torture_assert_int_equal ( tctx , i1 . area . top , add_info . info1 - > area . top , " top mismatch " ) ;
torture_assert_int_equal ( tctx , i1 . area . right , add_info . info1 - > area . right , " right mismatch " ) ;
torture_assert_int_equal ( tctx , i1 . area . bottom , add_info . info1 - > area . bottom , " bottom mismatch " ) ;
torture_assert_int_equal ( tctx , i1 . flags , add_info . info1 - > flags , " flags mismatch " ) ;
2010-04-06 15:23:22 +04:00
}
2010-04-07 16:37:30 +04:00
if ( ! print_server & & W_ERROR_IS_OK ( expected_add_result ) ) {
2010-04-06 15:23:22 +04:00
torture_assert ( tctx ,
test_GetForm_args ( tctx , b , handle , form_name , 1 , & info ) ,
" failed to get added form " ) ;
torture_assert_int_equal ( tctx , info . info1 . size . width , add_info . info1 - > size . width , " width mismatch " ) ;
torture_assert_int_equal ( tctx , info . info1 . size . height , add_info . info1 - > size . height , " height mismatch " ) ;
torture_assert_int_equal ( tctx , info . info1 . area . left , add_info . info1 - > area . left , " left mismatch " ) ;
torture_assert_int_equal ( tctx , info . info1 . area . top , add_info . info1 - > area . top , " top mismatch " ) ;
torture_assert_int_equal ( tctx , info . info1 . area . right , add_info . info1 - > area . right , " right mismatch " ) ;
torture_assert_int_equal ( tctx , info . info1 . area . bottom , add_info . info1 - > area . bottom , " bottom mismatch " ) ;
torture_assert_int_equal ( tctx , info . info1 . flags , add_info . info1 - > flags , " flags mismatch " ) ;
if ( winreg_handle & & hive_handle ) {
2010-09-14 17:23:45 +04:00
struct spoolss_FormInfo1 i1 ;
i1 . size . width = IVAL ( w_data , 0 ) ;
i1 . size . height = IVAL ( w_data , 4 ) ;
i1 . area . left = IVAL ( w_data , 8 ) ;
i1 . area . top = IVAL ( w_data , 12 ) ;
i1 . area . right = IVAL ( w_data , 16 ) ;
i1 . area . bottom = IVAL ( w_data , 20 ) ;
2010-04-06 15:23:22 +04:00
/* skip index here */
2010-09-14 17:23:45 +04:00
i1 . flags = IVAL ( w_data , 28 ) ;
torture_assert_int_equal ( tctx , i1 . size . width , info . info1 . size . width , " width mismatch " ) ;
torture_assert_int_equal ( tctx , i1 . size . height , info . info1 . size . height , " height mismatch " ) ;
torture_assert_int_equal ( tctx , i1 . area . left , info . info1 . area . left , " left mismatch " ) ;
torture_assert_int_equal ( tctx , i1 . area . top , info . info1 . area . top , " top mismatch " ) ;
torture_assert_int_equal ( tctx , i1 . area . right , info . info1 . area . right , " right mismatch " ) ;
torture_assert_int_equal ( tctx , i1 . area . bottom , info . info1 . area . bottom , " bottom mismatch " ) ;
torture_assert_int_equal ( tctx , i1 . flags , info . info1 . flags , " flags mismatch " ) ;
2009-06-30 15:11:16 +04:00
}
2010-04-06 15:23:22 +04:00
add_info . info1 - > size . width = 1234 ;
torture_assert ( tctx ,
test_SetForm ( tctx , b , handle , form_name , 1 , & add_info ) ,
" failed to set form " ) ;
torture_assert ( tctx ,
test_GetForm_args ( tctx , b , handle , form_name , 1 , & info ) ,
" failed to get setted form " ) ;
torture_assert_int_equal ( tctx , info . info1 . size . width , add_info . info1 - > size . width , " width mismatch " ) ;
2003-11-27 12:50:25 +03:00
}
2015-12-03 17:24:27 +03:00
if ( ! W_ERROR_EQUAL ( expected_add_result , WERR_INVALID_PARAMETER ) ) {
2010-04-07 16:56:07 +04:00
torture_assert ( tctx ,
test_EnumForms_find_one ( tctx , b , handle , print_server , form_name ) ,
" Newly added form not found in enum call " ) ;
}
2010-04-06 15:23:22 +04:00
torture_assert ( tctx ,
2010-04-07 16:37:30 +04:00
test_DeleteForm ( tctx , b , handle , form_name , expected_delete_result ) ,
2010-04-06 15:23:22 +04:00
" failed to delete form " ) ;
return true ;
2003-11-27 12:50:25 +03:00
}
2010-04-07 16:37:30 +04:00
static bool test_Forms ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
bool print_server ,
const char * printer_name ,
struct dcerpc_binding_handle * winreg_handle ,
struct policy_handle * hive_handle )
{
2010-04-12 15:44:19 +04:00
const struct spoolss_FormSize size = {
. width = 50 ,
. height = 25
} ;
const struct spoolss_FormArea area = {
. left = 5 ,
. top = 10 ,
. right = 45 ,
. bottom = 15
} ;
2010-04-07 16:37:30 +04:00
int i ;
struct {
struct spoolss_AddFormInfo1 info1 ;
WERROR expected_add_result ;
WERROR expected_delete_result ;
} forms [ ] = {
{
2010-04-13 11:38:42 +04:00
. info1 = {
. flags = SPOOLSS_FORM_USER ,
. form_name = " testform_user " ,
. size = size ,
. area = area ,
} ,
2010-04-07 16:37:30 +04:00
. expected_add_result = WERR_OK ,
. expected_delete_result = WERR_OK
} ,
/*
weird , we can add a builtin form but we can never remove it
again - gd
{
2010-04-13 11:38:42 +04:00
. info1 = {
. flags = SPOOLSS_FORM_BUILTIN ,
. form_name = " testform_builtin " ,
. size = size ,
. area = area ,
} ,
2010-04-07 16:37:30 +04:00
. expected_add_result = WERR_OK ,
2015-12-03 17:24:27 +03:00
. expected_delete_result = WERR_INVALID_PARAMETER ,
2010-04-07 16:37:30 +04:00
} ,
*/
{
2010-04-13 11:38:42 +04:00
. info1 = {
. flags = SPOOLSS_FORM_PRINTER ,
. form_name = " testform_printer " ,
. size = size ,
. area = area ,
} ,
2010-04-07 16:37:30 +04:00
. expected_add_result = WERR_OK ,
. expected_delete_result = WERR_OK
} ,
{
2010-04-13 11:38:42 +04:00
. info1 = {
. flags = SPOOLSS_FORM_USER ,
. form_name = " Letter " ,
. size = size ,
. area = area ,
} ,
2010-04-07 16:37:30 +04:00
. expected_add_result = WERR_FILE_EXISTS ,
2015-12-03 17:24:27 +03:00
. expected_delete_result = WERR_INVALID_PARAMETER
2010-04-07 16:37:30 +04:00
} ,
{
2010-04-13 11:38:42 +04:00
. info1 = {
. flags = SPOOLSS_FORM_BUILTIN ,
. form_name = " Letter " ,
. size = size ,
. area = area ,
} ,
2010-04-07 16:37:30 +04:00
. expected_add_result = WERR_FILE_EXISTS ,
2015-12-03 17:24:27 +03:00
. expected_delete_result = WERR_INVALID_PARAMETER
2010-04-07 16:37:30 +04:00
} ,
{
2010-04-13 11:38:42 +04:00
. info1 = {
. flags = SPOOLSS_FORM_PRINTER ,
. form_name = " Letter " ,
. size = size ,
. area = area ,
} ,
2010-04-07 16:37:30 +04:00
. expected_add_result = WERR_FILE_EXISTS ,
2015-12-03 17:24:27 +03:00
. expected_delete_result = WERR_INVALID_PARAMETER
2010-04-07 16:56:07 +04:00
} ,
{
2010-04-13 11:38:42 +04:00
. info1 = {
. flags = 12345 ,
. form_name = " invalid_flags " ,
. size = size ,
. area = area ,
} ,
2015-12-03 17:24:27 +03:00
. expected_add_result = WERR_INVALID_PARAMETER ,
2010-04-07 16:56:07 +04:00
. expected_delete_result = WERR_INVALID_FORM_NAME
2010-04-07 16:37:30 +04:00
}
2010-04-07 16:56:07 +04:00
2010-04-07 16:37:30 +04:00
} ;
for ( i = 0 ; i < ARRAY_SIZE ( forms ) ; i + + ) {
torture_assert ( tctx ,
test_Forms_args ( tctx , b , handle , print_server , printer_name ,
winreg_handle , hive_handle ,
forms [ i ] . info1 . form_name ,
& forms [ i ] . info1 ,
forms [ i ] . expected_add_result ,
forms [ i ] . expected_delete_result ) ,
talloc_asprintf ( tctx , " failed to test form '%s' " , forms [ i ] . info1 . form_name ) ) ;
}
return true ;
}
2009-06-30 13:38:41 +04:00
static bool test_EnumPorts_old ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2004-09-03 17:36:58 +04:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
2004-09-03 17:36:58 +04:00
NTSTATUS status ;
struct spoolss_EnumPorts r ;
2009-02-06 19:09:30 +03:00
uint32_t needed ;
2009-02-16 18:42:21 +03:00
uint32_t count ;
2009-03-02 19:32:24 +03:00
union spoolss_PortInfo * info ;
2010-05-19 01:40:43 +04:00
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2004-09-03 17:36:58 +04:00
2009-06-30 13:38:41 +04:00
r . in . servername = talloc_asprintf ( tctx , " \\ \\ %s " ,
2004-09-03 17:36:58 +04:00
dcerpc_server_name ( p ) ) ;
r . in . level = 2 ;
r . in . buffer = NULL ;
2005-06-14 19:52:31 +04:00
r . in . offered = 0 ;
2009-02-06 19:09:30 +03:00
r . out . needed = & needed ;
2009-02-16 18:42:21 +03:00
r . out . count = & count ;
2009-03-02 19:32:24 +03:00
r . out . info = & info ;
2004-09-03 17:36:58 +04:00
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing EnumPorts \n " ) ;
2004-09-03 17:36:58 +04:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EnumPorts_r ( b , tctx , & r ) ;
2004-09-03 17:36:58 +04:00
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " EnumPorts failed " ) ;
2004-09-03 17:36:58 +04:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
2010-04-08 13:56:27 +04:00
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
2004-09-03 17:36:58 +04:00
r . in . buffer = & blob ;
2009-02-06 19:09:30 +03:00
r . in . offered = needed ;
2004-09-03 17:36:58 +04:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EnumPorts_r ( b , tctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " EnumPorts failed " ) ;
2009-12-04 00:38:38 +03:00
torture_assert_werr_ok ( tctx , r . out . result , " EnumPorts failed " ) ;
2004-09-03 17:36:58 +04:00
2009-03-02 19:32:24 +03:00
torture_assert ( tctx , info , " No ports returned " ) ;
2004-09-03 17:36:58 +04:00
}
2009-12-04 00:38:38 +03:00
torture_assert_werr_ok ( tctx , r . out . result , " EnumPorts failed " ) ;
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_ENUM_LEVEL ( spoolss_EnumPorts , info , 2 , count , needed , 4 ) ;
2009-12-12 03:51:13 +03:00
2007-09-03 17:13:25 +04:00
return true ;
2004-09-03 17:36:58 +04:00
}
2009-06-30 13:38:41 +04:00
static bool test_AddPort ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2005-02-25 09:16:13 +03:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
2005-02-25 09:16:13 +03:00
NTSTATUS status ;
struct spoolss_AddPort r ;
2010-05-19 01:40:43 +04:00
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2005-02-25 09:16:13 +03:00
2009-06-30 13:38:41 +04:00
r . in . server_name = talloc_asprintf ( tctx , " \\ \\ %s " ,
2005-02-25 09:16:13 +03:00
dcerpc_server_name ( p ) ) ;
r . in . unknown = 0 ;
r . in . monitor_name = " foo " ;
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing AddPort \n " ) ;
2005-02-25 09:16:13 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_AddPort_r ( b , tctx , & r ) ;
2005-02-25 09:16:13 +03:00
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " AddPort failed " ) ;
2005-02-25 09:16:13 +03:00
/* win2k3 returns WERR_NOT_SUPPORTED */
#if 0
if ( ! W_ERROR_IS_OK ( r . out . result ) ) {
printf ( " AddPort failed - %s \n " , win_errstr ( r . out . result ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2005-02-25 09:16:13 +03:00
}
# endif
2007-10-07 02:28:14 +04:00
return true ;
2005-02-25 09:16:13 +03:00
}
2010-03-26 17:23:34 +03:00
static bool test_GetJob_args ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
uint32_t job_id ,
uint32_t level ,
union spoolss_JobInfo * info_p )
2003-11-28 08:02:32 +03:00
{
NTSTATUS status ;
struct spoolss_GetJob r ;
2009-07-02 00:52:49 +04:00
union spoolss_JobInfo info ;
2009-02-06 14:18:06 +03:00
uint32_t needed ;
2003-11-28 08:02:32 +03:00
r . in . handle = handle ;
r . in . job_id = job_id ;
2010-03-26 17:23:34 +03:00
r . in . level = level ;
2003-11-28 08:02:32 +03:00
r . in . buffer = NULL ;
2005-06-14 19:52:31 +04:00
r . in . offered = 0 ;
2009-02-06 14:18:06 +03:00
r . out . needed = & needed ;
2009-07-02 00:52:49 +04:00
r . out . info = & info ;
2003-11-28 08:02:32 +03:00
2010-03-25 02:48:55 +03:00
torture_comment ( tctx , " Testing GetJob(%d), level %d \n " , job_id , r . in . level ) ;
2003-11-28 08:02:32 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_GetJob_r ( b , tctx , & r ) ;
2010-03-26 17:23:34 +03:00
torture_assert_ntstatus_ok ( tctx , status , " GetJob failed " ) ;
if ( level = = 0 ) {
2015-12-03 17:24:43 +03:00
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_LEVEL , " Unexpected return code " ) ;
2010-03-26 17:23:34 +03:00
}
2009-07-02 00:52:49 +04:00
2010-03-26 17:23:34 +03:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
2010-04-08 13:56:27 +04:00
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
2010-03-26 17:23:34 +03:00
r . in . buffer = & blob ;
r . in . offered = needed ;
2003-11-28 08:02:32 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_GetJob_r ( b , tctx , & r ) ;
2009-04-14 01:56:59 +04:00
torture_assert_ntstatus_ok ( tctx , status , " GetJob failed " ) ;
2010-03-26 17:23:34 +03:00
}
2009-04-14 01:56:59 +04:00
2010-04-09 21:53:31 +04:00
torture_assert_werr_ok ( tctx , r . out . result , " GetJob failed " ) ;
torture_assert ( tctx , r . out . info , " No job info returned " ) ;
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_LEVEL ( spoolss_JobInfo , r . out . info , r . in . level , needed , 4 ) ;
2010-04-09 21:53:31 +04:00
2010-03-26 17:23:34 +03:00
if ( info_p ) {
* info_p = * r . out . info ;
}
2009-04-14 01:56:59 +04:00
2010-03-26 17:23:34 +03:00
return true ;
}
2009-12-12 03:51:13 +03:00
2013-12-04 17:01:52 +04:00
#if 0
2010-03-26 17:23:34 +03:00
static bool test_GetJob ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
uint32_t job_id )
{
uint32_t levels [ ] = { 0 , 1 , 2 /* 3, 4 */ } ;
uint32_t i ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
torture_assert ( tctx ,
test_GetJob_args ( tctx , b , handle , job_id , levels [ i ] , NULL ) ,
" GetJob failed " ) ;
2003-11-28 08:02:32 +03:00
}
2007-09-03 17:13:25 +04:00
return true ;
2003-11-28 08:02:32 +03:00
}
2013-12-04 17:01:52 +04:00
# endif
2003-11-28 08:02:32 +03:00
2009-06-30 13:38:41 +04:00
static bool test_SetJob ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-04-28 01:33:05 +04:00
struct policy_handle * handle ,
uint32_t job_id ,
struct spoolss_JobInfoContainer * ctr ,
2007-09-03 17:13:25 +04:00
enum spoolss_JobControl command )
2003-11-28 08:02:32 +03:00
{
NTSTATUS status ;
struct spoolss_SetJob r ;
2005-06-06 18:56:51 +04:00
r . in . handle = handle ;
r . in . job_id = job_id ;
2010-04-28 01:33:05 +04:00
r . in . ctr = ctr ;
2005-06-06 18:56:51 +04:00
r . in . command = command ;
2003-11-28 08:02:32 +03:00
2009-04-14 03:08:23 +04:00
switch ( command ) {
case SPOOLSS_JOB_CONTROL_PAUSE :
2010-04-08 01:40:17 +04:00
torture_comment ( tctx , " Testing SetJob(%d), SPOOLSS_JOB_CONTROL_PAUSE \n " , job_id ) ;
2009-04-14 03:08:23 +04:00
break ;
case SPOOLSS_JOB_CONTROL_RESUME :
2010-03-25 02:33:35 +03:00
torture_comment ( tctx , " Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RESUME \n " , job_id ) ;
2009-04-14 03:08:23 +04:00
break ;
case SPOOLSS_JOB_CONTROL_CANCEL :
2010-03-25 02:33:35 +03:00
torture_comment ( tctx , " Testing SetJob(%d), SPOOLSS_JOB_CONTROL_CANCEL \n " , job_id ) ;
2009-04-14 03:08:23 +04:00
break ;
case SPOOLSS_JOB_CONTROL_RESTART :
2010-03-25 02:33:35 +03:00
torture_comment ( tctx , " Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RESTART \n " , job_id ) ;
2009-04-14 03:08:23 +04:00
break ;
case SPOOLSS_JOB_CONTROL_DELETE :
2010-03-25 02:33:35 +03:00
torture_comment ( tctx , " Testing SetJob(%d), SPOOLSS_JOB_CONTROL_DELETE \n " , job_id ) ;
2009-04-14 03:08:23 +04:00
break ;
case SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER :
2010-03-25 02:33:35 +03:00
torture_comment ( tctx , " Testing SetJob(%d), SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER \n " , job_id ) ;
2009-04-14 03:08:23 +04:00
break ;
case SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED :
2010-03-25 02:33:35 +03:00
torture_comment ( tctx , " Testing SetJob(%d), SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED \n " , job_id ) ;
2009-04-14 03:08:23 +04:00
break ;
case SPOOLSS_JOB_CONTROL_RETAIN :
2010-03-25 02:33:35 +03:00
torture_comment ( tctx , " Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RETAIN \n " , job_id ) ;
2009-04-14 03:08:23 +04:00
break ;
case SPOOLSS_JOB_CONTROL_RELEASE :
2010-03-25 02:33:35 +03:00
torture_comment ( tctx , " Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RELEASE \n " , job_id ) ;
2009-04-14 03:08:23 +04:00
break ;
default :
2010-03-25 02:33:35 +03:00
torture_comment ( tctx , " Testing SetJob(%d) \n " , job_id ) ;
2009-04-14 03:08:23 +04:00
break ;
}
2003-11-28 08:02:32 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_SetJob_r ( b , tctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " SetJob failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " SetJob failed " ) ;
2003-11-28 08:02:32 +03:00
2007-09-03 17:13:25 +04:00
return true ;
2003-11-28 08:02:32 +03:00
}
2009-02-10 00:22:45 +03:00
static bool test_AddJob ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-02-10 00:22:45 +03:00
struct policy_handle * handle )
{
NTSTATUS status ;
struct spoolss_AddJob r ;
uint32_t needed ;
r . in . level = 0 ;
r . in . handle = handle ;
r . in . offered = 0 ;
r . out . needed = & needed ;
2009-04-13 22:44:19 +04:00
r . in . buffer = r . out . buffer = NULL ;
2009-02-10 00:22:45 +03:00
torture_comment ( tctx , " Testing AddJob \n " ) ;
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_AddJob_r ( b , tctx , & r ) ;
2013-02-05 19:10:34 +04:00
torture_assert_ntstatus_ok ( tctx , status , " AddJob failed " ) ;
2015-12-03 17:24:43 +03:00
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_LEVEL , " AddJob failed " ) ;
2009-02-10 00:22:45 +03:00
r . in . level = 1 ;
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_AddJob_r ( b , tctx , & r ) ;
2013-02-05 19:10:34 +04:00
torture_assert_ntstatus_ok ( tctx , status , " AddJob failed " ) ;
2015-12-03 17:24:27 +03:00
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_PARAMETER , " AddJob failed " ) ;
2009-02-10 00:22:45 +03:00
return true ;
}
2010-03-26 15:37:42 +03:00
static bool test_EnumJobs_args ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
uint32_t level ,
2014-10-27 22:13:57 +03:00
WERROR werr_expected ,
2010-03-26 15:37:42 +03:00
uint32_t * count_p ,
union spoolss_JobInfo * * info_p )
2003-11-28 08:02:32 +03:00
{
NTSTATUS status ;
struct spoolss_EnumJobs r ;
2009-02-06 19:09:30 +03:00
uint32_t needed ;
2009-02-16 18:42:21 +03:00
uint32_t count ;
2009-03-02 19:32:24 +03:00
union spoolss_JobInfo * info ;
2003-11-28 08:02:32 +03:00
r . in . handle = handle ;
r . in . firstjob = 0 ;
r . in . numjobs = 0xffffffff ;
2010-03-26 15:37:42 +03:00
r . in . level = level ;
2003-11-28 08:02:32 +03:00
r . in . buffer = NULL ;
2005-06-14 19:52:31 +04:00
r . in . offered = 0 ;
2009-02-06 19:09:30 +03:00
r . out . needed = & needed ;
2009-02-16 18:42:21 +03:00
r . out . count = & count ;
2009-03-02 19:32:24 +03:00
r . out . info = & info ;
2003-11-28 08:02:32 +03:00
2010-03-26 15:37:42 +03:00
torture_comment ( tctx , " Testing EnumJobs level %d \n " , level ) ;
2003-11-28 08:02:32 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EnumJobs_r ( b , tctx , & r ) ;
2003-11-28 08:02:32 +03:00
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " EnumJobs failed " ) ;
2003-11-28 08:02:32 +03:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
2010-04-08 13:56:27 +04:00
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
2003-11-28 08:02:32 +03:00
r . in . buffer = & blob ;
2009-02-06 19:09:30 +03:00
r . in . offered = needed ;
2003-11-28 08:02:32 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EnumJobs_r ( b , tctx , & r ) ;
2003-11-28 08:02:32 +03:00
2009-12-04 00:38:38 +03:00
torture_assert_ntstatus_ok ( tctx , status , " EnumJobs failed " ) ;
2014-10-27 22:13:57 +03:00
torture_assert_werr_equal ( tctx , r . out . result , werr_expected ,
" EnumJobs failed " ) ;
2009-03-02 19:32:24 +03:00
torture_assert ( tctx , info , " No jobs returned " ) ;
2003-11-28 08:02:32 +03:00
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_ENUM_LEVEL ( spoolss_EnumJobs , * r . out . info , r . in . level , count , needed , 4 ) ;
2009-12-12 03:51:13 +03:00
2007-09-03 17:13:25 +04:00
} else {
2014-10-27 22:13:57 +03:00
torture_assert_werr_equal ( tctx , r . out . result , werr_expected ,
" EnumJobs failed " ) ;
2003-11-28 08:02:32 +03:00
}
2010-03-26 15:37:42 +03:00
if ( count_p ) {
* count_p = count ;
}
if ( info_p ) {
* info_p = info ;
}
2007-09-03 17:13:25 +04:00
return true ;
2003-11-28 08:02:32 +03:00
}
2013-01-22 01:09:22 +04:00
static bool test_JobPropertiesEnum ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
uint32_t job_id )
{
2016-08-29 13:55:23 +03:00
struct spoolss_EnumJobNamedProperties r ;
2013-01-22 01:09:22 +04:00
uint32_t pcProperties = 0 ;
2016-09-07 08:50:14 +03:00
struct spoolss_PrintNamedProperty * ppProperties = NULL ;
2013-01-22 01:09:22 +04:00
r . in . hPrinter = handle ;
r . in . JobId = job_id ;
r . out . pcProperties = & pcProperties ;
r . out . ppProperties = & ppProperties ;
2016-08-29 13:55:23 +03:00
torture_comment ( tctx , " Testing EnumJobNamedProperties(%d) \n " , job_id ) ;
2013-01-22 01:09:22 +04:00
torture_assert_ntstatus_ok ( tctx ,
2016-08-29 13:55:23 +03:00
dcerpc_spoolss_EnumJobNamedProperties_r ( b , tctx , & r ) ,
" spoolss_EnumJobNamedProperties failed " ) ;
2013-01-22 01:09:22 +04:00
torture_assert_werr_ok ( tctx , r . out . result ,
2016-08-29 13:55:23 +03:00
" spoolss_EnumJobNamedProperties failed " ) ;
2013-01-22 01:09:22 +04:00
return true ;
}
static bool test_JobPropertySet ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
uint32_t job_id ,
2016-09-07 08:50:14 +03:00
struct spoolss_PrintNamedProperty * property )
2013-01-22 01:09:22 +04:00
{
2016-08-29 13:53:45 +03:00
struct spoolss_SetJobNamedProperty r ;
2013-01-22 01:09:22 +04:00
r . in . hPrinter = handle ;
r . in . JobId = job_id ;
r . in . pProperty = property ;
2016-08-29 13:53:45 +03:00
torture_comment ( tctx , " Testing SetJobNamedProperty(%d) %s - %d \n " ,
2013-01-22 01:09:22 +04:00
job_id , property - > propertyName ,
property - > propertyValue . ePropertyType ) ;
torture_assert_ntstatus_ok ( tctx ,
2016-08-29 13:53:45 +03:00
dcerpc_spoolss_SetJobNamedProperty_r ( b , tctx , & r ) ,
" spoolss_SetJobNamedProperty failed " ) ;
2013-01-22 01:09:22 +04:00
torture_assert_werr_ok ( tctx , r . out . result ,
2016-08-29 13:53:45 +03:00
" spoolss_SetJobNamedProperty failed " ) ;
2013-01-22 01:09:22 +04:00
return true ;
}
static bool test_JobPropertyGetValue ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
uint32_t job_id ,
const char * property_name ,
2016-09-07 08:50:14 +03:00
struct spoolss_PrintPropertyValue * value )
2013-01-22 01:09:22 +04:00
{
2016-08-29 13:52:38 +03:00
struct spoolss_GetJobNamedPropertyValue r ;
2013-01-22 01:09:22 +04:00
r . in . hPrinter = handle ;
r . in . JobId = job_id ;
r . in . pszName = property_name ;
r . out . pValue = value ;
2016-08-29 13:52:38 +03:00
torture_comment ( tctx , " Testing GetJobNamedPropertyValue(%d) %s \n " ,
2013-01-22 01:09:22 +04:00
job_id , property_name ) ;
torture_assert_ntstatus_ok ( tctx ,
2016-08-29 13:52:38 +03:00
dcerpc_spoolss_GetJobNamedPropertyValue_r ( b , tctx , & r ) ,
" spoolss_GetJobNamedPropertyValue failed " ) ;
2013-01-22 01:09:22 +04:00
torture_assert_werr_ok ( tctx , r . out . result ,
2016-08-29 13:52:38 +03:00
" spoolss_GetJobNamedPropertyValue failed " ) ;
2013-01-22 01:09:22 +04:00
return true ;
}
static bool test_JobPropertyDelete ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
uint32_t job_id ,
const char * property_name )
{
2016-08-29 13:54:47 +03:00
struct spoolss_DeleteJobNamedProperty r ;
2013-01-22 01:09:22 +04:00
r . in . hPrinter = handle ;
r . in . JobId = job_id ;
r . in . pszName = property_name ;
2016-08-29 13:54:47 +03:00
torture_comment ( tctx , " Testing DeleteJobNamedProperty(%d) %s \n " ,
2013-01-22 01:09:22 +04:00
job_id , property_name ) ;
torture_assert_ntstatus_ok ( tctx ,
2016-08-29 13:54:47 +03:00
dcerpc_spoolss_DeleteJobNamedProperty_r ( b , tctx , & r ) ,
" spoolss_DeleteJobNamedProperty failed " ) ;
2013-01-22 01:09:22 +04:00
torture_assert_werr_ok ( tctx , r . out . result ,
2016-08-29 13:54:47 +03:00
" spoolss_DeleteJobNamedProperty failed " ) ;
2013-01-22 01:09:22 +04:00
return true ;
}
2013-11-21 15:40:15 +04:00
static bool test_DoPrintTest_add_one_job_common ( struct torture_context * tctx ,
2010-03-26 15:37:42 +03:00
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
2011-04-20 19:53:43 +04:00
const char * document_name ,
2013-11-21 15:40:15 +04:00
const char * datatype ,
2010-03-26 15:37:42 +03:00
uint32_t * job_id )
2005-06-06 19:03:16 +04:00
{
NTSTATUS status ;
struct spoolss_StartDocPrinter s ;
2013-01-19 01:22:13 +04:00
struct spoolss_DocumentInfoCtr info_ctr ;
2005-06-06 19:03:16 +04:00
struct spoolss_DocumentInfo1 info1 ;
2005-06-06 20:08:29 +04:00
struct spoolss_StartPagePrinter sp ;
struct spoolss_WritePrinter w ;
struct spoolss_EndPagePrinter ep ;
2005-06-06 19:03:16 +04:00
struct spoolss_EndDocPrinter e ;
2005-06-06 20:08:29 +04:00
int i ;
2009-02-06 14:44:57 +03:00
uint32_t num_written ;
2005-06-06 19:03:16 +04:00
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing StartDocPrinter \n " ) ;
2005-06-06 19:03:16 +04:00
s . in . handle = handle ;
2013-01-19 01:22:13 +04:00
s . in . info_ctr = & info_ctr ;
2010-03-25 02:37:45 +03:00
s . out . job_id = job_id ;
2013-01-19 01:22:13 +04:00
2011-04-20 19:53:43 +04:00
info1 . document_name = document_name ;
2005-06-06 19:03:16 +04:00
info1 . output_file = NULL ;
2013-11-21 15:40:15 +04:00
info1 . datatype = datatype ;
2005-06-06 19:03:16 +04:00
2013-01-19 01:22:13 +04:00
info_ctr . level = 1 ;
info_ctr . info . info1 = & info1 ;
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_StartDocPrinter_r ( b , tctx , & s ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_StartDocPrinter failed " ) ;
torture_assert_werr_ok ( tctx , s . out . result , " StartDocPrinter failed " ) ;
2005-06-06 19:03:16 +04:00
2005-06-06 20:08:29 +04:00
for ( i = 1 ; i < 4 ; i + + ) {
2014-12-03 20:44:37 +03:00
union spoolss_JobInfo ginfo ;
bool ok ;
2010-03-25 02:37:45 +03:00
torture_comment ( tctx , " Testing StartPagePrinter: Page[%d], JobId[%d] \n " , i , * job_id ) ;
2005-06-06 20:08:29 +04:00
sp . in . handle = handle ;
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_StartPagePrinter_r ( b , tctx , & sp ) ;
2009-06-30 13:38:41 +04:00
torture_assert_ntstatus_ok ( tctx , status ,
2007-09-03 17:13:25 +04:00
" dcerpc_spoolss_StartPagePrinter failed " ) ;
torture_assert_werr_ok ( tctx , sp . out . result , " StartPagePrinter failed " ) ;
2005-06-06 20:08:29 +04:00
2014-12-03 20:44:37 +03:00
ok = test_GetJob_args ( tctx , b , handle , * job_id , 1 , & ginfo ) ;
if ( ! ok ) {
torture_comment ( tctx , " test_GetJob failed for JobId[%d] \n " , * job_id ) ;
}
2010-03-25 02:37:45 +03:00
torture_comment ( tctx , " Testing WritePrinter: Page[%d], JobId[%d] \n " , i , * job_id ) ;
2005-06-06 20:08:29 +04:00
w . in . handle = handle ;
2007-09-03 17:13:25 +04:00
w . in . data = data_blob_string_const ( talloc_asprintf ( tctx , " TortureTestPage: %d \n Data \n " , i ) ) ;
2009-02-06 14:44:57 +03:00
w . out . num_written = & num_written ;
2005-06-06 20:08:29 +04:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_WritePrinter_r ( b , tctx , & w ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_WritePrinter failed " ) ;
torture_assert_werr_ok ( tctx , w . out . result , " WritePrinter failed " ) ;
2005-06-06 20:08:29 +04:00
2010-03-25 02:37:45 +03:00
torture_comment ( tctx , " Testing EndPagePrinter: Page[%d], JobId[%d] \n " , i , * job_id ) ;
2005-06-06 20:08:29 +04:00
ep . in . handle = handle ;
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EndPagePrinter_r ( b , tctx , & ep ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_EndPagePrinter failed " ) ;
torture_assert_werr_ok ( tctx , ep . out . result , " EndPagePrinter failed " ) ;
2005-06-06 20:08:29 +04:00
}
2010-03-25 02:37:45 +03:00
torture_comment ( tctx , " Testing EndDocPrinter: JobId[%d] \n " , * job_id ) ;
2005-06-06 19:03:16 +04:00
e . in . handle = handle ;
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EndDocPrinter_r ( b , tctx , & e ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " dcerpc_spoolss_EndDocPrinter failed " ) ;
torture_assert_werr_ok ( tctx , e . out . result , " EndDocPrinter failed " ) ;
2005-06-06 19:03:16 +04:00
2010-03-25 02:37:45 +03:00
return true ;
}
2013-11-21 15:40:15 +04:00
static bool test_DoPrintTest_add_one_job ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * document_name ,
uint32_t * job_id )
{
test_DoPrintTest_add_one_job_common ( tctx , b , handle , document_name , " RAW " , job_id ) ;
2013-12-04 17:01:51 +04:00
return true ;
2013-11-21 15:40:15 +04:00
}
static bool test_DoPrintTest_add_one_job_v4 ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * document_name ,
uint32_t * job_id )
{
test_DoPrintTest_add_one_job_common ( tctx , b , handle , document_name , " XPS_PASS " , job_id ) ;
2013-12-04 17:01:51 +04:00
return true ;
2013-11-21 15:40:15 +04:00
}
2010-03-26 15:37:42 +03:00
static bool test_DoPrintTest_check_jobs ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
uint32_t num_jobs ,
uint32_t * job_ids )
{
uint32_t count ;
union spoolss_JobInfo * info = NULL ;
int i ;
torture_assert ( tctx ,
test_AddJob ( tctx , b , handle ) ,
" AddJob failed " ) ;
torture_assert ( tctx ,
2014-10-27 22:13:57 +03:00
test_EnumJobs_args ( tctx , b , handle , 1 , WERR_OK , & count , & info ) ,
2010-03-26 15:37:42 +03:00
" EnumJobs level 1 failed " ) ;
torture_assert_int_equal ( tctx , count , num_jobs , " unexpected number of jobs in queue " ) ;
for ( i = 0 ; i < num_jobs ; i + + ) {
2010-03-26 17:23:34 +03:00
union spoolss_JobInfo ginfo ;
2010-04-28 02:05:41 +04:00
const char * document_name ;
const char * new_document_name = " any_other_docname " ;
struct spoolss_JobInfoContainer ctr ;
struct spoolss_SetJobInfo1 info1 ;
2010-03-26 17:23:34 +03:00
2010-03-26 15:37:42 +03:00
torture_assert_int_equal ( tctx , info [ i ] . info1 . job_id , job_ids [ i ] , " job id mismatch " ) ;
torture_assert ( tctx ,
2010-03-26 17:23:34 +03:00
test_GetJob_args ( tctx , b , handle , info [ i ] . info1 . job_id , 1 , & ginfo ) ,
2010-03-26 15:37:42 +03:00
" failed to call test_GetJob " ) ;
2010-03-26 17:23:34 +03:00
torture_assert_int_equal ( tctx , ginfo . info1 . job_id , info [ i ] . info1 . job_id , " job id mismatch " ) ;
2010-04-28 02:05:41 +04:00
document_name = ginfo . info1 . document_name ;
info1 . job_id = ginfo . info1 . job_id ;
info1 . printer_name = ginfo . info1 . printer_name ;
info1 . server_name = ginfo . info1 . server_name ;
info1 . user_name = ginfo . info1 . user_name ;
info1 . document_name = new_document_name ;
info1 . data_type = ginfo . info1 . data_type ;
info1 . text_status = ginfo . info1 . text_status ;
info1 . status = ginfo . info1 . status ;
info1 . priority = ginfo . info1 . priority ;
info1 . position = ginfo . info1 . position ;
info1 . total_pages = ginfo . info1 . total_pages ;
info1 . pages_printed = ginfo . info1 . pages_printed ;
info1 . submitted = ginfo . info1 . submitted ;
ctr . level = 1 ;
ctr . info . info1 = & info1 ;
torture_assert ( tctx ,
test_SetJob ( tctx , b , handle , info [ i ] . info1 . job_id , & ctr , 0 ) ,
" failed to call test_SetJob level 1 " ) ;
torture_assert ( tctx ,
test_GetJob_args ( tctx , b , handle , info [ i ] . info1 . job_id , 1 , & ginfo ) ,
" failed to call test_GetJob " ) ;
if ( strequal ( ginfo . info1 . document_name , document_name ) ) {
torture_warning ( tctx ,
2010-11-16 07:14:43 +03:00
" document_name did *NOT* change from '%s' to '%s' \n " ,
document_name , new_document_name ) ;
2010-04-28 02:05:41 +04:00
}
2010-03-26 15:37:42 +03:00
}
for ( i = 0 ; i < num_jobs ; i + + ) {
2010-04-28 01:33:05 +04:00
if ( ! test_SetJob ( tctx , b , handle , info [ i ] . info1 . job_id , NULL , SPOOLSS_JOB_CONTROL_PAUSE ) ) {
2010-04-28 01:31:25 +04:00
torture_warning ( tctx , " failed to pause printjob \n " ) ;
}
2010-04-28 01:33:05 +04:00
if ( ! test_SetJob ( tctx , b , handle , info [ i ] . info1 . job_id , NULL , SPOOLSS_JOB_CONTROL_RESUME ) ) {
2010-04-28 01:31:25 +04:00
torture_warning ( tctx , " failed to resume printjob \n " ) ;
}
2010-03-26 15:37:42 +03:00
}
return true ;
}
2010-03-25 02:37:45 +03:00
static bool test_DoPrintTest ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle )
{
bool ret = true ;
uint32_t num_jobs = 8 ;
uint32_t * job_ids ;
int i ;
2010-06-01 18:46:37 +04:00
torture_comment ( tctx , " Testing real print operations \n " ) ;
job_ids = talloc_zero_array ( tctx , uint32_t , num_jobs ) ;
for ( i = 0 ; i < num_jobs ; i + + ) {
2011-04-20 19:53:43 +04:00
ret & = test_DoPrintTest_add_one_job ( tctx , b , handle , " TorturePrintJob " , & job_ids [ i ] ) ;
2010-06-01 18:46:37 +04:00
}
for ( i = 0 ; i < num_jobs ; i + + ) {
ret & = test_SetJob ( tctx , b , handle , job_ids [ i ] , NULL , SPOOLSS_JOB_CONTROL_DELETE ) ;
}
2013-11-21 15:40:15 +04:00
for ( i = 0 ; i < num_jobs ; i + + ) {
ret & = test_DoPrintTest_add_one_job_v4 ( tctx , b , handle , " TorturePrintJob v4 " , & job_ids [ i ] ) ;
}
for ( i = 0 ; i < num_jobs ; i + + ) {
ret & = test_SetJob ( tctx , b , handle , job_ids [ i ] , NULL , SPOOLSS_JOB_CONTROL_DELETE ) ;
}
2010-06-01 18:46:37 +04:00
if ( ret = = true ) {
torture_comment ( tctx , " real print operations test succeeded \n \n " ) ;
}
return ret ;
}
static bool test_DoPrintTest_extended ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle )
{
bool ret = true ;
uint32_t num_jobs = 8 ;
uint32_t * job_ids ;
int i ;
torture_comment ( tctx , " Testing real print operations (extended) \n " ) ;
2010-03-25 02:37:45 +03:00
job_ids = talloc_zero_array ( tctx , uint32_t , num_jobs ) ;
for ( i = 0 ; i < num_jobs ; i + + ) {
2011-04-20 19:53:43 +04:00
ret & = test_DoPrintTest_add_one_job ( tctx , b , handle , " TorturePrintJob " , & job_ids [ i ] ) ;
2010-03-25 02:37:45 +03:00
}
2010-03-26 15:37:42 +03:00
ret & = test_DoPrintTest_check_jobs ( tctx , b , handle , num_jobs , job_ids ) ;
2005-06-06 19:03:16 +04:00
2010-03-25 02:37:45 +03:00
for ( i = 0 ; i < num_jobs ; i + + ) {
2010-04-28 01:33:05 +04:00
ret & = test_SetJob ( tctx , b , handle , job_ids [ i ] , NULL , SPOOLSS_JOB_CONTROL_DELETE ) ;
2010-03-25 02:37:45 +03:00
}
2005-06-06 19:03:16 +04:00
2010-06-01 18:46:37 +04:00
if ( ret = = true ) {
torture_comment ( tctx , " real print operations (extended) test succeeded \n \n " ) ;
}
2005-06-06 19:03:16 +04:00
return ret ;
}
2013-01-22 01:09:22 +04:00
static bool test_JobPrintProperties_equal ( struct torture_context * tctx ,
2016-09-07 08:50:14 +03:00
struct spoolss_PrintPropertyValue * got ,
struct spoolss_PrintNamedProperty * exp )
2013-01-22 01:09:22 +04:00
{
torture_assert_int_equal ( tctx ,
got - > ePropertyType ,
exp - > propertyValue . ePropertyType ,
" ePropertyType " ) ;
switch ( exp - > propertyValue . ePropertyType ) {
case kRpcPropertyTypeString :
torture_assert_str_equal ( tctx ,
got - > value . propertyString ,
exp - > propertyValue . value . propertyString ,
" propertyString " ) ;
break ;
case kRpcPropertyTypeInt32 :
torture_assert_int_equal ( tctx ,
got - > value . propertyInt32 ,
exp - > propertyValue . value . propertyInt32 ,
" propertyInt32 " ) ;
break ;
case kRpcPropertyTypeInt64 :
torture_assert_u64_equal ( tctx ,
got - > value . propertyInt64 ,
exp - > propertyValue . value . propertyInt64 ,
" propertyInt64 " ) ;
break ;
case kRpcPropertyTypeByte :
torture_assert_int_equal ( tctx ,
got - > value . propertyByte ,
exp - > propertyValue . value . propertyByte ,
" propertyByte " ) ;
break ;
case kRpcPropertyTypeBuffer :
torture_assert_int_equal ( tctx ,
got - > value . propertyBlob . cbBuf ,
exp - > propertyValue . value . propertyBlob . cbBuf ,
" propertyBlob.cbBuf " ) ;
torture_assert_mem_equal ( tctx ,
got - > value . propertyBlob . pBuf ,
exp - > propertyValue . value . propertyBlob . pBuf ,
exp - > propertyValue . value . propertyBlob . cbBuf ,
" propertyBlob.pBuf " ) ;
break ;
}
return true ;
}
static bool test_JobPrintProperties ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
uint32_t job_id )
{
2016-09-07 08:50:14 +03:00
struct spoolss_PrintNamedProperty in ;
struct spoolss_PrintPropertyValue out ;
2013-01-22 01:09:22 +04:00
int i ;
DATA_BLOB blob = data_blob_string_const ( " blob " ) ;
struct {
const char * property_name ;
2016-09-07 08:50:14 +03:00
enum spoolss_EPrintPropertyType type ;
union spoolss_PrintPropertyValueUnion value ;
2013-01-22 01:09:22 +04:00
WERROR expected_result ;
} tests [ ] = {
{
. property_name = " torture_property_string " ,
. type = kRpcPropertyTypeString ,
. value . propertyString = " torture_property_value_string " ,
} , {
. property_name = " torture_property_int32 " ,
. type = kRpcPropertyTypeInt32 ,
. value . propertyInt32 = 42 ,
} , {
. property_name = " torture_property_int64 " ,
. type = kRpcPropertyTypeInt64 ,
. value . propertyInt64 = 0xaffe ,
} , {
. property_name = " torture_property_byte " ,
. type = kRpcPropertyTypeByte ,
. value . propertyByte = 0xab ,
} , {
. property_name = " torture_property_buffer " ,
. type = kRpcPropertyTypeBuffer ,
. value . propertyBlob . cbBuf = blob . length ,
. value . propertyBlob . pBuf = blob . data ,
}
} ;
torture_assert ( tctx ,
test_JobPropertiesEnum ( tctx , b , handle , job_id ) ,
" failed to enum properties " ) ;
for ( i = 0 ; i < ARRAY_SIZE ( tests ) ; i + + ) {
in . propertyName = tests [ i ] . property_name ;
in . propertyValue . ePropertyType = tests [ i ] . type ;
in . propertyValue . value = tests [ i ] . value ;
torture_assert ( tctx ,
test_JobPropertySet ( tctx , b , handle , job_id , & in ) ,
" failed to set property " ) ;
torture_assert ( tctx ,
test_JobPropertyGetValue ( tctx , b , handle , job_id , in . propertyName , & out ) ,
" failed to get property " ) ;
torture_assert ( tctx ,
test_JobPrintProperties_equal ( tctx , & out , & in ) ,
" property unequal " ) ;
torture_assert ( tctx ,
test_JobPropertiesEnum ( tctx , b , handle , job_id ) ,
" failed to enum properties " ) ;
torture_assert ( tctx ,
test_JobPropertyDelete ( tctx , b , handle , job_id , in . propertyName ) ,
" failed to delete job property " ) ;
}
torture_assert ( tctx ,
test_JobPropertiesEnum ( tctx , b , handle , job_id ) ,
" failed to enum properties " ) ;
return true ;
}
static bool test_DoPrintTest_properties ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle )
{
uint32_t num_jobs = 8 ;
uint32_t * job_ids ;
int i ;
torture_comment ( tctx , " Testing real print operations (properties) \n " ) ;
job_ids = talloc_zero_array ( tctx , uint32_t , num_jobs ) ;
for ( i = 0 ; i < num_jobs ; i + + ) {
torture_assert ( tctx ,
test_DoPrintTest_add_one_job ( tctx , b , handle , " TorturePrintJob " , & job_ids [ i ] ) ,
" failed to create print job " ) ;
}
for ( i = 0 ; i < num_jobs ; i + + ) {
torture_assert ( tctx ,
test_JobPrintProperties ( tctx , b , handle , job_ids [ i ] ) ,
" failed to test job properties " ) ;
}
for ( i = 0 ; i < num_jobs ; i + + ) {
torture_assert ( tctx ,
test_SetJob ( tctx , b , handle , job_ids [ i ] , NULL , SPOOLSS_JOB_CONTROL_DELETE ) ,
" failed to delete printjob " ) ;
}
torture_comment ( tctx , " real print operations (properties) test succeeded \n \n " ) ;
return true ;
}
2009-06-30 13:38:41 +04:00
static bool test_PausePrinter ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2007-09-03 17:13:25 +04:00
struct policy_handle * handle )
2005-06-06 17:21:49 +04:00
{
NTSTATUS status ;
struct spoolss_SetPrinter r ;
2009-02-13 19:18:32 +03:00
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
info_ctr . level = 0 ;
info_ctr . info . info0 = NULL ;
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
2005-06-06 17:21:49 +04:00
r . in . handle = handle ;
2009-02-13 19:18:32 +03:00
r . in . info_ctr = & info_ctr ;
r . in . devmode_ctr = & devmode_ctr ;
r . in . secdesc_ctr = & secdesc_ctr ;
2005-06-06 17:21:49 +04:00
r . in . command = SPOOLSS_PRINTER_CONTROL_PAUSE ;
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE \n " ) ;
2005-06-06 17:21:49 +04:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_SetPrinter_r ( b , tctx , & r ) ;
2005-06-06 17:21:49 +04:00
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " SetPrinter failed " ) ;
2005-06-06 17:21:49 +04:00
2007-09-03 17:13:25 +04:00
torture_assert_werr_ok ( tctx , r . out . result , " SetPrinter failed " ) ;
2005-06-06 17:21:49 +04:00
2007-09-03 17:13:25 +04:00
return true ;
2005-06-06 17:21:49 +04:00
}
2009-06-30 13:38:41 +04:00
static bool test_ResumePrinter ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2007-09-03 17:13:25 +04:00
struct policy_handle * handle )
2005-06-06 17:21:49 +04:00
{
NTSTATUS status ;
struct spoolss_SetPrinter r ;
2009-02-13 19:18:32 +03:00
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
info_ctr . level = 0 ;
info_ctr . info . info0 = NULL ;
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
2005-06-06 17:21:49 +04:00
r . in . handle = handle ;
2009-02-13 19:18:32 +03:00
r . in . info_ctr = & info_ctr ;
r . in . devmode_ctr = & devmode_ctr ;
r . in . secdesc_ctr = & secdesc_ctr ;
2005-06-06 17:21:49 +04:00
r . in . command = SPOOLSS_PRINTER_CONTROL_RESUME ;
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME \n " ) ;
2005-06-06 17:21:49 +04:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_SetPrinter_r ( b , tctx , & r ) ;
2005-06-06 17:21:49 +04:00
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " SetPrinter failed " ) ;
2005-06-06 17:21:49 +04:00
2007-09-03 17:13:25 +04:00
torture_assert_werr_ok ( tctx , r . out . result , " SetPrinter failed " ) ;
2005-06-06 17:21:49 +04:00
2007-09-03 17:13:25 +04:00
return true ;
2005-06-06 17:21:49 +04:00
}
2014-05-21 23:55:59 +04:00
static bool test_printer_purge ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle )
{
NTSTATUS status ;
struct spoolss_SetPrinter r ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
info_ctr . level = 0 ;
info_ctr . info . info0 = NULL ;
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
r . in . handle = handle ;
r . in . info_ctr = & info_ctr ;
r . in . devmode_ctr = & devmode_ctr ;
r . in . secdesc_ctr = & secdesc_ctr ;
r . in . command = SPOOLSS_PRINTER_CONTROL_PURGE ;
torture_comment ( tctx , " Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PURGE \n " ) ;
status = dcerpc_spoolss_SetPrinter_r ( b , tctx , & r ) ;
torture_assert_ntstatus_ok ( tctx , status , " SetPrinter failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " SetPrinter failed " ) ;
return true ;
}
2010-11-10 12:19:01 +03:00
static bool test_GetPrinterData_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 )
2003-11-28 09:39:06 +03:00
{
NTSTATUS status ;
struct spoolss_GetPrinterData r ;
2009-02-06 19:09:30 +03:00
uint32_t needed ;
2009-03-16 18:01:10 +03:00
enum winreg_Type type ;
2009-03-14 03:36:31 +03:00
union spoolss_PrinterData data ;
2003-11-28 09:39:06 +03:00
r . in . handle = handle ;
r . in . value_name = value_name ;
2005-06-14 19:52:31 +04:00
r . in . offered = 0 ;
2009-02-06 19:09:30 +03:00
r . out . needed = & needed ;
2009-02-06 20:32:24 +03:00
r . out . type = & type ;
2010-03-05 00:40:31 +03:00
r . out . data = talloc_zero_array ( tctx , uint8_t , r . in . offered ) ;
2003-11-28 09:39:06 +03:00
2009-12-04 04:54:33 +03:00
torture_comment ( tctx , " Testing GetPrinterData(%s) \n " , r . in . value_name ) ;
2003-11-28 09:39:06 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_GetPrinterData_r ( b , tctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " GetPrinterData failed " ) ;
2003-11-28 09:39:06 +03:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_MORE_DATA ) ) {
2010-11-10 12:19:01 +03:00
if ( expected_type ) {
torture_assert_int_equal ( tctx , type , * expected_type , " unexpected type " ) ;
}
2009-02-06 19:09:30 +03:00
r . in . offered = needed ;
2010-03-05 00:40:31 +03:00
r . out . data = talloc_zero_array ( tctx , uint8_t , r . in . offered ) ;
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_GetPrinterData_r ( b , tctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " GetPrinterData failed " ) ;
2003-11-28 09:39:06 +03:00
}
2009-12-05 02:58:45 +03:00
torture_assert_werr_ok ( tctx , r . out . result ,
talloc_asprintf ( tctx , " GetPrinterData(%s) failed " , r . in . value_name ) ) ;
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_LEVEL ( spoolss_PrinterData , & data , type , needed , 1 ) ;
2009-12-12 03:51:13 +03:00
2009-12-04 04:54:33 +03:00
if ( type_p ) {
* type_p = type ;
}
if ( data_p ) {
2010-03-05 00:40:31 +03:00
* data_p = r . out . data ;
}
if ( needed_p ) {
* needed_p = needed ;
2009-12-04 04:54:33 +03:00
}
2007-09-03 17:13:25 +04:00
return true ;
2003-11-28 09:39:06 +03:00
}
2010-11-10 12:19:01 +03:00
static bool test_GetPrinterData ( 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_GetPrinterData_checktype ( tctx , b , handle , value_name ,
NULL , type_p , data_p , needed_p ) ;
}
static bool test_GetPrinterDataEx_checktype ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle ,
const char * key_name ,
const char * value_name ,
enum winreg_Type * expected_type ,
enum winreg_Type * type_p ,
uint8_t * * data_p ,
uint32_t * needed_p )
2003-11-28 14:50:33 +03:00
{
NTSTATUS status ;
struct spoolss_GetPrinterDataEx r ;
2009-03-16 18:01:10 +03:00
enum winreg_Type type ;
2009-02-06 15:38:59 +03:00
uint32_t needed ;
2009-12-05 02:58:45 +03:00
union spoolss_PrinterData data ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2003-11-28 14:50:33 +03:00
r . in . handle = handle ;
r . in . key_name = key_name ;
r . in . value_name = value_name ;
2005-06-14 19:52:31 +04:00
r . in . offered = 0 ;
2009-02-06 15:38:59 +03:00
r . out . type = & type ;
r . out . needed = & needed ;
2010-03-05 00:40:31 +03:00
r . out . data = talloc_zero_array ( tctx , uint8_t , r . in . offered ) ;
2003-11-28 14:50:33 +03:00
2009-12-04 04:54:33 +03:00
torture_comment ( tctx , " Testing GetPrinterDataEx(%s - %s) \n " ,
r . in . key_name , r . in . value_name ) ;
2003-11-28 14:50:33 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_GetPrinterDataEx_r ( b , tctx , & r ) ;
2003-11-28 14:50:33 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-04-12 16:14:29 +04:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE ) ) {
2007-09-03 17:13:25 +04:00
torture_skip ( tctx , " GetPrinterDataEx not supported by server \n " ) ;
2005-02-23 18:08:41 +03:00
}
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " GetPrinterDataEx failed " ) ;
2003-11-28 14:50:33 +03:00
}
if ( W_ERROR_EQUAL ( r . out . result , WERR_MORE_DATA ) ) {
2010-11-10 12:19:01 +03:00
if ( expected_type ) {
torture_assert_int_equal ( tctx , type , * expected_type , " unexpected type " ) ;
}
2009-02-06 15:38:59 +03:00
r . in . offered = needed ;
2010-03-05 00:40:31 +03:00
r . out . data = talloc_zero_array ( tctx , uint8_t , r . in . offered ) ;
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_GetPrinterDataEx_r ( b , tctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " GetPrinterDataEx failed " ) ;
2009-12-04 04:54:33 +03:00
}
2009-12-05 02:58:45 +03:00
torture_assert_werr_ok ( tctx , r . out . result ,
talloc_asprintf ( tctx , " GetPrinterDataEx(%s - %s) failed " , r . in . key_name , r . in . value_name ) ) ;
2009-12-04 04:54:33 +03:00
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_LEVEL ( spoolss_PrinterData , & data , type , needed , 1 ) ;
2009-12-12 03:51:13 +03:00
2009-12-04 04:54:33 +03:00
if ( type_p ) {
* type_p = type ;
}
2005-02-25 08:39:01 +03:00
2009-12-05 02:58:45 +03:00
if ( data_p ) {
2010-03-05 00:40:31 +03:00
* data_p = r . out . data ;
2003-11-28 14:50:33 +03:00
}
2010-03-01 16:26:30 +03:00
if ( needed_p ) {
* needed_p = needed ;
}
2007-09-03 17:13:25 +04:00
return true ;
2003-11-28 14:50:33 +03:00
}
2010-11-10 12:19:01 +03:00
static bool test_GetPrinterDataEx ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle ,
const char * key_name ,
const char * value_name ,
enum winreg_Type * type_p ,
uint8_t * * data_p ,
uint32_t * needed_p )
{
return test_GetPrinterDataEx_checktype ( tctx , p , handle , key_name , value_name ,
NULL , type_p , data_p , needed_p ) ;
}
2010-04-20 21:29:12 +04:00
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 ,
test_GetPrinterData ( tctx , b , handle , " Architecture " , & type , & data , & needed ) ,
" failed to get Architecture " ) ;
torture_assert_int_equal ( tctx , type , REG_SZ , " unexpected type " ) ;
blob = data_blob_const ( data , needed ) ;
2010-05-09 19:20:01 +04:00
* architecture = reg_val_data_string ( tctx , REG_SZ , blob ) ;
2010-04-20 21:29:12 +04:00
return true ;
}
2009-12-04 04:54:33 +03:00
static bool test_GetPrinterData_list ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2009-12-04 04:54:33 +03:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-12-04 04:54:33 +03:00
const char * list [ ] = {
" W3SvcInstalled " ,
" BeepEnabled " ,
" EventLog " ,
2009-12-05 02:58:45 +03:00
/* "NetPopup", not on w2k8 */
/* "NetPopupToComputer", not on w2k8 */
2009-12-04 04:54:33 +03:00
" MajorVersion " ,
" MinorVersion " ,
" DefaultSpoolDirectory " ,
" Architecture " ,
" DsPresent " ,
" OSVersion " ,
2009-12-05 02:58:45 +03:00
/* "OSVersionEx", not on s3 */
2009-12-04 04:54:33 +03:00
" DNSMachineName "
} ;
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( list ) ; i + + ) {
2015-03-03 10:48:00 +03:00
enum winreg_Type type = REG_NONE ;
2016-09-01 20:54:46 +03:00
enum winreg_Type type_ex1 = REG_NONE ;
enum winreg_Type type_ex2 = REG_NONE ;
2015-03-03 10:48:00 +03:00
uint8_t * data ;
2016-09-01 20:54:46 +03:00
uint8_t * data_ex1 = NULL ;
uint8_t * data_ex2 = NULL ;
2015-03-03 10:48:00 +03:00
uint32_t needed ;
2016-09-01 20:54:46 +03:00
uint32_t needed_ex1 = 0 ;
uint32_t needed_ex2 = 0 ;
2009-12-05 02:58:45 +03:00
2010-05-19 01:40:43 +04:00
torture_assert ( tctx , test_GetPrinterData ( tctx , b , & ctx - > server_handle , list [ i ] , & type , & data , & needed ) ,
2009-12-05 02:58:45 +03:00
talloc_asprintf ( tctx , " GetPrinterData failed on %s \n " , list [ i ] ) ) ;
2016-09-01 20:54:46 +03:00
torture_assert ( tctx , test_GetPrinterDataEx ( tctx , p , & ctx - > server_handle , " random_string " , list [ i ] , & type_ex1 , & data_ex1 , & needed_ex1 ) ,
2009-12-05 02:58:45 +03:00
talloc_asprintf ( tctx , " GetPrinterDataEx failed on %s \n " , list [ i ] ) ) ;
2016-09-01 20:54:46 +03:00
torture_assert ( tctx , test_GetPrinterDataEx ( tctx , p , & ctx - > server_handle , " " , list [ i ] , & type_ex2 , & data_ex2 , & needed_ex2 ) ,
talloc_asprintf ( tctx , " GetPrinterDataEx failed on %s \n " , list [ i ] ) ) ;
torture_assert_int_equal ( tctx , type , type_ex1 , " type mismatch " ) ;
torture_assert_int_equal ( tctx , type , type_ex2 , " type mismatch " ) ;
torture_assert_int_equal ( tctx , needed , needed_ex1 , " needed mismatch " ) ;
torture_assert_int_equal ( tctx , needed , needed_ex2 , " needed mismatch " ) ;
torture_assert_mem_equal ( tctx , data , data_ex1 , needed , " data mismatch " ) ;
torture_assert_mem_equal ( tctx , data , data_ex2 , needed , " data mismatch " ) ;
2009-12-04 04:54:33 +03:00
}
2009-12-05 02:58:45 +03:00
return true ;
2009-12-04 04:54:33 +03:00
}
2010-03-13 03:05:24 +03:00
static bool test_EnumPrinterData ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle ,
uint32_t enum_index ,
uint32_t value_offered ,
uint32_t data_offered ,
enum winreg_Type * type_p ,
uint32_t * value_needed_p ,
uint32_t * data_needed_p ,
const char * * value_name_p ,
uint8_t * * data_p ,
WERROR * result_p )
2003-11-18 08:54:14 +03:00
{
struct spoolss_EnumPrinterData r ;
2010-03-13 03:05:24 +03:00
uint32_t data_needed ;
uint32_t value_needed ;
enum winreg_Type type ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2003-11-18 08:54:14 +03:00
r . in . handle = handle ;
2010-03-13 03:05:24 +03:00
r . in . enum_index = enum_index ;
r . in . value_offered = value_offered ;
r . in . data_offered = data_offered ;
r . out . data_needed = & data_needed ;
r . out . value_needed = & value_needed ;
r . out . type = & type ;
r . out . data = talloc_zero_array ( tctx , uint8_t , r . in . data_offered ) ;
r . out . value_name = talloc_zero_array ( tctx , const char , r . in . value_offered ) ;
2008-02-13 12:36:49 +03:00
2010-03-13 03:05:24 +03:00
torture_comment ( tctx , " Testing EnumPrinterData(%d) \n " , enum_index ) ;
2008-02-13 12:36:49 +03:00
2010-03-13 03:05:24 +03:00
torture_assert_ntstatus_ok ( tctx ,
2010-03-16 13:45:51 +03:00
dcerpc_spoolss_EnumPrinterData_r ( b , tctx , & r ) ,
2010-03-13 03:05:24 +03:00
" EnumPrinterData failed " ) ;
2003-11-18 08:54:14 +03:00
2010-03-13 03:05:24 +03:00
if ( type_p ) {
* type_p = type ;
}
if ( value_needed_p ) {
* value_needed_p = value_needed ;
}
if ( data_needed_p ) {
* data_needed_p = data_needed ;
}
if ( value_name_p ) {
* value_name_p = r . out . value_name ;
}
if ( data_p ) {
* data_p = r . out . data ;
}
if ( result_p ) {
* result_p = r . out . result ;
}
2003-11-18 08:54:14 +03:00
2010-03-13 03:05:24 +03:00
return true ;
}
2003-11-18 08:54:14 +03:00
2010-03-13 03:05:24 +03:00
static bool test_EnumPrinterData_all ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle )
{
uint32_t enum_index = 0 ;
enum winreg_Type type ;
uint32_t value_needed ;
uint32_t data_needed ;
uint8_t * data ;
const char * value_name ;
WERROR result ;
2003-11-18 08:54:14 +03:00
2010-03-16 15:52:48 +03:00
torture_comment ( tctx , " Testing EnumPrinterData \n " ) ;
2010-03-13 03:05:24 +03:00
do {
torture_assert ( tctx ,
test_EnumPrinterData ( tctx , p , handle , enum_index , 0 , 0 ,
& type , & value_needed , & data_needed ,
& value_name , & data , & result ) ,
" EnumPrinterData failed " ) ;
2003-11-18 08:54:14 +03:00
2010-03-13 03:05:24 +03:00
if ( W_ERROR_EQUAL ( result , WERR_NO_MORE_ITEMS ) ) {
2009-12-04 00:38:38 +03:00
break ;
}
2010-03-13 03:05:24 +03:00
torture_assert ( tctx ,
test_EnumPrinterData ( tctx , p , handle , enum_index , value_needed , data_needed ,
& type , & value_needed , & data_needed ,
& value_name , & data , & result ) ,
" EnumPrinterData failed " ) ;
2003-11-28 09:39:06 +03:00
2010-03-13 03:05:24 +03:00
if ( W_ERROR_EQUAL ( result , WERR_NO_MORE_ITEMS ) ) {
break ;
}
2003-11-28 14:50:33 +03:00
2010-03-13 03:05:24 +03:00
enum_index + + ;
2003-11-28 09:39:06 +03:00
2010-03-13 03:05:24 +03:00
} while ( W_ERROR_IS_OK ( result ) ) ;
2003-11-18 08:54:14 +03:00
2010-03-16 15:52:48 +03:00
torture_comment ( tctx , " EnumPrinterData test succeeded \n " ) ;
2007-10-07 02:28:14 +04:00
return true ;
2003-11-18 08:54:14 +03:00
}
2009-06-30 13:38:41 +04:00
static bool test_EnumPrinterDataEx ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-12-04 00:38:38 +03:00
struct policy_handle * handle ,
2010-03-11 01:08:09 +03:00
const char * key_name ,
uint32_t * count_p ,
struct spoolss_PrinterEnumValues * * info_p )
2005-03-02 03:15:06 +03:00
{
struct spoolss_EnumPrinterDataEx r ;
2009-03-18 03:39:49 +03:00
struct spoolss_PrinterEnumValues * info ;
2009-02-06 15:44:44 +03:00
uint32_t needed ;
uint32_t count ;
2005-03-02 03:15:06 +03:00
r . in . handle = handle ;
2009-12-04 00:38:38 +03:00
r . in . key_name = key_name ;
2005-06-14 19:52:31 +04:00
r . in . offered = 0 ;
2009-02-06 15:44:44 +03:00
r . out . needed = & needed ;
r . out . count = & count ;
2009-03-18 03:39:49 +03:00
r . out . info = & info ;
2005-03-02 03:15:06 +03:00
2009-12-04 00:38:38 +03:00
torture_comment ( tctx , " Testing EnumPrinterDataEx(%s) \n " , key_name ) ;
2005-03-02 03:15:06 +03:00
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_EnumPrinterDataEx_r ( b , tctx , & r ) ,
2009-12-04 00:38:38 +03:00
" EnumPrinterDataEx failed " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_MORE_DATA ) ) {
r . in . offered = needed ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_EnumPrinterDataEx_r ( b , tctx , & r ) ,
2009-12-04 00:38:38 +03:00
" EnumPrinterDataEx failed " ) ;
}
2005-03-02 03:15:06 +03:00
2009-12-04 00:38:38 +03:00
torture_assert_werr_ok ( tctx , r . out . result , " EnumPrinterDataEx failed " ) ;
2005-03-02 03:15:06 +03:00
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_ENUM ( spoolss_EnumPrinterDataEx , info , count , needed , 1 ) ;
2009-12-12 03:51:13 +03:00
2010-03-11 01:08:09 +03:00
if ( count_p ) {
* count_p = count ;
}
if ( info_p ) {
* info_p = info ;
}
2007-09-03 17:13:25 +04:00
return true ;
2005-03-02 03:15:06 +03:00
}
2010-03-15 16:11:44 +03:00
static bool test_SetPrinterData ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-03-15 16:11:44 +03:00
struct policy_handle * handle ,
const char * value_name ,
enum winreg_Type type ,
uint8_t * data ,
uint32_t offered ) ;
2010-03-15 16:55:25 +03:00
static bool test_DeletePrinterData ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-03-15 16:55:25 +03:00
struct policy_handle * handle ,
const char * value_name ) ;
2010-03-15 16:11:44 +03:00
2010-03-13 03:07:43 +03:00
static bool test_EnumPrinterData_consistency ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle )
{
uint32_t count ;
struct spoolss_PrinterEnumValues * info ;
int i ;
uint32_t value_needed , data_needed ;
uint32_t value_offered , data_offered ;
WERROR result ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-03-13 03:07:43 +03:00
2010-03-15 16:11:44 +03:00
enum winreg_Type type ;
DATA_BLOB blob ;
2010-03-15 12:20:06 +03:00
torture_comment ( tctx , " Testing EnumPrinterData vs EnumPrinterDataEx consistency \n " ) ;
2010-03-13 03:07:43 +03:00
2010-05-21 00:13:48 +04:00
torture_assert ( tctx , push_reg_sz ( tctx , & blob , " torture_data1 " ) , " " ) ;
type = REG_SZ ;
2010-03-15 16:11:44 +03:00
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_SetPrinterData ( tctx , b , handle , " torture_value1 " , type , blob . data , blob . length ) ,
2010-03-15 18:11:43 +03:00
" SetPrinterData failed " ) ;
blob = data_blob_string_const ( " torture_data2 " ) ;
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_SetPrinterData ( tctx , b , handle , " torture_value2 " , REG_BINARY , blob . data , blob . length ) ,
2010-03-15 18:11:43 +03:00
" SetPrinterData failed " ) ;
blob = data_blob_talloc ( tctx , NULL , 4 ) ;
SIVAL ( blob . data , 0 , 0x11223344 ) ;
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_SetPrinterData ( tctx , b , handle , " torture_value3 " , type , blob . data , blob . length ) ,
2010-03-15 16:11:44 +03:00
" SetPrinterData failed " ) ;
2010-03-13 03:07:43 +03:00
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_EnumPrinterDataEx ( tctx , b , handle , " PrinterDriverData " , & count , & info ) ,
2010-03-13 03:07:43 +03:00
" failed to call EnumPrinterDataEx " ) ;
/* get the max sizes for value and data */
torture_assert ( tctx ,
test_EnumPrinterData ( tctx , p , handle , 0 , 0 , 0 ,
NULL , & value_needed , & data_needed ,
NULL , NULL , & result ) ,
" EnumPrinterData failed " ) ;
torture_assert_werr_ok ( tctx , result , " unexpected result " ) ;
/* check if the reply from the EnumPrinterData really matches max values */
for ( i = 0 ; i < count ; i + + ) {
if ( info [ i ] . value_name_len > value_needed ) {
torture_fail ( tctx ,
talloc_asprintf ( tctx ,
" EnumPrinterDataEx gave a reply with value length %d which is larger then expected max value length %d from EnumPrinterData " ,
info [ i ] . value_name_len , value_needed ) ) ;
}
if ( info [ i ] . data_length > data_needed ) {
torture_fail ( tctx ,
talloc_asprintf ( tctx ,
" EnumPrinterDataEx gave a reply with data length %d which is larger then expected max data length %d from EnumPrinterData " ,
info [ i ] . data_length , data_needed ) ) ;
}
}
/* assuming that both EnumPrinterData and EnumPrinterDataEx do either
* sort or not sort the replies by value name , we should be able to do
* the following entry comparison */
data_offered = data_needed ;
value_offered = value_needed ;
for ( i = 0 ; i < count ; i + + ) {
const char * value_name ;
uint8_t * data ;
torture_assert ( tctx ,
test_EnumPrinterData ( tctx , p , handle , i , value_offered , data_offered ,
& type , & value_needed , & data_needed ,
& value_name , & data , & result ) ,
" EnumPrinterData failed " ) ;
if ( i - 1 = = count ) {
torture_assert_werr_equal ( tctx , result , WERR_NO_MORE_ITEMS ,
" unexpected result " ) ;
break ;
} else {
torture_assert_werr_ok ( tctx , result , " unexpected result " ) ;
}
torture_assert_int_equal ( tctx , type , info [ i ] . type , " type mismatch " ) ;
torture_assert_int_equal ( tctx , value_needed , info [ i ] . value_name_len , " value name length mismatch " ) ;
torture_assert_str_equal ( tctx , value_name , info [ i ] . value_name , " value name mismatch " ) ;
torture_assert_int_equal ( tctx , data_needed , info [ i ] . data_length , " data length mismatch " ) ;
torture_assert_mem_equal ( tctx , data , info [ i ] . data - > data , info [ i ] . data_length , " data mismatch " ) ;
}
2010-03-15 16:55:25 +03:00
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_DeletePrinterData ( tctx , b , handle , " torture_value1 " ) ,
2010-03-15 18:11:43 +03:00
" DeletePrinterData failed " ) ;
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_DeletePrinterData ( tctx , b , handle , " torture_value2 " ) ,
2010-03-15 18:11:43 +03:00
" DeletePrinterData failed " ) ;
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_DeletePrinterData ( tctx , b , handle , " torture_value3 " ) ,
2010-03-15 16:55:25 +03:00
" DeletePrinterData failed " ) ;
2010-03-15 16:11:44 +03:00
torture_comment ( tctx , " EnumPrinterData vs EnumPrinterDataEx consistency test succeeded \n \n " ) ;
2010-03-13 03:07:43 +03:00
return true ;
}
2005-03-02 03:15:06 +03:00
2009-06-30 13:38:41 +04:00
static bool test_DeletePrinterData ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-06-30 13:38:41 +04:00
struct policy_handle * handle ,
2004-10-28 17:40:50 +04:00
const char * value_name )
2003-11-28 13:34:58 +03:00
{
NTSTATUS status ;
struct spoolss_DeletePrinterData r ;
r . in . handle = handle ;
r . in . value_name = value_name ;
2009-12-04 04:54:33 +03:00
torture_comment ( tctx , " Testing DeletePrinterData(%s) \n " ,
r . in . value_name ) ;
2003-11-28 13:34:58 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_DeletePrinterData_r ( b , tctx , & r ) ;
2003-11-28 13:34:58 +03:00
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " DeletePrinterData failed " ) ;
2009-12-04 00:38:38 +03:00
torture_assert_werr_ok ( tctx , r . out . result , " DeletePrinterData failed " ) ;
2003-11-28 13:34:58 +03:00
2007-09-03 17:13:25 +04:00
return true ;
2003-11-28 13:34:58 +03:00
}
2009-12-04 04:54:33 +03:00
static bool test_DeletePrinterDataEx ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-12-04 04:54:33 +03:00
struct policy_handle * handle ,
const char * key_name ,
const char * value_name )
{
struct spoolss_DeletePrinterDataEx r ;
r . in . handle = handle ;
r . in . key_name = key_name ;
r . in . value_name = value_name ;
torture_comment ( tctx , " Testing DeletePrinterDataEx(%s - %s) \n " ,
r . in . key_name , r . in . value_name ) ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-16 13:45:51 +03:00
dcerpc_spoolss_DeletePrinterDataEx_r ( b , tctx , & r ) ,
2009-12-04 04:54:33 +03:00
" DeletePrinterDataEx failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" DeletePrinterDataEx failed " ) ;
return true ;
}
static bool test_DeletePrinterKey ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-12-04 04:54:33 +03:00
struct policy_handle * handle ,
const char * key_name )
{
struct spoolss_DeletePrinterKey r ;
r . in . handle = handle ;
r . in . key_name = key_name ;
torture_comment ( tctx , " Testing DeletePrinterKey(%s) \n " , r . in . key_name ) ;
if ( strequal ( key_name , " " ) & & ! torture_setting_bool ( tctx , " dangerous " , false ) ) {
torture_skip ( tctx , " not wiping out printer registry - enable dangerous tests to use \n " ) ;
return true ;
}
torture_assert_ntstatus_ok ( tctx ,
2010-03-16 13:45:51 +03:00
dcerpc_spoolss_DeletePrinterKey_r ( b , tctx , & r ) ,
2009-12-04 04:54:33 +03:00
" DeletePrinterKey failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" DeletePrinterKey failed " ) ;
return true ;
}
2010-03-05 16:42:10 +03:00
static bool test_winreg_OpenHKLM ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-03-05 16:42:10 +03:00
struct policy_handle * handle )
{
struct winreg_OpenHKLM r ;
r . in . system_name = NULL ;
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
r . out . handle = handle ;
torture_comment ( tctx , " Testing winreg_OpenHKLM \n " ) ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_winreg_OpenHKLM_r ( b , tctx , & r ) , " OpenHKLM failed " ) ;
2010-03-05 16:42:10 +03:00
torture_assert_werr_ok ( tctx , r . out . result , " OpenHKLM failed " ) ;
return true ;
}
static void init_winreg_String ( struct winreg_String * name , const char * s )
{
name - > name = s ;
if ( s ) {
name - > name_len = 2 * ( strlen_m ( s ) + 1 ) ;
name - > name_size = name - > name_len ;
} else {
name - > name_len = 0 ;
name - > name_size = 0 ;
}
}
2010-04-09 17:58:01 +04:00
static bool test_winreg_OpenKey_opts ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * hive_handle ,
const char * keyname ,
uint32_t options ,
struct policy_handle * key_handle )
2010-03-05 16:42:10 +03:00
{
struct winreg_OpenKey r ;
r . in . parent_handle = hive_handle ;
init_winreg_String ( & r . in . keyname , keyname ) ;
2010-04-09 17:58:01 +04:00
r . in . options = options ;
2010-03-05 16:42:10 +03:00
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
r . out . handle = key_handle ;
torture_comment ( tctx , " Testing winreg_OpenKey(%s) \n " , keyname ) ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_winreg_OpenKey_r ( b , tctx , & r ) , " OpenKey failed " ) ;
2010-03-05 16:42:10 +03:00
torture_assert_werr_ok ( tctx , r . out . result , " OpenKey failed " ) ;
return true ;
}
2010-04-09 17:58:01 +04:00
static bool test_winreg_OpenKey ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * hive_handle ,
const char * keyname ,
struct policy_handle * key_handle )
{
return test_winreg_OpenKey_opts ( tctx , b , hive_handle , keyname ,
REG_OPTION_NON_VOLATILE , key_handle ) ;
}
2010-03-05 16:42:10 +03:00
static bool test_winreg_CloseKey ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-03-05 16:42:10 +03:00
struct policy_handle * handle )
{
struct winreg_CloseKey r ;
r . in . handle = handle ;
r . out . handle = handle ;
torture_comment ( tctx , " Testing winreg_CloseKey \n " ) ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_winreg_CloseKey_r ( b , tctx , & r ) , " CloseKey failed " ) ;
2010-03-05 16:42:10 +03:00
torture_assert_werr_ok ( tctx , r . out . result , " CloseKey failed " ) ;
return true ;
}
2010-03-11 20:37:02 +03:00
bool test_winreg_QueryValue ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-03-11 20:37:02 +03:00
struct policy_handle * handle ,
const char * value_name ,
enum winreg_Type * type_p ,
uint32_t * data_size_p ,
uint32_t * data_length_p ,
uint8_t * * data_p )
2010-03-05 16:42:10 +03:00
{
struct winreg_QueryValue r ;
enum winreg_Type type = REG_NONE ;
uint32_t data_size = 0 ;
uint32_t data_length = 0 ;
struct winreg_String valuename ;
2010-03-10 02:16:46 +03:00
uint8_t * data = NULL ;
2010-03-05 16:42:10 +03:00
init_winreg_String ( & valuename , value_name ) ;
2010-03-10 02:16:46 +03:00
data = talloc_zero_array ( tctx , uint8_t , 0 ) ;
2010-03-05 16:42:10 +03:00
r . in . handle = handle ;
r . in . value_name = & valuename ;
r . in . type = & type ;
r . in . data_size = & data_size ;
r . in . data_length = & data_length ;
2010-03-10 02:16:46 +03:00
r . in . data = data ;
2010-03-05 16:42:10 +03:00
r . out . type = & type ;
2010-03-10 02:16:46 +03:00
r . out . data = data ;
2010-03-05 16:42:10 +03:00
r . out . data_size = & data_size ;
r . out . data_length = & data_length ;
torture_comment ( tctx , " Testing winreg_QueryValue(%s) \n " , value_name ) ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_winreg_QueryValue_r ( b , tctx , & r ) , " QueryValue failed " ) ;
2010-03-05 16:42:10 +03:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_MORE_DATA ) ) {
* r . in . data_size = * r . out . data_size ;
2010-03-10 02:16:46 +03:00
data = talloc_zero_array ( tctx , uint8_t , * r . in . data_size ) ;
r . in . data = data ;
r . out . data = data ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_winreg_QueryValue_r ( b , tctx , & r ) , " QueryValue failed " ) ;
2010-03-05 16:42:10 +03:00
}
torture_assert_werr_ok ( tctx , r . out . result , " QueryValue failed " ) ;
if ( type_p ) {
* type_p = * r . out . type ;
}
if ( data_size_p ) {
* data_size_p = * r . out . data_size ;
}
if ( data_length_p ) {
* data_length_p = * r . out . data_length ;
}
if ( data_p ) {
* data_p = r . out . data ;
}
return true ;
}
2010-03-13 00:45:33 +03:00
static bool test_winreg_query_printerdata ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-03-13 00:45:33 +03:00
struct policy_handle * handle ,
const char * printer_name ,
const char * key_name ,
const char * value_name ,
enum winreg_Type * w_type ,
uint32_t * w_size ,
uint32_t * w_length ,
uint8_t * * w_data )
{
const char * printer_key ;
struct policy_handle key_handle ;
printer_key = talloc_asprintf ( tctx , " %s \\ %s \\ %s " ,
2010-04-06 15:23:22 +04:00
TOP_LEVEL_PRINT_PRINTERS_KEY , printer_name , key_name ) ;
2010-03-13 00:45:33 +03:00
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_winreg_OpenKey ( tctx , b , handle , printer_key , & key_handle ) , " " ) ;
2010-03-13 00:45:33 +03:00
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_winreg_QueryValue ( tctx , b , & key_handle , value_name , w_type , w_size , w_length , w_data ) , " " ) ;
2010-03-13 00:45:33 +03:00
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_winreg_CloseKey ( tctx , b , & key_handle ) , " " ) ;
2010-03-13 00:45:33 +03:00
return true ;
}
2010-04-06 15:23:22 +04:00
static bool test_GetForm_winreg ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * key_name ,
const char * form_name ,
enum winreg_Type * w_type ,
uint32_t * w_size ,
uint32_t * w_length ,
uint8_t * * w_data )
{
struct policy_handle key_handle ;
torture_assert ( tctx ,
test_winreg_OpenKey ( tctx , b , handle , key_name , & key_handle ) , " " ) ;
torture_assert ( tctx ,
test_winreg_QueryValue ( tctx , b , & key_handle , form_name , w_type , w_size , w_length , w_data ) , " " ) ;
torture_assert ( tctx ,
test_winreg_CloseKey ( tctx , b , & key_handle ) , " " ) ;
return true ;
}
2010-04-09 17:58:01 +04:00
static bool test_winreg_symbolic_link ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * symlink_keyname ,
const char * symlink_destination )
{
/* check if the first key is a symlink to the second key */
enum winreg_Type w_type ;
uint32_t w_size ;
uint32_t w_length ;
uint8_t * w_data ;
struct policy_handle key_handle ;
DATA_BLOB blob ;
const char * str ;
2010-04-09 21:54:31 +04:00
if ( torture_setting_bool ( tctx , " samba3 " , false ) ) {
torture_skip ( tctx , " skip winreg symlink test against samba " ) ;
}
2010-04-09 17:58:01 +04:00
torture_assert ( tctx ,
test_winreg_OpenKey_opts ( tctx , b , handle , symlink_keyname , REG_OPTION_OPEN_LINK , & key_handle ) ,
" failed to open key link " ) ;
torture_assert ( tctx ,
test_winreg_QueryValue ( tctx , b , & key_handle ,
" SymbolicLinkValue " ,
& w_type , & w_size , & w_length , & w_data ) ,
" failed to query for 'SymbolicLinkValue' attribute " ) ;
torture_assert_int_equal ( tctx , w_type , REG_LINK , " unexpected type " ) ;
blob = data_blob ( w_data , w_size ) ;
2010-05-09 19:20:01 +04:00
str = reg_val_data_string ( tctx , REG_SZ , blob ) ;
2010-04-09 17:58:01 +04:00
torture_assert_str_equal ( tctx , str , symlink_destination , " unexpected symlink target string " ) ;
torture_assert ( tctx ,
test_winreg_CloseKey ( tctx , b , & key_handle ) ,
" failed to close key link " ) ;
return true ;
}
2010-04-08 18:09:36 +04:00
static const char * strip_unc ( const char * unc )
{
char * name ;
if ( ! unc ) {
return NULL ;
}
if ( unc [ 0 ] = = ' \\ ' & & unc [ 1 ] = = ' \\ ' ) {
unc + = 2 ;
}
name = strchr ( unc , ' \\ ' ) ;
if ( name ) {
return name + 1 ;
}
return unc ;
}
2010-04-08 17:00:34 +04:00
static bool test_GetPrinterInfo_winreg ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * printer_name ,
struct dcerpc_binding_handle * winreg_handle ,
struct policy_handle * hive_handle )
{
union spoolss_PrinterInfo info ;
const char * keys [ ] = {
TOP_LEVEL_CONTROL_PRINTERS_KEY ,
TOP_LEVEL_PRINT_PRINTERS_KEY
} ;
int i ;
2010-04-08 18:09:36 +04:00
const char * printername , * sharename ;
2010-04-08 17:00:34 +04:00
torture_comment ( tctx , " Testing Printer Info and winreg consistency \n " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , handle , 2 , & info ) ,
" failed to get printer info level 2 " ) ;
2010-04-08 18:09:36 +04:00
printername = strip_unc ( info . info2 . printername ) ;
sharename = strip_unc ( info . info2 . sharename ) ;
2010-04-20 20:16:03 +04:00
# define test_sz(wname, iname) \
2010-04-08 17:00:34 +04:00
do { \
DATA_BLOB blob ; \
const char * str ; \
enum winreg_Type w_type ; \
uint32_t w_size ; \
uint32_t w_length ; \
uint8_t * w_data ; \
torture_assert ( tctx , \
test_winreg_QueryValue ( tctx , winreg_handle , & key_handle , wname , \
& w_type , & w_size , & w_length , & w_data ) , \
" failed to query winreg " ) ; \
torture_assert_int_equal ( tctx , w_type , REG_SZ , " unexpected type " ) ; \
blob = data_blob ( w_data , w_size ) ; \
2010-05-09 19:20:01 +04:00
str = reg_val_data_string ( tctx , REG_SZ , blob ) ; \
2010-04-08 17:00:34 +04:00
if ( w_size = = 2 & & iname = = NULL ) { \
/*torture_comment(tctx, "%s: \"\", %s: (null)\n", #wname, #iname);\ */ \
} else { \
torture_assert_str_equal ( tctx , str , iname , \
talloc_asprintf ( tctx , " %s - %s mismatch " , # wname , # iname ) ) ; \
} \
} while ( 0 ) ;
2010-04-20 20:16:03 +04:00
# define test_dword(wname, iname) \
2010-04-08 17:00:34 +04:00
do { \
uint32_t value ; \
enum winreg_Type w_type ; \
uint32_t w_size ; \
uint32_t w_length ; \
uint8_t * w_data ; \
torture_assert ( tctx , \
test_winreg_QueryValue ( tctx , winreg_handle , & key_handle , wname , \
& w_type , & w_size , & w_length , & w_data ) , \
" failed to query winreg " ) ; \
torture_assert_int_equal ( tctx , w_type , REG_DWORD , " unexpected type " ) ; \
torture_assert_int_equal ( tctx , w_size , 4 , " unexpected size " ) ; \
torture_assert_int_equal ( tctx , w_length , 4 , " unexpected length " ) ; \
value = IVAL ( w_data , 0 ) ; \
torture_assert_int_equal ( tctx , value , iname , \
talloc_asprintf ( tctx , " %s - %s mismatch " , # wname , # iname ) ) ; \
} while ( 0 ) ;
2010-12-20 18:02:02 +03:00
# define test_binary(wname, iname) \
do { \
enum winreg_Type w_type ; \
uint32_t w_size ; \
uint32_t w_length ; \
uint8_t * w_data ; \
torture_assert ( tctx , \
test_winreg_QueryValue ( tctx , winreg_handle , & key_handle , wname , \
& w_type , & w_size , & w_length , & w_data ) , \
" failed to query winreg " ) ; \
torture_assert_int_equal ( tctx , w_type , REG_BINARY , " unexpected type " ) ; \
torture_assert_int_equal ( tctx , w_size , iname . length , " unexpected length " ) ; \
torture_assert_mem_equal ( tctx , w_data , iname . data , w_size , \
" binary unequal " ) ; \
} while ( 0 ) ;
2010-04-20 20:16:03 +04:00
# define test_dm(wname, iname) \
2010-04-08 17:00:34 +04:00
do { \
DATA_BLOB blob ; \
struct spoolss_DeviceMode dm ; \
enum ndr_err_code ndr_err ; \
enum winreg_Type w_type ; \
uint32_t w_size ; \
uint32_t w_length ; \
uint8_t * w_data ; \
torture_assert ( tctx , \
test_winreg_QueryValue ( tctx , winreg_handle , & key_handle , wname , \
& w_type , & w_size , & w_length , & w_data ) , \
" failed to query winreg " ) ; \
torture_assert_int_equal ( tctx , w_type , REG_BINARY , " unexpected type " ) ; \
blob = data_blob ( w_data , w_size ) ; \
2010-05-09 19:20:01 +04:00
ndr_err = ndr_pull_struct_blob ( & blob , tctx , & dm , \
2010-04-08 17:00:34 +04:00
( ndr_pull_flags_fn_t ) ndr_pull_spoolss_DeviceMode ) ; \
torture_assert_ndr_success ( tctx , ndr_err , " failed to unmarshall dm " ) ; \
torture_assert ( tctx , test_devicemode_equal ( tctx , & dm , iname ) , \
" dm unequal " ) ; \
} while ( 0 ) ;
2010-04-20 20:16:03 +04:00
# define test_sd(wname, iname) \
2010-04-08 17:00:34 +04:00
do { \
DATA_BLOB blob ; \
struct security_descriptor sd ; \
enum ndr_err_code ndr_err ; \
enum winreg_Type w_type ; \
uint32_t w_size ; \
uint32_t w_length ; \
uint8_t * w_data ; \
torture_assert ( tctx , \
test_winreg_QueryValue ( tctx , winreg_handle , & key_handle , wname , \
& w_type , & w_size , & w_length , & w_data ) , \
" failed to query winreg " ) ; \
torture_assert_int_equal ( tctx , w_type , REG_BINARY , " unexpected type " ) ; \
blob = data_blob ( w_data , w_size ) ; \
2010-05-09 19:20:01 +04:00
ndr_err = ndr_pull_struct_blob ( & blob , tctx , & sd , \
2010-04-08 17:00:34 +04:00
( ndr_pull_flags_fn_t ) ndr_pull_security_descriptor ) ; \
torture_assert_ndr_success ( tctx , ndr_err , " failed to unmarshall sd " ) ; \
torture_assert ( tctx , test_security_descriptor_equal ( tctx , & sd , iname ) , \
" sd unequal " ) ; \
} while ( 0 ) ;
2010-04-27 01:35:19 +04:00
# define test_multi_sz(wname, iname) \
do { \
DATA_BLOB blob ; \
const char * * array ; \
enum winreg_Type w_type ; \
uint32_t w_size ; \
uint32_t w_length ; \
uint8_t * w_data ; \
int i ; \
torture_assert ( tctx , \
test_winreg_QueryValue ( tctx , winreg_handle , & key_handle , wname , \
& w_type , & w_size , & w_length , & w_data ) , \
" failed to query winreg " ) ; \
torture_assert_int_equal ( tctx , w_type , REG_MULTI_SZ , " unexpected type " ) ; \
blob = data_blob ( w_data , w_size ) ; \
torture_assert ( tctx , \
2010-05-09 19:20:01 +04:00
pull_reg_multi_sz ( tctx , & blob , & array ) , \
2010-04-27 01:35:19 +04:00
" failed to pull multi sz " ) ; \
for ( i = 0 ; array [ i ] ! = NULL ; i + + ) { \
torture_assert_str_equal ( tctx , array [ i ] , iname [ i ] , \
talloc_asprintf ( tctx , " %s - %s mismatch " , # wname , iname [ i ] ) ) ; \
} \
} while ( 0 ) ;
2010-04-09 17:58:01 +04:00
if ( ! test_winreg_symbolic_link ( tctx , winreg_handle , hive_handle ,
TOP_LEVEL_CONTROL_PRINTERS_KEY ,
" \\ Registry \\ Machine \\ Software \\ Microsoft \\ Windows NT \\ CurrentVersion \\ Print \\ Printers " ) )
{
torture_warning ( tctx , " failed to check for winreg symlink " ) ;
}
2010-04-08 17:00:34 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( keys ) ; i + + ) {
const char * printer_key ;
struct policy_handle key_handle ;
printer_key = talloc_asprintf ( tctx , " %s \\ %s " ,
keys [ i ] , printer_name ) ;
torture_assert ( tctx ,
test_winreg_OpenKey ( tctx , winreg_handle , hive_handle , printer_key , & key_handle ) , " " ) ;
2010-04-20 20:16:03 +04:00
test_sz ( " Name " , printername ) ;
test_sz ( " Share Name " , sharename ) ;
test_sz ( " Port " , info . info2 . portname ) ;
test_sz ( " Printer Driver " , info . info2 . drivername ) ;
test_sz ( " Description " , info . info2 . comment ) ;
test_sz ( " Location " , info . info2 . location ) ;
test_sz ( " Separator File " , info . info2 . sepfile ) ;
test_sz ( " Print Processor " , info . info2 . printprocessor ) ;
test_sz ( " Datatype " , info . info2 . datatype ) ;
test_sz ( " Parameters " , info . info2 . parameters ) ;
2010-04-08 17:00:34 +04:00
/* winreg: 0, spoolss not */
2010-04-20 20:16:03 +04:00
/* test_dword("Attributes", info.info2.attributes); */
test_dword ( " Priority " , info . info2 . priority ) ;
test_dword ( " Default Priority " , info . info2 . defaultpriority ) ;
2010-04-08 17:00:34 +04:00
/* winreg: 60, spoolss: 0 */
2010-04-20 20:16:03 +04:00
/* test_dword("StartTime", info.info2.starttime); */
/* test_dword("UntilTime", info.info2.untiltime); */
2010-04-08 17:00:34 +04:00
/* winreg != spoolss */
2010-04-20 20:16:03 +04:00
/* test_dword("Status", info.info2.status); */
test_dm ( " Default DevMode " , info . info2 . devmode ) ;
test_sd ( " Security " , info . info2 . secdesc ) ;
2010-04-08 17:00:34 +04:00
torture_assert ( tctx ,
test_winreg_CloseKey ( tctx , winreg_handle , & key_handle ) , " " ) ;
}
# undef test_dm
torture_comment ( tctx , " Printer Info and winreg consistency test succeeded \n \n " ) ;
return true ;
}
2016-09-13 10:28:03 +03:00
static bool test_GetPrintserverInfo_winreg ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
struct dcerpc_binding_handle * winreg_handle ,
struct policy_handle * hive_handle )
{
union spoolss_PrinterInfo info ;
struct policy_handle key_handle ;
torture_comment ( tctx ,
" Testing Printserver Info and winreg consistency \n " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , handle , 3 , & info ) ,
" failed to get printer info level 2 " ) ;
torture_assert ( tctx ,
test_winreg_OpenKey ( tctx , winreg_handle , hive_handle ,
TOP_LEVEL_CONTROL_KEY , & key_handle ) , " " ) ;
test_sd ( " ServerSecurityDescriptor " , info . info3 . secdesc ) ;
torture_assert ( tctx ,
test_winreg_CloseKey ( tctx , winreg_handle , & key_handle ) , " " ) ;
# undef test_sd
torture_comment ( tctx ,
" Printserver Info and winreg consistency test succeeded \n \n " ) ;
return true ;
}
2010-06-03 15:01:40 +04:00
static bool test_PrintProcessors ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * environment ,
struct dcerpc_binding_handle * winreg_handle ,
struct policy_handle * hive_handle )
{
union spoolss_PrintProcessorInfo * info ;
uint32_t count ;
int i ;
torture_comment ( tctx , " Testing Print Processor Info and winreg consistency \n " ) ;
torture_assert ( tctx ,
2010-09-28 01:33:52 +04:00
test_EnumPrintProcessors_level ( tctx , b , environment , 1 , & count , & info , WERR_OK ) ,
2010-06-03 15:01:40 +04:00
" failed to enum print processors level 1 " ) ;
for ( i = 0 ; i < count ; i + + ) {
const char * processor_key ;
struct policy_handle key_handle ;
processor_key = talloc_asprintf ( tctx , " %s \\ %s \\ Print Processors \\ %s " ,
TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY ,
environment ,
info [ i ] . info1 . print_processor_name ) ;
torture_assert ( tctx ,
test_winreg_OpenKey ( tctx , winreg_handle , hive_handle , processor_key , & key_handle ) , " " ) ;
/* nothing to check in there so far */
torture_assert ( tctx ,
test_winreg_CloseKey ( tctx , winreg_handle , & key_handle ) , " " ) ;
}
torture_comment ( tctx , " Print Processor Info and winreg consistency test succeeded \n \n " ) ;
return true ;
}
2010-04-20 21:50:37 +04:00
static bool test_GetPrinterDriver2_level ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * driver_name ,
const char * architecture ,
uint32_t level ,
uint32_t client_major_version ,
uint32_t client_minor_version ,
union spoolss_DriverInfo * info_p ,
WERROR * result ) ;
static const char * strip_path ( const char * path )
{
char * p ;
if ( path = = NULL ) {
return NULL ;
}
p = strrchr ( path , ' \\ ' ) ;
if ( p ) {
return p + 1 ;
}
return path ;
}
2010-04-27 01:35:19 +04:00
static const char * * strip_paths ( const char * * path_array )
{
int i ;
if ( path_array = = NULL ) {
return NULL ;
}
for ( i = 0 ; path_array [ i ] ! = NULL ; i + + ) {
path_array [ i ] = strip_path ( path_array [ i ] ) ;
}
return path_array ;
}
2010-04-20 21:50:37 +04:00
static const char * driver_winreg_date ( TALLOC_CTX * mem_ctx , NTTIME nt )
{
time_t t ;
struct tm * tm ;
2010-12-21 19:00:33 +03:00
if ( nt = = 0 ) {
return talloc_strdup ( mem_ctx , " 01/01/1601 " ) ;
}
2010-04-20 21:50:37 +04:00
t = nt_time_to_unix ( nt ) ;
tm = localtime ( & t ) ;
return talloc_asprintf ( mem_ctx , " %02d/%02d/%04d " ,
tm - > tm_mon + 1 , tm - > tm_mday , tm - > tm_year + 1900 ) ;
}
static const char * driver_winreg_version ( TALLOC_CTX * mem_ctx , uint64_t v )
{
return talloc_asprintf ( mem_ctx , " %u.%u.%u.%u " ,
( unsigned ) ( ( v > > 48 ) & 0xFFFF ) ,
( unsigned ) ( ( v > > 32 ) & 0xFFFF ) ,
( unsigned ) ( ( v > > 16 ) & 0xFFFF ) ,
( unsigned ) ( v & 0xFFFF ) ) ;
}
static bool test_GetDriverInfo_winreg ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * printer_name ,
const char * driver_name ,
const char * environment ,
2010-12-16 17:59:19 +03:00
enum spoolss_DriverOSVersion version ,
2010-04-20 21:50:37 +04:00
struct dcerpc_binding_handle * winreg_handle ,
2010-12-16 18:06:02 +03:00
struct policy_handle * hive_handle ,
const char * server_name_slash )
2010-04-20 21:50:37 +04:00
{
2013-12-04 17:01:50 +04:00
WERROR result = WERR_OK ;
2010-04-20 21:50:37 +04:00
union spoolss_DriverInfo info ;
const char * driver_key ;
struct policy_handle key_handle ;
const char * driver_path ;
const char * data_file ;
const char * config_file ;
const char * help_file ;
const char * * dependent_files ;
const char * driver_date ;
const char * inbox_driver_date ;
const char * driver_version ;
const char * inbox_driver_version ;
2013-12-04 17:01:50 +04:00
ZERO_STRUCT ( key_handle ) ;
2010-04-20 21:50:37 +04:00
torture_comment ( tctx , " Testing Driver Info and winreg consistency \n " ) ;
driver_key = talloc_asprintf ( tctx , " %s \\ %s \\ Drivers \\ Version-%d \\ %s " ,
TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY ,
environment ,
2010-12-16 17:59:19 +03:00
version ,
2010-04-20 21:50:37 +04:00
driver_name ) ;
torture_assert ( tctx ,
test_winreg_OpenKey ( tctx , winreg_handle , hive_handle , driver_key , & key_handle ) ,
" failed to open driver key " ) ;
2010-12-24 03:25:04 +03:00
if ( torture_setting_bool ( tctx , " samba3 " , false ) | |
torture_setting_bool ( tctx , " w2k3 " , false ) ) {
2010-12-16 18:01:51 +03:00
goto try_level6 ;
}
2010-12-16 18:06:02 +03:00
if ( handle ) {
torture_assert ( tctx ,
test_GetPrinterDriver2_level ( tctx , b , handle , driver_name , environment , 8 , version , 0 , & info , & result ) ,
" failed to get driver info level 8 " ) ;
} else {
torture_assert ( tctx ,
test_EnumPrinterDrivers_findone ( tctx , b , server_name_slash , environment , 8 , driver_name , & info ) ,
" failed to get driver info level 8 " ) ;
}
2010-04-20 21:50:37 +04:00
if ( W_ERROR_EQUAL ( result , WERR_INVALID_LEVEL ) ) {
goto try_level6 ;
}
driver_path = strip_path ( info . info8 . driver_path ) ;
data_file = strip_path ( info . info8 . data_file ) ;
config_file = strip_path ( info . info8 . config_file ) ;
help_file = strip_path ( info . info8 . help_file ) ;
2010-04-27 01:35:19 +04:00
dependent_files = strip_paths ( info . info8 . dependent_files ) ;
2010-04-20 21:50:37 +04:00
driver_date = driver_winreg_date ( tctx , info . info8 . driver_date ) ;
inbox_driver_date = driver_winreg_date ( tctx , info . info8 . min_inbox_driver_ver_date ) ;
driver_version = driver_winreg_version ( tctx , info . info8 . driver_version ) ;
inbox_driver_version = driver_winreg_version ( tctx , info . info8 . min_inbox_driver_ver_version ) ;
test_sz ( " Configuration File " , config_file ) ;
test_sz ( " Data File " , data_file ) ;
test_sz ( " Datatype " , info . info8 . default_datatype ) ;
test_sz ( " Driver " , driver_path ) ;
test_sz ( " DriverDate " , driver_date ) ;
test_sz ( " DriverVersion " , driver_version ) ;
test_sz ( " HardwareID " , info . info8 . hardware_id ) ;
test_sz ( " Help File " , help_file ) ;
test_sz ( " InfPath " , info . info8 . inf_path ) ;
test_sz ( " Manufacturer " , info . info8 . manufacturer_name ) ;
test_sz ( " MinInboxDriverVerDate " , inbox_driver_date ) ;
test_sz ( " MinInboxDriverVerVersion " , inbox_driver_version ) ;
test_sz ( " Monitor " , info . info8 . monitor_name ) ;
test_sz ( " OEM URL " , info . info8 . manufacturer_url ) ;
test_sz ( " Print Processor " , info . info8 . print_processor ) ;
test_sz ( " Provider " , info . info8 . provider ) ;
test_sz ( " VendorSetup " , info . info8 . vendor_setup ) ;
test_multi_sz ( " ColorProfiles " , info . info8 . color_profiles ) ;
test_multi_sz ( " Dependent Files " , dependent_files ) ;
test_multi_sz ( " CoreDependencies " , info . info8 . core_driver_dependencies ) ;
test_multi_sz ( " Previous Names " , info . info8 . previous_names ) ;
/* test_dword("Attributes", ?); */
test_dword ( " PrinterDriverAttributes " , info . info8 . printer_driver_attributes ) ;
test_dword ( " Version " , info . info8 . version ) ;
/* test_dword("TempDir", ?); */
try_level6 :
2010-12-16 18:06:02 +03:00
if ( handle ) {
torture_assert ( tctx ,
test_GetPrinterDriver2_level ( tctx , b , handle , driver_name , environment , 6 , version , 0 , & info , & result ) ,
" failed to get driver info level 6 " ) ;
} else {
torture_assert ( tctx ,
test_EnumPrinterDrivers_findone ( tctx , b , server_name_slash , environment , 6 , driver_name , & info ) ,
" failed to get driver info level 6 " ) ;
}
2010-04-20 21:50:37 +04:00
driver_path = strip_path ( info . info6 . driver_path ) ;
data_file = strip_path ( info . info6 . data_file ) ;
config_file = strip_path ( info . info6 . config_file ) ;
help_file = strip_path ( info . info6 . help_file ) ;
2010-04-27 01:35:19 +04:00
dependent_files = strip_paths ( info . info6 . dependent_files ) ;
2010-04-20 21:50:37 +04:00
driver_date = driver_winreg_date ( tctx , info . info6 . driver_date ) ;
driver_version = driver_winreg_version ( tctx , info . info6 . driver_version ) ;
test_sz ( " Configuration File " , config_file ) ;
test_sz ( " Data File " , data_file ) ;
test_sz ( " Datatype " , info . info6 . default_datatype ) ;
test_sz ( " Driver " , driver_path ) ;
2010-12-20 18:02:02 +03:00
if ( torture_setting_bool ( tctx , " w2k3 " , false ) ) {
DATA_BLOB blob = data_blob_talloc_zero ( tctx , 8 ) ;
2010-12-24 03:14:49 +03:00
push_nttime ( blob . data , 0 , info . info6 . driver_date ) ;
2010-12-20 18:02:02 +03:00
test_binary ( " DriverDate " , blob ) ;
2010-12-24 03:14:49 +03:00
SBVAL ( blob . data , 0 , info . info6 . driver_version ) ;
2010-12-20 18:02:02 +03:00
test_binary ( " DriverVersion " , blob ) ;
} else {
test_sz ( " DriverDate " , driver_date ) ;
test_sz ( " DriverVersion " , driver_version ) ;
}
2010-04-20 21:50:37 +04:00
test_sz ( " HardwareID " , info . info6 . hardware_id ) ;
test_sz ( " Help File " , help_file ) ;
test_sz ( " Manufacturer " , info . info6 . manufacturer_name ) ;
test_sz ( " Monitor " , info . info6 . monitor_name ) ;
test_sz ( " OEM URL " , info . info6 . manufacturer_url ) ;
test_sz ( " Provider " , info . info6 . provider ) ;
test_multi_sz ( " Dependent Files " , dependent_files ) ;
test_multi_sz ( " Previous Names " , info . info6 . previous_names ) ;
/* test_dword("Attributes", ?); */
test_dword ( " Version " , info . info6 . version ) ;
/* test_dword("TempDir", ?); */
2010-12-16 18:06:02 +03:00
if ( handle ) {
torture_assert ( tctx ,
test_GetPrinterDriver2_level ( tctx , b , handle , driver_name , environment , 3 , version , 0 , & info , & result ) ,
" failed to get driver info level 3 " ) ;
} else {
torture_assert ( tctx ,
test_EnumPrinterDrivers_findone ( tctx , b , server_name_slash , environment , 3 , driver_name , & info ) ,
" failed to get driver info level 3 " ) ;
}
2010-04-27 17:48:03 +04:00
driver_path = strip_path ( info . info3 . driver_path ) ;
data_file = strip_path ( info . info3 . data_file ) ;
config_file = strip_path ( info . info3 . config_file ) ;
help_file = strip_path ( info . info3 . help_file ) ;
dependent_files = strip_paths ( info . info3 . dependent_files ) ;
test_sz ( " Configuration File " , config_file ) ;
test_sz ( " Data File " , data_file ) ;
test_sz ( " Datatype " , info . info3 . default_datatype ) ;
test_sz ( " Driver " , driver_path ) ;
test_sz ( " Help File " , help_file ) ;
test_sz ( " Monitor " , info . info3 . monitor_name ) ;
test_multi_sz ( " Dependent Files " , dependent_files ) ;
/* test_dword("Attributes", ?); */
test_dword ( " Version " , info . info3 . version ) ;
/* test_dword("TempDir", ?); */
2010-04-20 21:50:37 +04:00
torture_assert ( tctx ,
test_winreg_CloseKey ( tctx , winreg_handle , & key_handle ) , " " ) ;
torture_comment ( tctx , " Driver Info and winreg consistency test succeeded \n \n " ) ;
return true ;
}
# undef test_sz
# undef test_dword
2010-03-13 00:45:33 +03:00
static bool test_SetPrinterData ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-03-13 00:45:33 +03:00
struct policy_handle * handle ,
const char * value_name ,
enum winreg_Type type ,
uint8_t * data ,
uint32_t offered )
{
struct spoolss_SetPrinterData r ;
r . in . handle = handle ;
r . in . value_name = value_name ;
r . in . type = type ;
r . in . data = data ;
r . in . offered = offered ;
torture_comment ( tctx , " Testing SetPrinterData(%s) \n " ,
r . in . value_name ) ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-16 13:45:51 +03:00
dcerpc_spoolss_SetPrinterData_r ( b , tctx , & r ) ,
2010-03-13 00:45:33 +03:00
" SetPrinterData failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" SetPrinterData failed " ) ;
return true ;
}
static bool test_SetPrinterData_matrix ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-03-13 00:45:33 +03:00
struct policy_handle * handle ,
const char * printer_name ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * winreg_handle ,
2010-03-13 00:45:33 +03:00
struct policy_handle * hive_handle )
{
const char * values [ ] = {
" spootyfoot " ,
" spooty \\ foot " ,
#if 0
/* FIXME: not working with s3 atm. */
" spooty,foot " ,
" spooty,fo,ot " ,
# endif
" spooty foot " ,
#if 0
/* FIXME: not working with s3 atm. */
" spooty \\ fo,ot " ,
" spooty,fo \\ ot "
# endif
} ;
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( values ) ; i + + ) {
2010-11-10 17:21:15 +03:00
enum winreg_Type type , expected_type = REG_SZ ;
2010-03-13 00:45:33 +03:00
DATA_BLOB blob ;
uint8_t * data ;
uint32_t needed ;
2010-05-21 00:13:48 +04:00
torture_assert ( tctx , push_reg_sz ( tctx , & blob , " dog " ) , " " ) ;
type = REG_SZ ;
2010-03-13 00:45:33 +03:00
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_SetPrinterData ( tctx , b , handle , values [ i ] , REG_SZ , blob . data , blob . length ) ,
2010-03-13 00:45:33 +03:00
" SetPrinterData failed " ) ;
torture_assert ( tctx ,
2010-11-10 17:21:15 +03:00
test_GetPrinterData_checktype ( tctx , b , handle , values [ i ] , & expected_type , & type , & data , & needed ) ,
2010-03-13 00:45:33 +03:00
" GetPrinterData failed " ) ;
torture_assert_int_equal ( tctx , type , REG_SZ , " type mismatch " ) ;
torture_assert_int_equal ( tctx , needed , blob . length , " size mismatch " ) ;
torture_assert_mem_equal ( tctx , data , blob . data , blob . length , " buffer mismatch " ) ;
2010-03-16 13:45:51 +03:00
if ( winreg_handle & & hive_handle ) {
2010-03-13 00:45:33 +03:00
enum winreg_Type w_type ;
uint32_t w_size ;
uint32_t w_length ;
uint8_t * w_data ;
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_winreg_query_printerdata ( tctx , winreg_handle , hive_handle ,
2010-03-13 00:45:33 +03:00
printer_name , " PrinterDriverData " , values [ i ] ,
& w_type , & w_size , & w_length , & w_data ) , " " ) ;
torture_assert_int_equal ( tctx , w_type , REG_SZ , " winreg type mismatch " ) ;
torture_assert_int_equal ( tctx , w_size , blob . length , " winreg size mismatch " ) ;
torture_assert_int_equal ( tctx , w_length , blob . length , " winreg length mismatch " ) ;
torture_assert_mem_equal ( tctx , w_data , blob . data , blob . length , " winreg buffer mismatch " ) ;
}
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_DeletePrinterData ( tctx , b , handle , values [ i ] ) ,
2010-03-13 00:45:33 +03:00
" DeletePrinterData failed " ) ;
}
return true ;
}
static bool test_EnumPrinterKey ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-03-13 00:45:33 +03:00
struct policy_handle * handle ,
const char * key_name ,
const char * * * array ) ;
static bool test_SetPrinterDataEx ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-03-13 00:45:33 +03:00
struct policy_handle * handle ,
const char * key_name ,
const char * value_name ,
enum winreg_Type type ,
uint8_t * data ,
uint32_t offered )
{
NTSTATUS status ;
struct spoolss_SetPrinterDataEx r ;
r . in . handle = handle ;
r . in . key_name = key_name ;
r . in . value_name = value_name ;
r . in . type = type ;
r . in . data = data ;
r . in . offered = offered ;
torture_comment ( tctx , " Testing SetPrinterDataEx(%s - %s) type: %s, offered: 0x%08x \n " ,
r . in . key_name , r . in . value_name , str_regtype ( r . in . type ) , r . in . offered ) ;
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_SetPrinterDataEx_r ( b , tctx , & r ) ;
2010-03-13 00:45:33 +03:00
torture_assert_ntstatus_ok ( tctx , status , " SetPrinterDataEx failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " SetPrinterDataEx failed " ) ;
return true ;
}
2010-06-22 16:55:20 +04:00
static bool test_SetPrinterDataEx_keys ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle )
2010-03-01 16:35:59 +03:00
{
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-12-04 04:54:33 +03:00
const char * value_name = " dog " ;
const char * keys [ ] = {
" torturedataex " ,
2009-12-05 02:58:45 +03:00
" torture data ex " ,
2009-12-04 04:54:33 +03:00
" torturedataex_with_subkey \\ subkey " ,
" torturedataex_with_subkey \\ subkey:0 " ,
" torturedataex_with_subkey \\ subkey:1 " ,
" torturedataex_with_subkey \\ subkey \\ subsubkey " ,
" torturedataex_with_subkey \\ subkey \\ subsubkey:0 " ,
" torturedataex_with_subkey \\ subkey \\ subsubkey:1 " ,
2009-12-05 02:58:45 +03:00
" torture,data " ,
" torture,data,ex " ,
" torture,data \\ ex " ,
2010-06-22 17:25:01 +04:00
" torture \\ data,ex " ,
" torture/data " ,
" torture/data ex " ,
" torture/data ex/sub " ,
" torture//data " ,
" torture//data ex " ,
" torture//data ex/sub " ,
" torture//data ex//sub " ,
2009-12-04 04:54:33 +03:00
} ;
2010-06-22 16:55:20 +04:00
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( keys ) ; i + + ) {
char * c ;
const char * key ;
enum winreg_Type type ;
DATA_BLOB blob_in , blob_out ;
const char * * subkeys ;
uint32_t ecount ;
struct spoolss_PrinterEnumValues * einfo ;
uint32_t needed ;
blob_in = data_blob_talloc ( tctx , NULL , 42 ) ;
generate_random_buffer ( blob_in . data , blob_in . length ) ;
torture_assert ( tctx ,
test_SetPrinterDataEx ( tctx , b , handle , keys [ i ] , value_name , REG_BINARY , blob_in . data , blob_in . length ) ,
" failed to call SetPrinterDataEx " ) ;
torture_assert ( tctx ,
test_GetPrinterDataEx ( tctx , p , handle , keys [ i ] , value_name , & type , & blob_out . data , & needed ) ,
" failed to call GetPrinterDataEx " ) ;
blob_out . length = needed ;
torture_assert ( tctx ,
test_EnumPrinterDataEx ( tctx , b , handle , keys [ i ] , & ecount , & einfo ) ,
" failed to call EnumPrinterDataEx " ) ;
torture_assert_int_equal ( tctx , type , REG_BINARY , " type mismatch " ) ;
torture_assert_int_equal ( tctx , blob_out . length , blob_in . length , " size mismatch " ) ;
torture_assert_mem_equal ( tctx , blob_out . data , blob_in . data , blob_in . length , " buffer mismatch " ) ;
torture_assert_int_equal ( tctx , ecount , 1 , " unexpected enum count " ) ;
torture_assert_str_equal ( tctx , einfo [ 0 ] . value_name , value_name , " value_name mismatch " ) ;
torture_assert_int_equal ( tctx , einfo [ 0 ] . value_name_len , strlen_m_term ( value_name ) * 2 , " unexpected value_name_len " ) ;
torture_assert_int_equal ( tctx , einfo [ 0 ] . type , REG_BINARY , " type mismatch " ) ;
torture_assert_int_equal ( tctx , einfo [ 0 ] . data_length , blob_in . length , " size mismatch " ) ;
if ( einfo [ 0 ] . data_length > 0 ) {
torture_assert_mem_equal ( tctx , einfo [ 0 ] . data - > data , blob_in . data , blob_in . length , " buffer mismatch " ) ;
}
key = talloc_strdup ( tctx , keys [ i ] ) ;
if ( ! test_DeletePrinterDataEx ( tctx , b , handle , keys [ i ] , value_name ) ) {
return false ;
}
c = strchr ( key , ' \\ ' ) ;
if ( c ) {
int k ;
/* we have subkeys */
* c = 0 ;
if ( ! test_EnumPrinterKey ( tctx , b , handle , key , & subkeys ) ) {
return false ;
}
for ( k = 0 ; subkeys & & subkeys [ k ] ; k + + ) {
const char * current_key = talloc_asprintf ( tctx , " %s \\ %s " , key , subkeys [ k ] ) ;
if ( ! test_DeletePrinterKey ( tctx , b , handle , current_key ) ) {
return false ;
}
}
if ( ! test_DeletePrinterKey ( tctx , b , handle , key ) ) {
return false ;
}
} else {
if ( ! test_DeletePrinterKey ( tctx , b , handle , key ) ) {
return false ;
}
}
}
return true ;
}
2010-06-22 17:45:45 +04:00
static bool test_SetPrinterDataEx_values ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle )
{
struct dcerpc_binding_handle * b = p - > binding_handle ;
const char * key = " torturedataex " ;
const char * values [ ] = {
" torture_value " ,
" torture value " ,
" torture,value " ,
" torture/value " ,
" torture \\ value " ,
" torture \\ \\ value "
} ;
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( values ) ; i + + ) {
2017-08-09 09:23:29 +03:00
enum winreg_Type type = REG_NONE ;
DATA_BLOB blob_in = data_blob_null ;
DATA_BLOB blob_out = data_blob_null ;
2010-06-22 17:45:45 +04:00
uint32_t ecount ;
struct spoolss_PrinterEnumValues * einfo ;
2017-08-09 09:23:29 +03:00
uint32_t needed = 0 ;
2010-06-22 17:45:45 +04:00
if ( torture_setting_bool ( tctx , " samba3 " , false ) ) {
char * q ;
q = strrchr ( values [ i ] , ' , ' ) ;
if ( q ) {
2010-06-23 12:47:01 +04:00
torture_comment ( tctx , " skipping valuename '%s' including ',' character against Samba3 \n " ,
values [ i ] ) ;
continue ;
2010-06-22 17:45:45 +04:00
}
}
blob_in = data_blob_talloc ( tctx , NULL , 42 ) ;
generate_random_buffer ( blob_in . data , blob_in . length ) ;
torture_assert ( tctx ,
test_SetPrinterDataEx ( tctx , b , handle , key , values [ i ] , REG_BINARY , blob_in . data , blob_in . length ) ,
" failed to call SetPrinterDataEx " ) ;
torture_assert ( tctx ,
test_GetPrinterDataEx ( tctx , p , handle , key , values [ i ] , & type , & blob_out . data , & needed ) ,
" failed to call GetPrinterDataEx " ) ;
blob_out . length = needed ;
torture_assert ( tctx ,
test_EnumPrinterDataEx ( tctx , b , handle , key , & ecount , & einfo ) ,
" failed to call EnumPrinterDataEx " ) ;
torture_assert_int_equal ( tctx , type , REG_BINARY , " type mismatch " ) ;
torture_assert_int_equal ( tctx , blob_out . length , blob_in . length , " size mismatch " ) ;
torture_assert_mem_equal ( tctx , blob_out . data , blob_in . data , blob_in . length , " buffer mismatch " ) ;
torture_assert_int_equal ( tctx , ecount , 1 , " unexpected enum count " ) ;
torture_assert_str_equal ( tctx , einfo [ 0 ] . value_name , values [ i ] , " value_name mismatch " ) ;
torture_assert_int_equal ( tctx , einfo [ 0 ] . value_name_len , strlen_m_term ( values [ i ] ) * 2 , " unexpected value_name_len " ) ;
torture_assert_int_equal ( tctx , einfo [ 0 ] . type , REG_BINARY , " type mismatch " ) ;
torture_assert_int_equal ( tctx , einfo [ 0 ] . data_length , blob_in . length , " size mismatch " ) ;
if ( einfo [ 0 ] . data_length > 0 ) {
torture_assert_mem_equal ( tctx , einfo [ 0 ] . data - > data , blob_in . data , blob_in . length , " buffer mismatch " ) ;
}
torture_assert ( tctx ,
test_DeletePrinterDataEx ( tctx , b , handle , key , values [ i ] ) ,
" failed to call DeletePrinterDataEx " ) ;
}
return true ;
}
2010-06-22 16:55:20 +04:00
static bool test_SetPrinterDataEx_matrix ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle ,
const char * printername ,
struct dcerpc_binding_handle * winreg_handle ,
struct policy_handle * hive_handle )
{
struct dcerpc_binding_handle * b = p - > binding_handle ;
const char * value_name = " dog " ;
const char * key_name = " torturedataex " ;
2010-03-01 14:53:11 +03:00
enum winreg_Type types [ ] = {
REG_SZ ,
2010-03-17 17:32:42 +03:00
REG_MULTI_SZ ,
2010-03-01 14:53:11 +03:00
REG_DWORD ,
REG_BINARY
} ;
2010-06-03 13:46:44 +04:00
const char * str = " abcdefghi " ;
2010-06-22 16:55:20 +04:00
int t , s ;
2009-12-04 04:54:33 +03:00
2010-03-01 14:53:11 +03:00
for ( t = 0 ; t < ARRAY_SIZE ( types ) ; t + + ) {
2010-03-01 16:35:59 +03:00
for ( s = 0 ; s < strlen ( str ) ; s + + ) {
2009-12-04 04:54:33 +03:00
enum winreg_Type type ;
2010-03-01 16:35:59 +03:00
const char * string = talloc_strndup ( tctx , str , s ) ;
2010-05-21 00:13:48 +04:00
const char * array [ 2 ] ;
2010-03-01 16:35:59 +03:00
DATA_BLOB blob = data_blob_string_const ( string ) ;
2010-03-05 00:22:45 +03:00
DATA_BLOB data ;
2010-03-05 00:40:31 +03:00
uint8_t * data_out ;
2010-03-01 16:35:59 +03:00
uint32_t needed , offered = 0 ;
2010-03-11 01:08:09 +03:00
uint32_t ecount ;
struct spoolss_PrinterEnumValues * einfo ;
2009-12-04 04:54:33 +03:00
2010-05-21 00:13:48 +04:00
array [ 0 ] = talloc_strdup ( tctx , string ) ;
array [ 1 ] = NULL ;
2010-03-17 17:32:42 +03:00
if ( types [ t ] = = REG_DWORD ) {
s = 0xffff ;
}
2010-03-01 14:53:11 +03:00
switch ( types [ t ] ) {
case REG_BINARY :
2010-03-05 00:22:45 +03:00
data = blob ;
2010-03-01 16:35:59 +03:00
offered = blob . length ;
2010-03-01 14:53:11 +03:00
break ;
2010-03-17 17:32:42 +03:00
case REG_DWORD :
data = data_blob_talloc ( tctx , NULL , 4 ) ;
SIVAL ( data . data , 0 , 0x12345678 ) ;
offered = 4 ;
break ;
2010-03-01 14:53:11 +03:00
case REG_SZ :
2010-05-21 00:13:48 +04:00
torture_assert ( tctx , push_reg_sz ( tctx , & data , string ) , " " ) ;
type = REG_SZ ;
2010-03-05 00:22:45 +03:00
offered = data . length ;
/*strlen_m_term(data.string)*2;*/
2010-03-01 14:53:11 +03:00
break ;
2010-03-17 17:32:42 +03:00
case REG_MULTI_SZ :
2010-05-21 00:13:48 +04:00
torture_assert ( tctx , push_reg_multi_sz ( tctx , & data , array ) , " " ) ;
type = REG_MULTI_SZ ;
2010-03-17 17:32:42 +03:00
offered = data . length ;
break ;
2010-03-01 14:53:11 +03:00
default :
torture_fail ( tctx , talloc_asprintf ( tctx , " type %d untested \n " , types [ t ] ) ) ;
}
2009-12-04 04:54:33 +03:00
2010-03-01 16:35:59 +03:00
torture_assert ( tctx ,
2010-06-22 16:55:20 +04:00
test_SetPrinterDataEx ( tctx , b , handle , key_name , value_name , types [ t ] , data . data , offered ) ,
2010-03-01 16:35:59 +03:00
" failed to call SetPrinterDataEx " ) ;
2009-12-04 04:54:33 +03:00
2010-03-11 01:08:09 +03:00
torture_assert ( tctx ,
2010-11-10 17:21:15 +03:00
test_GetPrinterDataEx_checktype ( tctx , p , handle , key_name , value_name , & types [ t ] , & type , & data_out , & needed ) ,
2010-03-11 01:08:09 +03:00
" failed to call GetPrinterDataEx " ) ;
torture_assert ( tctx ,
2010-06-22 16:55:20 +04:00
test_EnumPrinterDataEx ( tctx , b , handle , key_name , & ecount , & einfo ) ,
2010-03-11 01:08:09 +03:00
" failed to call EnumPrinterDataEx " ) ;
2010-03-05 01:13:10 +03:00
torture_assert_int_equal ( tctx , types [ t ] , type , " type mismatch " ) ;
2010-03-01 16:35:59 +03:00
torture_assert_int_equal ( tctx , needed , offered , " size mismatch " ) ;
2010-03-05 00:40:31 +03:00
torture_assert_mem_equal ( tctx , data_out , data . data , offered , " buffer mismatch " ) ;
2010-03-01 16:35:59 +03:00
2010-03-11 01:08:09 +03:00
torture_assert_int_equal ( tctx , ecount , 1 , " unexpected enum count " ) ;
torture_assert_str_equal ( tctx , einfo [ 0 ] . value_name , value_name , " value_name mismatch " ) ;
torture_assert_int_equal ( tctx , einfo [ 0 ] . value_name_len , strlen_m_term ( value_name ) * 2 , " unexpected value_name_len " ) ;
torture_assert_int_equal ( tctx , einfo [ 0 ] . type , types [ t ] , " type mismatch " ) ;
torture_assert_int_equal ( tctx , einfo [ 0 ] . data_length , offered , " size mismatch " ) ;
2010-03-11 02:07:00 +03:00
if ( einfo [ 0 ] . data_length > 0 ) {
torture_assert_mem_equal ( tctx , einfo [ 0 ] . data - > data , data . data , offered , " buffer mismatch " ) ;
}
2010-03-11 01:08:09 +03:00
2010-03-16 13:45:51 +03:00
if ( winreg_handle & & hive_handle ) {
2010-03-05 16:42:10 +03:00
enum winreg_Type w_type ;
2010-03-13 00:45:33 +03:00
uint32_t w_size ;
uint32_t w_length ;
2010-03-05 16:42:10 +03:00
uint8_t * w_data ;
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_winreg_query_printerdata ( tctx , winreg_handle , hive_handle ,
2010-06-22 16:55:20 +04:00
printername , key_name , value_name ,
2010-03-13 00:45:33 +03:00
& w_type , & w_size , & w_length , & w_data ) , " " ) ;
2010-03-05 16:42:10 +03:00
torture_assert_int_equal ( tctx , w_type , types [ t ] , " winreg type mismatch " ) ;
torture_assert_int_equal ( tctx , w_size , offered , " winreg size mismatch " ) ;
2010-03-13 00:45:33 +03:00
torture_assert_int_equal ( tctx , w_length , offered , " winreg length mismatch " ) ;
2010-03-05 16:42:10 +03:00
torture_assert_mem_equal ( tctx , w_data , data . data , offered , " winreg buffer mismatch " ) ;
}
2010-06-22 16:55:20 +04:00
torture_assert ( tctx ,
test_DeletePrinterDataEx ( tctx , b , handle , key_name , value_name ) ,
" failed to call DeletePrinterDataEx " ) ;
2010-03-01 14:53:11 +03:00
}
2010-03-01 16:35:59 +03:00
}
2003-11-28 13:34:58 +03:00
2007-09-03 17:13:25 +04:00
return true ;
2003-11-28 13:34:58 +03:00
}
2010-03-05 16:42:10 +03:00
static bool test_PrinterData_winreg ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle ,
const char * printer_name )
{
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-03-05 16:42:10 +03:00
struct dcerpc_pipe * p2 ;
bool ret = true ;
struct policy_handle hive_handle ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b2 ;
2010-03-05 16:42:10 +03:00
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection ( tctx , & p2 , & ndr_table_winreg ) ,
" could not open winreg pipe " ) ;
2010-03-16 13:45:51 +03:00
b2 = p2 - > binding_handle ;
2010-03-05 16:42:10 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_winreg_OpenHKLM ( tctx , b2 , & hive_handle ) , " " ) ;
2010-03-05 16:42:10 +03:00
2010-03-16 13:45:51 +03:00
ret & = test_SetPrinterData_matrix ( tctx , b , handle , printer_name , b2 , & hive_handle ) ;
ret & = test_SetPrinterDataEx_matrix ( tctx , p , handle , printer_name , b2 , & hive_handle ) ;
2010-03-05 16:42:10 +03:00
2010-03-16 13:45:51 +03:00
test_winreg_CloseKey ( tctx , b2 , & hive_handle ) ;
2010-03-05 16:42:10 +03:00
talloc_free ( p2 ) ;
return ret ;
}
2010-04-06 15:23:22 +04:00
static bool test_Forms_winreg ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
bool print_server ,
const char * printer_name )
{
struct dcerpc_pipe * p2 ;
bool ret = true ;
struct policy_handle hive_handle ;
struct dcerpc_binding_handle * b2 ;
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection ( tctx , & p2 , & ndr_table_winreg ) ,
" could not open winreg pipe " ) ;
b2 = p2 - > binding_handle ;
torture_assert ( tctx , test_winreg_OpenHKLM ( tctx , b2 , & hive_handle ) , " " ) ;
ret = test_Forms ( tctx , b , handle , print_server , printer_name , b2 , & hive_handle ) ;
test_winreg_CloseKey ( tctx , b2 , & hive_handle ) ;
talloc_free ( p2 ) ;
return ret ;
}
2010-04-08 17:00:34 +04:00
static bool test_PrinterInfo_winreg ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle ,
const char * printer_name )
{
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct dcerpc_pipe * p2 ;
bool ret = true ;
struct policy_handle hive_handle ;
struct dcerpc_binding_handle * b2 ;
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection ( tctx , & p2 , & ndr_table_winreg ) ,
" could not open winreg pipe " ) ;
b2 = p2 - > binding_handle ;
torture_assert ( tctx , test_winreg_OpenHKLM ( tctx , b2 , & hive_handle ) , " " ) ;
ret = test_GetPrinterInfo_winreg ( tctx , b , handle , printer_name , b2 , & hive_handle ) ;
test_winreg_CloseKey ( tctx , b2 , & hive_handle ) ;
talloc_free ( p2 ) ;
return ret ;
}
2016-09-13 10:28:03 +03:00
static bool test_PrintserverInfo_winreg ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle )
{
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct dcerpc_pipe * p2 ;
bool ret = true ;
struct policy_handle hive_handle ;
struct dcerpc_binding_handle * b2 ;
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection ( tctx , & p2 , & ndr_table_winreg ) ,
" could not open winreg pipe " ) ;
b2 = p2 - > binding_handle ;
torture_assert ( tctx , test_winreg_OpenHKLM ( tctx , b2 , & hive_handle ) , " " ) ;
ret = test_GetPrintserverInfo_winreg ( tctx , b , handle , b2 , & hive_handle ) ;
test_winreg_CloseKey ( tctx , b2 , & hive_handle ) ;
talloc_free ( p2 ) ;
return ret ;
}
2010-04-20 21:50:37 +04:00
static bool test_DriverInfo_winreg ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle ,
const char * printer_name ,
const char * driver_name ,
2010-12-16 17:59:19 +03:00
const char * environment ,
enum spoolss_DriverOSVersion version )
2010-04-20 21:50:37 +04:00
{
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct dcerpc_pipe * p2 ;
bool ret = true ;
struct policy_handle hive_handle ;
struct dcerpc_binding_handle * b2 ;
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection ( tctx , & p2 , & ndr_table_winreg ) ,
" could not open winreg pipe " ) ;
b2 = p2 - > binding_handle ;
torture_assert ( tctx , test_winreg_OpenHKLM ( tctx , b2 , & hive_handle ) , " " ) ;
2010-12-16 18:06:02 +03:00
ret = test_GetDriverInfo_winreg ( tctx , b , handle , printer_name , driver_name , environment , version , b2 , & hive_handle , NULL ) ;
2010-04-20 21:50:37 +04:00
test_winreg_CloseKey ( tctx , b2 , & hive_handle ) ;
talloc_free ( p2 ) ;
return ret ;
}
2010-06-03 15:01:40 +04:00
static bool test_PrintProcessors_winreg ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * environment )
{
struct dcerpc_pipe * p2 ;
bool ret = true ;
struct policy_handle hive_handle ;
struct dcerpc_binding_handle * b2 ;
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection ( tctx , & p2 , & ndr_table_winreg ) ,
" could not open winreg pipe " ) ;
b2 = p2 - > binding_handle ;
torture_assert ( tctx , test_winreg_OpenHKLM ( tctx , b2 , & hive_handle ) , " " ) ;
2010-06-03 16:54:02 +04:00
ret = test_PrintProcessors ( tctx , b , environment , b2 , & hive_handle ) ;
2010-06-03 15:01:40 +04:00
test_winreg_CloseKey ( tctx , b2 , & hive_handle ) ;
talloc_free ( p2 ) ;
return ret ;
}
2010-04-28 15:34:31 +04:00
static bool test_PrinterData_DsSpooler ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle ,
const char * printer_name )
{
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
union spoolss_SetPrinterInfo sinfo ;
union spoolss_PrinterInfo info ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-04-30 16:38:07 +04:00
const char * pname ;
2010-04-28 15:34:31 +04:00
ZERO_STRUCT ( info_ctr ) ;
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
torture_comment ( tctx , " Testing DsSpooler <-> SetPrinter relations \n " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , handle , 2 , & info ) ,
" failed to query Printer level 2 " ) ;
torture_assert ( tctx ,
PrinterInfo_to_SetPrinterInfo ( tctx , & info , 2 , & sinfo ) ,
" failed to convert " ) ;
info_ctr . level = 2 ;
info_ctr . info = sinfo ;
2010-04-28 19:03:30 +04:00
# define TEST_SZ(wname, iname) \
do { \
enum winreg_Type type ; \
uint8_t * data ; \
uint32_t needed ; \
DATA_BLOB blob ; \
const char * str ; \
torture_assert ( tctx , \
test_GetPrinterDataEx ( tctx , p , handle , " DsSpooler " , wname , & type , & data , & needed ) , \
" failed to query " ) ; \
torture_assert_int_equal ( tctx , type , REG_SZ , " unexpected type " ) ; \
blob = data_blob_const ( data , needed ) ; \
torture_assert ( tctx , \
2010-05-09 19:20:01 +04:00
pull_reg_sz ( tctx , & blob , & str ) , \
2010-04-28 19:03:30 +04:00
" failed to pull REG_SZ " ) ; \
torture_assert_str_equal ( tctx , str , iname , " unexpected result " ) ; \
} while ( 0 ) ;
2010-04-28 15:34:31 +04:00
# define TEST_SET_SZ(wname, iname, val) \
do { \
enum winreg_Type type ; \
uint8_t * data ; \
uint32_t needed ; \
DATA_BLOB blob ; \
const char * str ; \
sinfo . info2 - > iname = val ; \
torture_assert ( tctx , \
test_SetPrinter ( tctx , b , handle , & info_ctr , & devmode_ctr , & secdesc_ctr , 0 ) , \
" failed to call SetPrinter " ) ; \
torture_assert ( tctx , \
test_GetPrinterDataEx ( tctx , p , handle , " DsSpooler " , wname , & type , & data , & needed ) , \
" failed to query " ) ; \
torture_assert_int_equal ( tctx , type , REG_SZ , " unexpected type " ) ; \
blob = data_blob_const ( data , needed ) ; \
torture_assert ( tctx , \
2010-05-09 19:20:01 +04:00
pull_reg_sz ( tctx , & blob , & str ) , \
2010-04-28 15:34:31 +04:00
" failed to pull REG_SZ " ) ; \
torture_assert_str_equal ( tctx , str , val , " unexpected result " ) ; \
} while ( 0 ) ;
# define TEST_SET_DWORD(wname, iname, val) \
do { \
enum winreg_Type type ; \
uint8_t * data ; \
uint32_t needed ; \
uint32_t value ; \
sinfo . info2 - > iname = val ; \
torture_assert ( tctx , \
test_SetPrinter ( tctx , b , handle , & info_ctr , & devmode_ctr , & secdesc_ctr , 0 ) , \
" failed to call SetPrinter " ) ; \
torture_assert ( tctx , \
test_GetPrinterDataEx ( tctx , p , handle , " DsSpooler " , wname , & type , & data , & needed ) , \
" failed to query " ) ; \
torture_assert_int_equal ( tctx , type , REG_DWORD , " unexpected type " ) ; \
torture_assert_int_equal ( tctx , needed , 4 , " unexpected length " ) ; \
value = IVAL ( data , 0 ) ; \
torture_assert_int_equal ( tctx , value , val , " unexpected result " ) ; \
} while ( 0 ) ;
TEST_SET_SZ ( " description " , comment , " newval " ) ;
TEST_SET_SZ ( " location " , location , " newval " ) ;
2012-03-30 03:00:51 +04:00
TEST_SET_SZ ( " driverName " , drivername , " newval " ) ;
2010-04-28 15:34:31 +04:00
/* TEST_SET_DWORD("priority", priority, 25); */
2010-04-28 19:03:30 +04:00
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , handle , 2 , & info ) ,
" failed to query Printer level 2 " ) ;
TEST_SZ ( " description " , info . info2 . comment ) ;
2010-06-01 19:09:21 +04:00
TEST_SZ ( " driverName " , info . info2 . drivername ) ;
2010-04-28 19:03:30 +04:00
TEST_SZ ( " location " , info . info2 . location ) ;
2010-04-30 16:38:07 +04:00
pname = strrchr ( info . info2 . printername , ' \\ ' ) ;
if ( pname = = NULL ) {
pname = info . info2 . printername ;
} else {
pname + + ;
}
2010-06-01 19:09:21 +04:00
TEST_SZ ( " printerName " , pname ) ;
2010-04-28 19:03:30 +04:00
/* TEST_SZ("printSeparatorFile", info.info2.sepfile); */
/* TEST_SZ("printShareName", info.info2.sharename); */
2010-04-28 15:34:31 +04:00
/* FIXME gd: complete the list */
2010-04-28 19:03:30 +04:00
# undef TEST_SZ
2010-04-28 15:34:31 +04:00
# undef TEST_SET_SZ
# undef TEST_DWORD
torture_comment ( tctx , " DsSpooler <-> SetPrinter relations test succeeded \n \n " ) ;
return true ;
}
2010-05-19 01:40:43 +04:00
static bool test_print_processors_winreg ( struct torture_context * tctx ,
void * private_data )
{
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
return test_PrintProcessors_winreg ( tctx , b , ctx - > environment ) ;
}
2013-02-01 17:07:50 +04:00
static bool test_AddPrintProcessor ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * environment ,
const char * path_name ,
const char * print_processor_name ,
WERROR expected_error )
{
struct spoolss_AddPrintProcessor r ;
r . in . server = NULL ;
r . in . architecture = environment ;
r . in . path_name = path_name ;
r . in . print_processor_name = print_processor_name ;
torture_comment ( tctx , " Testing AddPrintProcessor(%s) \n " ,
print_processor_name ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_AddPrintProcessor_r ( b , tctx , & r ) ,
" spoolss_AddPrintProcessor failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , expected_error ,
" spoolss_AddPrintProcessor failed " ) ;
return true ;
}
static bool test_DeletePrintProcessor ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * environment ,
const char * print_processor_name ,
WERROR expected_error )
{
struct spoolss_DeletePrintProcessor r ;
r . in . server = NULL ;
r . in . architecture = environment ;
r . in . print_processor_name = print_processor_name ;
torture_comment ( tctx , " Testing DeletePrintProcessor(%s) \n " ,
print_processor_name ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_DeletePrintProcessor_r ( b , tctx , & r ) ,
" spoolss_DeletePrintProcessor failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , expected_error ,
" spoolss_DeletePrintProcessor failed " ) ;
return true ;
}
static bool test_add_print_processor ( struct torture_context * tctx ,
void * private_data )
{
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
int i ;
struct {
const char * environment ;
const char * path_name ;
const char * print_processor_name ;
WERROR expected_add_result ;
WERROR expected_del_result ;
} tests [ ] = {
{
. environment = ctx - > environment ,
. path_name = " " ,
. print_processor_name = " winprint " ,
. expected_add_result = WERR_PRINT_PROCESSOR_ALREADY_INSTALLED ,
. expected_del_result = WERR_CAN_NOT_COMPLETE
} , {
. environment = ctx - > environment ,
. path_name = " " ,
. print_processor_name = " unknown " ,
. expected_add_result = WERR_MOD_NOT_FOUND ,
. expected_del_result = WERR_UNKNOWN_PRINTPROCESSOR
}
} ;
for ( i = 0 ; i < ARRAY_SIZE ( tests ) ; i + + ) {
torture_assert ( tctx ,
test_AddPrintProcessor ( tctx , b ,
tests [ i ] . environment ,
tests [ i ] . path_name ,
tests [ i ] . print_processor_name ,
tests [ i ] . expected_add_result ) ,
" add print processor failed " ) ;
torture_assert ( tctx ,
test_DeletePrintProcessor ( tctx , b ,
tests [ i ] . environment ,
tests [ i ] . print_processor_name ,
tests [ i ] . expected_del_result ) ,
" delete print processor failed " ) ;
}
return true ;
}
2010-01-06 21:34:33 +03:00
static bool test_GetChangeID_PrinterData ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-01-06 21:34:33 +03:00
struct policy_handle * handle ,
uint32_t * change_id )
{
enum winreg_Type type ;
2010-03-05 00:40:31 +03:00
uint8_t * data ;
uint32_t needed ;
2010-01-06 21:34:33 +03:00
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_GetPrinterData ( tctx , b , handle , " ChangeID " , & type , & data , & needed ) ,
2010-01-06 21:34:33 +03:00
" failed to call GetPrinterData " ) ;
torture_assert ( tctx , type = = REG_DWORD , " unexpected type " ) ;
2010-03-05 00:40:31 +03:00
torture_assert_int_equal ( tctx , needed , 4 , " unexpected size " ) ;
2010-01-06 21:34:33 +03:00
2010-03-05 00:40:31 +03:00
* change_id = IVAL ( data , 0 ) ;
2010-01-06 21:34:33 +03:00
return true ;
}
static bool test_GetChangeID_PrinterDataEx ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle ,
uint32_t * change_id )
{
2015-03-03 10:48:00 +03:00
enum winreg_Type type = REG_NONE ;
uint8_t * data = NULL ;
uint32_t needed = 0 ;
2010-01-06 21:34:33 +03:00
torture_assert ( tctx ,
2010-03-05 00:40:31 +03:00
test_GetPrinterDataEx ( tctx , p , handle , " PrinterDriverData " , " ChangeID " , & type , & data , & needed ) ,
2010-01-06 21:34:33 +03:00
" failed to call GetPrinterData " ) ;
torture_assert ( tctx , type = = REG_DWORD , " unexpected type " ) ;
2010-03-05 00:40:31 +03:00
torture_assert_int_equal ( tctx , needed , 4 , " unexpected size " ) ;
2010-01-06 21:34:33 +03:00
2010-03-05 00:40:31 +03:00
* change_id = IVAL ( data , 0 ) ;
2010-01-06 21:34:33 +03:00
return true ;
}
static bool test_GetChangeID_PrinterInfo ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2010-01-06 21:34:33 +03:00
struct policy_handle * handle ,
uint32_t * change_id )
{
union spoolss_PrinterInfo info ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 0 , & info ) ,
2010-01-06 21:34:33 +03:00
" failed to query Printer level 0 " ) ;
* change_id = info . info0 . change_id ;
return true ;
}
static bool test_ChangeID ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle )
{
uint32_t change_id , change_id_ex , change_id_info ;
uint32_t change_id2 , change_id_ex2 , change_id_info2 ;
union spoolss_PrinterInfo info ;
const char * comment ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-01-06 21:34:33 +03:00
torture_comment ( tctx , " Testing ChangeID: id change test #1 \n " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetChangeID_PrinterData ( tctx , b , handle , & change_id ) ,
2010-01-06 21:34:33 +03:00
" failed to query for ChangeID " ) ;
torture_assert ( tctx , test_GetChangeID_PrinterDataEx ( tctx , p , handle , & change_id_ex ) ,
" failed to query for ChangeID " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetChangeID_PrinterInfo ( tctx , b , handle , & change_id_info ) ,
2010-01-06 21:34:33 +03:00
" failed to query for ChangeID " ) ;
torture_assert_int_equal ( tctx , change_id , change_id_ex ,
" change_ids should all be equal " ) ;
torture_assert_int_equal ( tctx , change_id_ex , change_id_info ,
" change_ids should all be equal " ) ;
torture_comment ( tctx , " Testing ChangeID: id change test #2 \n " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetChangeID_PrinterData ( tctx , b , handle , & change_id ) ,
2010-01-06 21:34:33 +03:00
" failed to query for ChangeID " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) ,
2010-01-06 21:34:33 +03:00
" failed to query Printer level 2 " ) ;
torture_assert ( tctx , test_GetChangeID_PrinterDataEx ( tctx , p , handle , & change_id_ex ) ,
" failed to query for ChangeID " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetChangeID_PrinterInfo ( tctx , b , handle , & change_id_info ) ,
2010-01-06 21:34:33 +03:00
" failed to query for ChangeID " ) ;
torture_assert_int_equal ( tctx , change_id , change_id_ex ,
" change_id should not have changed " ) ;
torture_assert_int_equal ( tctx , change_id_ex , change_id_info ,
" change_id should not have changed " ) ;
torture_comment ( tctx , " Testing ChangeID: id change test #3 \n " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetChangeID_PrinterData ( tctx , b , handle , & change_id ) ,
2010-01-06 21:34:33 +03:00
" failed to query for ChangeID " ) ;
torture_assert ( tctx , test_GetChangeID_PrinterDataEx ( tctx , p , handle , & change_id_ex ) ,
" failed to query for ChangeID " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetChangeID_PrinterInfo ( tctx , b , handle , & change_id_info ) ,
2010-01-06 21:34:33 +03:00
" failed to query for ChangeID " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) ,
2010-01-06 21:34:33 +03:00
" failed to query Printer level 2 " ) ;
comment = talloc_strdup ( tctx , info . info2 . comment ) ;
{
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
2010-03-15 14:38:17 +03:00
union spoolss_SetPrinterInfo sinfo ;
2010-01-06 21:34:33 +03:00
ZERO_STRUCT ( info_ctr ) ;
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
2010-03-15 14:38:17 +03:00
torture_assert ( tctx , PrinterInfo_to_SetPrinterInfo ( tctx , & info , 2 , & sinfo ) , " " ) ;
sinfo . info2 - > comment = " torture_comment " ;
2010-01-06 21:34:33 +03:00
info_ctr . level = 2 ;
2010-03-15 14:38:17 +03:00
info_ctr . info = sinfo ;
2010-01-06 21:34:33 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_SetPrinter ( tctx , b , handle , & info_ctr , & devmode_ctr , & secdesc_ctr , 0 ) ,
2010-01-06 21:34:33 +03:00
" failed to call SetPrinter " ) ;
2010-03-15 14:38:17 +03:00
sinfo . info2 - > comment = comment ;
2010-01-06 21:34:33 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_SetPrinter ( tctx , b , handle , & info_ctr , & devmode_ctr , & secdesc_ctr , 0 ) ,
2010-01-06 21:34:33 +03:00
" failed to call SetPrinter " ) ;
}
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetChangeID_PrinterData ( tctx , b , handle , & change_id2 ) ,
2010-01-06 21:34:33 +03:00
" failed to query for ChangeID " ) ;
torture_assert ( tctx , test_GetChangeID_PrinterDataEx ( tctx , p , handle , & change_id_ex2 ) ,
" failed to query for ChangeID " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_GetChangeID_PrinterInfo ( tctx , b , handle , & change_id_info2 ) ,
2010-01-06 21:34:33 +03:00
" failed to query for ChangeID " ) ;
torture_assert_int_equal ( tctx , change_id2 , change_id_ex2 ,
" change_ids should all be equal " ) ;
torture_assert_int_equal ( tctx , change_id_ex2 , change_id_info2 ,
" change_ids should all be equal " ) ;
torture_assert ( tctx , ( change_id < change_id2 ) ,
talloc_asprintf ( tctx , " change_id %d needs to be larger than change_id %d " ,
change_id2 , change_id ) ) ;
torture_assert ( tctx , ( change_id_ex < change_id_ex2 ) ,
talloc_asprintf ( tctx , " change_id %d needs to be larger than change_id %d " ,
change_id_ex2 , change_id_ex ) ) ;
torture_assert ( tctx , ( change_id_info < change_id_info2 ) ,
talloc_asprintf ( tctx , " change_id %d needs to be larger than change_id %d " ,
change_id_info2 , change_id_info ) ) ;
2010-03-16 15:52:48 +03:00
torture_comment ( tctx , " ChangeID tests succeeded \n \n " ) ;
2010-01-06 21:34:33 +03:00
return true ;
}
2009-12-04 04:54:33 +03:00
2009-06-30 13:38:41 +04:00
static bool test_SecondaryClosePrinter ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
2004-01-20 09:07:09 +03:00
struct policy_handle * handle )
{
NTSTATUS status ;
2014-01-17 12:54:39 +04:00
struct cli_credentials * anon_creds ;
2014-01-23 12:46:55 +04:00
const struct dcerpc_binding * binding2 ;
2004-01-20 09:07:09 +03:00
struct dcerpc_pipe * p2 ;
2007-11-20 11:33:14 +03:00
struct spoolss_ClosePrinter cp ;
2004-01-20 09:07:09 +03:00
/* only makes sense on SMB */
2005-01-09 11:34:05 +03:00
if ( p - > conn - > transport . transport ! = NCACN_NP ) {
2007-10-07 02:28:14 +04:00
return true ;
2004-01-20 09:07:09 +03:00
}
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing close on secondary pipe \n " ) ;
2004-01-20 09:07:09 +03:00
2014-01-17 12:54:39 +04:00
anon_creds = cli_credentials_init_anon ( tctx ) ;
torture_assert ( tctx , anon_creds ! = NULL , " cli_credentials_init_anon failed " ) ;
2014-01-23 12:46:55 +04:00
binding2 = p - > binding ;
2014-01-17 12:54:39 +04:00
status = dcerpc_secondary_auth_connection ( p , binding2 , & ndr_table_spoolss ,
anon_creds , tctx - > lp_ctx ,
tctx , & p2 ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " Failed to create secondary connection " ) ;
2004-01-20 09:07:09 +03:00
2007-11-20 11:33:14 +03:00
cp . in . handle = handle ;
cp . out . handle = handle ;
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_ClosePrinter_r ( p2 - > binding_handle , tctx , & cp ) ;
2010-04-12 16:14:29 +04:00
torture_assert_ntstatus_equal ( tctx , status , NT_STATUS_RPC_SS_CONTEXT_MISMATCH ,
2007-11-20 11:33:14 +03:00
" ERROR: Allowed close on secondary connection " ) ;
2004-01-20 09:10:15 +03:00
2005-03-22 11:00:45 +03:00
talloc_free ( p2 ) ;
2004-01-20 09:07:09 +03:00
2007-09-03 17:13:25 +04:00
return true ;
2004-01-20 09:07:09 +03:00
}
2009-06-30 13:38:41 +04:00
static bool test_OpenPrinter_badname ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b , const char * name )
2005-02-22 14:51:18 +03:00
{
NTSTATUS status ;
struct spoolss_OpenPrinter op ;
struct spoolss_OpenPrinterEx opEx ;
struct policy_handle handle ;
2007-09-03 17:13:25 +04:00
bool ret = true ;
2005-02-22 14:51:18 +03:00
op . in . printername = name ;
op . in . datatype = NULL ;
op . in . devmode_ctr . devmode = NULL ;
op . in . access_mask = 0 ;
op . out . handle = & handle ;
2010-03-15 19:08:23 +03:00
torture_comment ( tctx , " Testing OpenPrinter(%s) with bad name \n " , op . in . printername ) ;
2005-02-22 14:51:18 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_OpenPrinter_r ( b , tctx , & op ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " OpenPrinter failed " ) ;
2010-03-16 02:01:16 +03:00
torture_assert_werr_equal ( tctx , op . out . result , WERR_INVALID_PRINTER_NAME ,
" unexpected result " ) ;
2005-02-22 14:51:18 +03:00
if ( W_ERROR_IS_OK ( op . out . result ) ) {
2010-03-16 13:45:51 +03:00
ret & = test_ClosePrinter ( tctx , b , & handle ) ;
2005-02-22 14:51:18 +03:00
}
opEx . in . printername = name ;
opEx . in . datatype = NULL ;
opEx . in . devmode_ctr . devmode = NULL ;
opEx . in . access_mask = 0 ;
2013-01-14 20:26:31 +04:00
opEx . in . userlevel_ctr . level = 1 ;
opEx . in . userlevel_ctr . user_info . level1 = NULL ;
2005-02-22 14:51:18 +03:00
opEx . out . handle = & handle ;
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing OpenPrinterEx(%s) with bad name \n " , opEx . in . printername ) ;
2005-02-22 14:51:18 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_OpenPrinterEx_r ( b , tctx , & opEx ) ;
2007-10-15 10:35:24 +04:00
torture_assert_ntstatus_ok ( tctx , status , " OpenPrinterEx failed " ) ;
2015-12-03 17:24:27 +03:00
torture_assert_werr_equal ( tctx , opEx . out . result , WERR_INVALID_PARAMETER ,
2010-03-16 02:01:16 +03:00
" unexpected result " ) ;
2005-02-22 14:51:18 +03:00
if ( W_ERROR_IS_OK ( opEx . out . result ) ) {
2010-03-16 13:45:51 +03:00
ret & = test_ClosePrinter ( tctx , b , & handle ) ;
2005-02-22 14:51:18 +03:00
}
return ret ;
}
2010-04-07 02:39:17 +04:00
static bool test_OpenPrinter_badname_list ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2010-04-07 02:39:17 +04:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
2010-04-07 02:39:17 +04:00
const char * badnames [ ] = {
" __INVALID_PRINTER__ " ,
" \\ \\ __INVALID_HOST__ " ,
" " ,
" \\ \\ \\ " ,
" \\ \\ \\ __INVALID_PRINTER__ "
} ;
const char * badname ;
2010-05-19 01:40:43 +04:00
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
const char * server_name = dcerpc_server_name ( p ) ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-04-07 02:39:17 +04:00
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( badnames ) ; i + + ) {
torture_assert ( tctx ,
test_OpenPrinter_badname ( tctx , b , badnames [ i ] ) ,
" " ) ;
}
badname = talloc_asprintf ( tctx , " \\ \\ %s \\ " , server_name ) ;
torture_assert ( tctx ,
test_OpenPrinter_badname ( tctx , b , badname ) ,
" " ) ;
badname = talloc_asprintf ( tctx , " \\ \\ %s \\ __INVALID_PRINTER__ " , server_name ) ;
torture_assert ( tctx ,
test_OpenPrinter_badname ( tctx , b , badname ) ,
" " ) ;
return true ;
}
2009-06-30 13:38:41 +04:00
static bool test_OpenPrinter ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
2010-02-25 21:06:39 +03:00
const char * name ,
2010-09-10 02:16:30 +04:00
const char * environment ,
bool open_only )
2003-11-17 06:38:13 +03:00
{
NTSTATUS status ;
struct spoolss_OpenPrinter r ;
struct policy_handle handle ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2003-11-17 06:38:13 +03:00
2010-09-10 02:16:30 +04:00
r . in . printername = name ;
2005-02-22 11:04:52 +03:00
r . in . datatype = NULL ;
r . in . devmode_ctr . devmode = NULL ;
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
r . out . handle = & handle ;
2003-11-17 06:38:13 +03:00
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing OpenPrinter(%s) \n " , r . in . printername ) ;
2003-11-17 06:38:13 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_OpenPrinter_r ( b , tctx , & r ) ;
2005-02-25 08:39:01 +03:00
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " OpenPrinter failed " ) ;
2005-02-25 08:39:01 +03:00
2007-09-03 17:13:25 +04:00
torture_assert_werr_ok ( tctx , r . out . result , " OpenPrinter failed " ) ;
2003-11-17 06:38:13 +03:00
2010-09-10 02:16:30 +04:00
if ( open_only ) {
goto close_printer ;
}
2010-03-16 13:45:51 +03:00
if ( ! test_GetPrinter ( tctx , b , & handle , environment ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2003-11-17 07:56:59 +03:00
}
2009-04-13 19:06:37 +04:00
if ( ! torture_setting_bool ( tctx , " samba3 " , false ) ) {
if ( ! test_SecondaryClosePrinter ( tctx , p , & handle ) ) {
ret = false ;
}
2004-01-20 09:07:09 +03:00
}
2010-09-10 02:16:30 +04:00
close_printer :
2010-03-16 13:45:51 +03:00
if ( ! test_ClosePrinter ( tctx , b , & handle ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2003-11-17 07:56:59 +03:00
}
2005-02-22 11:04:52 +03:00
2003-11-22 14:49:22 +03:00
return ret ;
2003-11-17 07:56:59 +03:00
}
2010-10-02 23:53:54 +04:00
static bool test_OpenPrinterEx ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * printername ,
const char * datatype ,
struct spoolss_DeviceMode * devmode ,
uint32_t access_mask ,
2013-01-14 20:26:31 +04:00
struct spoolss_UserLevelCtr * userlevel_ctr ,
2010-10-02 23:53:54 +04:00
struct policy_handle * handle ,
WERROR expected_result )
{
struct spoolss_OpenPrinterEx r ;
r . in . printername = printername ;
r . in . datatype = datatype ;
r . in . devmode_ctr . devmode = devmode ;
r . in . access_mask = access_mask ;
2013-01-14 20:26:31 +04:00
r . in . userlevel_ctr = * userlevel_ctr ;
2010-10-02 23:53:54 +04:00
r . out . handle = handle ;
torture_comment ( tctx , " Testing OpenPrinterEx(%s) \n " , r . in . printername ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_OpenPrinterEx_r ( b , tctx , & r ) ,
" OpenPrinterEx failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , expected_result ,
" OpenPrinterEx failed " ) ;
return true ;
}
2009-06-30 13:38:41 +04:00
static bool call_OpenPrinterEx ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
2010-02-16 05:26:10 +03:00
const char * name ,
struct spoolss_DeviceMode * devmode ,
struct policy_handle * handle )
2003-11-17 07:56:59 +03:00
{
2013-01-14 20:26:31 +04:00
struct spoolss_UserLevelCtr userlevel_ctr ;
2003-11-17 07:56:59 +03:00
struct spoolss_UserLevel1 userlevel1 ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2003-11-17 07:56:59 +03:00
userlevel1 . size = 1234 ;
userlevel1 . client = " hello " ;
userlevel1 . user = " spottyfoot! " ;
userlevel1 . build = 1 ;
userlevel1 . major = 2 ;
userlevel1 . minor = 3 ;
userlevel1 . processor = 4 ;
2013-01-14 20:26:31 +04:00
userlevel_ctr . level = 1 ;
userlevel_ctr . user_info . level1 = & userlevel1 ;
2003-11-17 07:56:59 +03:00
2010-10-02 23:53:54 +04:00
return test_OpenPrinterEx ( tctx , b , name , NULL , devmode ,
SEC_FLAG_MAXIMUM_ALLOWED ,
2013-01-14 20:26:31 +04:00
& userlevel_ctr ,
2010-10-02 23:53:54 +04:00
handle ,
WERR_OK ) ;
2003-11-30 14:57:40 +03:00
}
2010-03-15 19:08:23 +03:00
static bool test_printer_rename ( struct torture_context * tctx ,
2010-06-03 23:39:51 +04:00
void * private_data )
2010-03-15 19:08:23 +03:00
{
2010-06-03 23:39:51 +04:00
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
2010-03-15 19:08:23 +03:00
bool ret = true ;
union spoolss_PrinterInfo info ;
union spoolss_SetPrinterInfo sinfo ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
const char * printer_name ;
const char * printer_name_orig ;
const char * printer_name_new = " SAMBA smbtorture Test Printer (Copy 2) " ;
struct policy_handle new_handle ;
const char * q ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-03-15 19:08:23 +03:00
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
torture_comment ( tctx , " Testing Printer rename operations \n " ) ;
torture_assert ( tctx ,
2010-06-03 23:39:51 +04:00
test_GetPrinter_level ( tctx , b , & t - > handle , 2 , & info ) ,
2010-03-15 19:08:23 +03:00
" failed to call GetPrinter level 2 " ) ;
printer_name_orig = talloc_strdup ( tctx , info . info2 . printername ) ;
q = strrchr ( info . info2 . printername , ' \\ ' ) ;
if ( q ) {
torture_warning ( tctx ,
" server returns printername %s incl. servername although we did not set servername " , info . info2 . printername ) ;
}
torture_assert ( tctx ,
PrinterInfo_to_SetPrinterInfo ( tctx , & info , 2 , & sinfo ) , " " ) ;
sinfo . info2 - > printername = printer_name_new ;
info_ctr . level = 2 ;
info_ctr . info = sinfo ;
torture_assert ( tctx ,
2010-06-03 23:39:51 +04:00
test_SetPrinter ( tctx , b , & t - > handle , & info_ctr , & devmode_ctr , & secdesc_ctr , 0 ) ,
2010-03-15 19:08:23 +03:00
" failed to call SetPrinter level 2 " ) ;
torture_assert ( tctx ,
2010-06-03 23:39:51 +04:00
test_GetPrinter_level ( tctx , b , & t - > handle , 2 , & info ) ,
2010-03-15 19:08:23 +03:00
" failed to call GetPrinter level 2 " ) ;
printer_name = talloc_strdup ( tctx , info . info2 . printername ) ;
q = strrchr ( info . info2 . printername , ' \\ ' ) ;
if ( q ) {
torture_warning ( tctx ,
" server returns printername %s incl. servername although we did not set servername " , info . info2 . printername ) ;
q + + ;
printer_name = q ;
}
torture_assert_str_equal ( tctx , printer_name , printer_name_new ,
" new printer name was not set " ) ;
2010-03-17 17:45:54 +03:00
/* samba currently cannot fully rename printers */
if ( ! torture_setting_bool ( tctx , " samba3 " , false ) ) {
torture_assert ( tctx ,
test_OpenPrinter_badname ( tctx , b , printer_name_orig ) ,
" still can open printer with oldname after rename " ) ;
} else {
torture_warning ( tctx , " *not* checking for open with oldname after rename for samba3 " ) ;
}
2010-03-15 19:08:23 +03:00
torture_assert ( tctx ,
call_OpenPrinterEx ( tctx , p , printer_name_new , NULL , & new_handle ) ,
" failed to open printer with new name " ) ;
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_GetPrinter_level ( tctx , b , & new_handle , 2 , & info ) ,
2010-03-15 19:08:23 +03:00
" failed to call GetPrinter level 2 " ) ;
2010-09-29 06:49:57 +04:00
torture_assert_str_equal ( tctx , info . info2 . printername , printer_name_new ,
2010-03-15 19:08:23 +03:00
" new printer name was not set " ) ;
torture_assert ( tctx ,
2010-03-16 13:45:51 +03:00
test_ClosePrinter ( tctx , b , & new_handle ) ,
2010-03-15 19:08:23 +03:00
" failed to close printer " ) ;
2010-03-16 15:52:48 +03:00
torture_comment ( tctx , " Printer rename operations test succeeded \n \n " ) ;
2010-03-15 19:08:23 +03:00
return ret ;
}
2010-10-03 00:13:44 +04:00
static bool test_openprinter ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * real_printername )
{
2013-01-14 20:26:31 +04:00
struct spoolss_UserLevelCtr userlevel_ctr ;
2010-10-03 00:13:44 +04:00
struct policy_handle handle ;
struct spoolss_UserLevel1 userlevel1 ;
const char * printername = NULL ;
int i ;
struct {
const char * suffix ;
WERROR expected_result ;
} tests [ ] = {
{
. suffix = " rubbish " ,
. expected_result = WERR_INVALID_PRINTER_NAME
} , {
. suffix = " , LocalOnl " ,
. expected_result = WERR_INVALID_PRINTER_NAME
} , {
. suffix = " , localOnly " ,
. expected_result = WERR_INVALID_PRINTER_NAME
} , {
. suffix = " , localonl " ,
. expected_result = WERR_INVALID_PRINTER_NAME
} , {
. suffix = " ,LocalOnl " ,
. expected_result = WERR_INVALID_PRINTER_NAME
} , {
. suffix = " ,localOnl2 " ,
. expected_result = WERR_INVALID_PRINTER_NAME
} , {
. suffix = " , DrvConver2t " ,
. expected_result = WERR_INVALID_PRINTER_NAME
} , {
. suffix = " , drvconvert " ,
. expected_result = WERR_INVALID_PRINTER_NAME
} , {
. suffix = " ,drvconvert " ,
. expected_result = WERR_INVALID_PRINTER_NAME
} , {
. suffix = " , DrvConvert " ,
. expected_result = WERR_OK
} , {
. suffix = " , DrvConvert " ,
. expected_result = WERR_INVALID_PRINTER_NAME
} , {
. suffix = " ,DrvConvert " ,
. expected_result = WERR_OK
} , {
. suffix = " , DrvConvertsadfasdf " ,
. expected_result = WERR_OK
} , {
. suffix = " ,DrvConvertasdfasd " ,
. expected_result = WERR_OK
} , {
. suffix = " , LocalOnly " ,
. expected_result = WERR_OK
} , {
. suffix = " , LocalOnly " ,
. expected_result = WERR_INVALID_PRINTER_NAME
} , {
. suffix = " ,LocalOnly " ,
. expected_result = WERR_OK
} , {
. suffix = " , LocalOnlysagi4gjfkd " ,
. expected_result = WERR_OK
} , {
. suffix = " ,LocalOnlysagi4gjfkd " ,
. expected_result = WERR_OK
}
} ;
userlevel1 . size = 1234 ;
userlevel1 . client = " hello " ;
userlevel1 . user = " spottyfoot! " ;
userlevel1 . build = 1 ;
userlevel1 . major = 2 ;
userlevel1 . minor = 3 ;
userlevel1 . processor = 4 ;
2013-01-14 20:26:31 +04:00
userlevel_ctr . level = 1 ;
userlevel_ctr . user_info . level1 = & userlevel1 ;
2010-10-03 00:13:44 +04:00
torture_comment ( tctx , " Testing openprinterex printername pattern \n " ) ;
torture_assert ( tctx ,
2013-01-14 20:26:31 +04:00
test_OpenPrinterEx ( tctx , b , real_printername , NULL , NULL , 0 ,
& userlevel_ctr , & handle ,
2010-10-03 00:13:44 +04:00
WERR_OK ) ,
" OpenPrinterEx failed " ) ;
test_ClosePrinter ( tctx , b , & handle ) ;
for ( i = 0 ; i < ARRAY_SIZE ( tests ) ; i + + ) {
printername = talloc_asprintf ( tctx , " %s%s " ,
real_printername ,
tests [ i ] . suffix ) ;
torture_assert ( tctx ,
2013-01-14 20:26:31 +04:00
test_OpenPrinterEx ( tctx , b , printername , NULL , NULL , 0 ,
& userlevel_ctr , & handle ,
2010-10-03 00:13:44 +04:00
tests [ i ] . expected_result ) ,
" OpenPrinterEx failed " ) ;
if ( W_ERROR_IS_OK ( tests [ i ] . expected_result ) ) {
test_ClosePrinter ( tctx , b , & handle ) ;
}
}
return true ;
}
2010-03-15 19:08:23 +03:00
2010-10-02 23:53:54 +04:00
static bool test_existing_printer_openprinterex ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
const char * name ,
const char * environment )
2003-11-30 14:57:40 +03:00
{
struct policy_handle handle ;
2007-09-03 17:13:25 +04:00
bool ret = true ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2003-11-30 14:57:40 +03:00
2010-10-03 00:13:44 +04:00
if ( ! test_openprinter ( tctx , b , name ) ) {
return false ;
}
2010-02-16 05:26:10 +03:00
if ( ! call_OpenPrinterEx ( tctx , p , name , NULL , & handle ) ) {
2007-09-03 17:13:25 +04:00
return false ;
2003-11-30 14:57:40 +03:00
}
2010-03-16 13:45:51 +03:00
if ( ! test_PrinterInfo_SD ( tctx , b , & handle ) ) {
2010-02-13 04:11:31 +03:00
ret = false ;
}
2010-03-16 13:45:51 +03:00
if ( ! test_GetPrinter ( tctx , b , & handle , environment ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2003-11-17 07:56:59 +03:00
}
2010-04-06 15:23:22 +04:00
if ( ! test_EnumForms_all ( tctx , b , & handle , false ) ) {
ret = false ;
}
if ( ! test_Forms ( tctx , b , & handle , false , name , NULL , NULL ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2003-11-26 09:26:18 +03:00
}
2010-04-06 15:23:22 +04:00
if ( ! test_Forms_winreg ( tctx , b , & handle , false , name ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2003-11-27 12:50:25 +03:00
}
2010-03-13 03:05:24 +03:00
if ( ! test_EnumPrinterData_all ( tctx , p , & handle ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2003-11-18 08:54:14 +03:00
}
2010-03-16 13:45:51 +03:00
if ( ! test_EnumPrinterDataEx ( tctx , b , & handle , " PrinterDriverData " , NULL , NULL ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2005-03-02 03:15:06 +03:00
}
2010-03-13 03:34:31 +03:00
if ( ! test_EnumPrinterData_consistency ( tctx , p , & handle ) ) {
2010-03-13 03:07:43 +03:00
ret = false ;
}
2010-06-03 23:39:51 +04:00
if ( ! test_printer_all_keys ( tctx , b , & handle ) ) {
2009-11-28 01:14:27 +03:00
ret = false ;
}
2010-03-16 13:45:51 +03:00
if ( ! test_PausePrinter ( tctx , b , & handle ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2005-06-06 17:21:49 +04:00
}
2010-03-16 13:45:51 +03:00
if ( ! test_DoPrintTest ( tctx , b , & handle ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2003-11-28 08:02:32 +03:00
}
2010-03-16 13:45:51 +03:00
if ( ! test_ResumePrinter ( tctx , b , & handle ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2005-06-06 17:21:49 +04:00
}
2010-03-16 13:45:51 +03:00
if ( ! test_SetPrinterData_matrix ( tctx , b , & handle , name , NULL , NULL ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2003-11-28 13:34:58 +03:00
}
2010-03-05 16:42:10 +03:00
if ( ! test_SetPrinterDataEx_matrix ( tctx , p , & handle , name , NULL , NULL ) ) {
2009-12-04 04:54:33 +03:00
ret = false ;
}
2009-04-13 19:06:37 +04:00
if ( ! torture_setting_bool ( tctx , " samba3 " , false ) ) {
if ( ! test_SecondaryClosePrinter ( tctx , p , & handle ) ) {
ret = false ;
}
2004-01-20 09:07:09 +03:00
}
2010-03-16 13:45:51 +03:00
if ( ! test_ClosePrinter ( tctx , b , & handle ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2003-11-17 07:56:59 +03:00
}
2009-06-30 13:38:41 +04:00
2003-11-17 07:56:59 +03:00
return ret ;
2003-11-17 06:38:13 +03:00
}
2010-02-25 21:06:39 +03:00
static bool test_EnumPrinters_old ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2003-11-16 07:20:29 +03:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
2003-11-16 07:20:29 +03:00
struct spoolss_EnumPrinters r ;
NTSTATUS status ;
2004-05-25 21:24:24 +04:00
uint16_t levels [ ] = { 1 , 2 , 4 , 5 } ;
2003-11-16 16:49:14 +03:00
int i ;
2007-09-03 17:13:25 +04:00
bool ret = true ;
2010-05-19 01:40:43 +04:00
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2003-11-16 07:20:29 +03:00
2003-11-16 16:49:14 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
2003-11-17 07:56:59 +03:00
union spoolss_PrinterInfo * info ;
2003-11-17 05:18:11 +03:00
int j ;
2009-02-06 19:09:30 +03:00
uint32_t needed ;
2009-02-16 18:42:21 +03:00
uint32_t count ;
2003-11-17 05:18:11 +03:00
2005-02-24 17:05:52 +03:00
r . in . flags = PRINTER_ENUM_LOCAL ;
r . in . server = " " ;
r . in . level = levels [ i ] ;
r . in . buffer = NULL ;
2005-06-14 19:52:31 +04:00
r . in . offered = 0 ;
2009-02-06 19:09:30 +03:00
r . out . needed = & needed ;
2009-02-16 18:42:21 +03:00
r . out . count = & count ;
2009-03-02 19:32:24 +03:00
r . out . info = & info ;
2003-11-16 07:20:29 +03:00
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Testing EnumPrinters level %u \n " , r . in . level ) ;
2003-11-16 07:20:29 +03:00
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EnumPrinters_r ( b , tctx , & r ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " EnumPrinters failed " ) ;
2005-02-24 17:05:52 +03:00
2003-11-17 05:58:10 +03:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
2010-04-08 13:56:27 +04:00
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
2003-11-17 05:18:11 +03:00
r . in . buffer = & blob ;
2009-02-06 19:09:30 +03:00
r . in . offered = needed ;
2010-03-16 13:45:51 +03:00
status = dcerpc_spoolss_EnumPrinters_r ( b , tctx , & r ) ;
2003-11-16 16:49:14 +03:00
}
2005-02-24 17:05:52 +03:00
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " EnumPrinters failed " ) ;
2005-02-25 08:39:01 +03:00
2007-09-03 17:13:25 +04:00
torture_assert_werr_ok ( tctx , r . out . result , " EnumPrinters failed " ) ;
2003-11-16 14:36:59 +03:00
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_ENUM_LEVEL ( spoolss_EnumPrinters , info , r . in . level , count , needed , 4 ) ;
2009-12-12 03:51:13 +03:00
2009-03-02 19:32:24 +03:00
if ( ! info ) {
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " No printers returned \n " ) ;
return true ;
2003-11-18 12:19:34 +03:00
}
2009-02-16 18:42:21 +03:00
for ( j = 0 ; j < count ; j + + ) {
2003-11-17 07:56:59 +03:00
if ( r . in . level = = 1 ) {
2009-04-13 16:48:32 +04:00
char * unc = talloc_strdup ( tctx , info [ j ] . info1 . name ) ;
2010-09-10 02:16:30 +04:00
char * slash , * name , * full_name ;
2009-04-13 16:48:32 +04:00
name = unc ;
if ( unc [ 0 ] = = ' \\ ' & & unc [ 1 ] = = ' \\ ' ) {
unc + = 2 ;
}
slash = strchr ( unc , ' \\ ' ) ;
if ( slash ) {
slash + + ;
name = slash ;
}
2010-09-10 02:16:30 +04:00
full_name = talloc_asprintf ( tctx , " \\ \\ %s \\ %s " ,
dcerpc_server_name ( p ) , name ) ;
if ( ! test_OpenPrinter ( tctx , p , name , ctx - > environment , true ) ) {
ret = false ;
}
if ( ! test_OpenPrinter ( tctx , p , full_name , ctx - > environment , true ) ) {
ret = false ;
}
if ( ! test_OpenPrinter ( tctx , p , name , ctx - > environment , false ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2003-11-17 07:56:59 +03:00
}
2010-10-02 23:53:54 +04:00
if ( ! test_existing_printer_openprinterex ( tctx , p , name , ctx - > environment ) ) {
2007-09-03 17:13:25 +04:00
ret = false ;
2003-11-17 07:56:59 +03:00
}
2003-11-17 06:38:13 +03:00
}
}
2003-11-16 07:20:29 +03:00
}
2005-02-24 17:05:52 +03:00
2003-11-16 16:49:14 +03:00
return ret ;
2003-11-16 07:20:29 +03:00
}
2010-09-29 06:49:57 +04:00
static bool test_EnumPrinters_level ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
uint32_t flags ,
const char * servername ,
uint32_t level ,
uint32_t * count_p ,
union spoolss_PrinterInfo * * info_p )
{
struct spoolss_EnumPrinters r ;
union spoolss_PrinterInfo * info ;
uint32_t needed ;
uint32_t count ;
r . in . flags = flags ;
r . in . server = servername ;
r . in . level = level ;
r . in . buffer = NULL ;
r . in . offered = 0 ;
r . out . needed = & needed ;
r . out . count = & count ;
r . out . info = & info ;
torture_comment ( tctx , " Testing EnumPrinters(%s) level %u \n " ,
r . in . server , r . in . level ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_EnumPrinters_r ( b , tctx , & r ) ,
" EnumPrinters failed " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
r . in . buffer = & blob ;
r . in . offered = needed ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_EnumPrinters_r ( b , tctx , & r ) ,
" EnumPrinters failed " ) ;
}
torture_assert_werr_ok ( tctx , r . out . result , " EnumPrinters failed " ) ;
CHECK_NEEDED_SIZE_ENUM_LEVEL ( spoolss_EnumPrinters , info , r . in . level , count , needed , 4 ) ;
if ( count_p ) {
* count_p = count ;
}
if ( info_p ) {
* info_p = info ;
}
return true ;
}
static const char * get_short_printername ( struct torture_context * tctx ,
const char * name )
{
const char * short_name ;
if ( name [ 0 ] = = ' \\ ' & & name [ 1 ] = = ' \\ ' ) {
name + = 2 ;
short_name = strchr ( name , ' \\ ' ) ;
if ( short_name ) {
return talloc_strdup ( tctx , short_name + 1 ) ;
}
}
return name ;
}
static const char * get_full_printername ( struct torture_context * tctx ,
const char * name )
{
const char * full_name = talloc_strdup ( tctx , name ) ;
char * p ;
if ( name & & name [ 0 ] = = ' \\ ' & & name [ 1 ] = = ' \\ ' ) {
name + = 2 ;
p = strchr ( name , ' \\ ' ) ;
if ( p ) {
return full_name ;
}
}
return NULL ;
}
static bool test_OnePrinter_servername ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct dcerpc_binding_handle * b ,
const char * servername ,
const char * printername )
{
union spoolss_PrinterInfo info ;
const char * short_name = get_short_printername ( tctx , printername ) ;
const char * full_name = get_full_printername ( tctx , printername ) ;
if ( short_name ) {
struct policy_handle handle ;
torture_assert ( tctx ,
call_OpenPrinterEx ( tctx , p , short_name , NULL , & handle ) ,
" failed to open printer " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , & handle , 2 , & info ) ,
" failed to get printer info " ) ;
torture_assert_casestr_equal ( tctx , info . info2 . servername , NULL ,
" unexpected servername " ) ;
torture_assert_casestr_equal ( tctx , info . info2 . printername , short_name ,
" unexpected printername " ) ;
if ( info . info2 . devmode ) {
const char * expected_devicename ;
expected_devicename = talloc_strndup ( tctx , short_name , MIN ( strlen ( short_name ) , 31 ) ) ;
torture_assert_casestr_equal ( tctx , info . info2 . devmode - > devicename , expected_devicename ,
" unexpected devicemode devicename " ) ;
}
torture_assert ( tctx ,
test_ClosePrinter ( tctx , b , & handle ) ,
" failed to close printer " ) ;
}
if ( full_name ) {
struct policy_handle handle ;
torture_assert ( tctx ,
call_OpenPrinterEx ( tctx , p , full_name , NULL , & handle ) ,
" failed to open printer " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , & handle , 2 , & info ) ,
" failed to get printer info " ) ;
torture_assert_casestr_equal ( tctx , info . info2 . servername , servername ,
" unexpected servername " ) ;
torture_assert_casestr_equal ( tctx , info . info2 . printername , full_name ,
" unexpected printername " ) ;
if ( info . info2 . devmode ) {
const char * expected_devicename ;
expected_devicename = talloc_strndup ( tctx , full_name , MIN ( strlen ( full_name ) , 31 ) ) ;
torture_assert_casestr_equal ( tctx , info . info2 . devmode - > devicename , expected_devicename ,
" unexpected devicemode devicename " ) ;
}
torture_assert ( tctx ,
test_ClosePrinter ( tctx , b , & handle ) ,
" failed to close printer " ) ;
}
return true ;
}
static bool test_EnumPrinters_servername ( struct torture_context * tctx ,
void * private_data )
{
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
int i ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
uint32_t count ;
union spoolss_PrinterInfo * info ;
const char * servername ;
uint32_t flags = PRINTER_ENUM_NAME | PRINTER_ENUM_LOCAL ;
torture_comment ( tctx , " Testing servername behaviour in EnumPrinters and GetPrinters \n " ) ;
servername = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
torture_assert ( tctx ,
test_EnumPrinters_level ( tctx , b , flags , servername , 2 , & count , & info ) ,
" failed to enumerate printers " ) ;
for ( i = 0 ; i < count ; i + + ) {
torture_assert_casestr_equal ( tctx , info [ i ] . info2 . servername , servername ,
" unexpected servername " ) ;
torture_assert ( tctx ,
test_OnePrinter_servername ( tctx , p , b , servername , info [ i ] . info2 . printername ) ,
" failed to check printer " ) ;
}
servername = " " ;
torture_assert ( tctx ,
test_EnumPrinters_level ( tctx , b , flags , servername , 2 , & count , & info ) ,
" failed to enumerate printers " ) ;
for ( i = 0 ; i < count ; i + + ) {
torture_assert_casestr_equal ( tctx , info [ i ] . info2 . servername , NULL ,
" unexpected servername " ) ;
torture_assert ( tctx ,
test_OnePrinter_servername ( tctx , p , b , servername , info [ i ] . info2 . printername ) ,
" failed to check printer " ) ;
}
return true ;
}
2013-12-04 17:01:52 +04:00
#if 0
2009-07-04 00:01:01 +04:00
static bool test_GetPrinterDriver ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-07-04 00:01:01 +04:00
struct policy_handle * handle ,
const char * driver_name )
{
struct spoolss_GetPrinterDriver r ;
uint32_t needed ;
r . in . handle = handle ;
r . in . architecture = " W32X86 " ;
r . in . level = 1 ;
r . in . buffer = NULL ;
r . in . offered = 0 ;
r . out . needed = & needed ;
torture_comment ( tctx , " Testing GetPrinterDriver level %d \n " , r . in . level ) ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_GetPrinterDriver_r ( b , tctx , & r ) ,
2009-07-04 00:01:01 +04:00
" failed to call GetPrinterDriver " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
2010-04-08 13:56:27 +04:00
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
2009-07-04 00:01:01 +04:00
r . in . buffer = & blob ;
r . in . offered = needed ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_GetPrinterDriver_r ( b , tctx , & r ) ,
2009-07-04 00:01:01 +04:00
" failed to call GetPrinterDriver " ) ;
}
torture_assert_werr_ok ( tctx , r . out . result ,
" failed to call GetPrinterDriver " ) ;
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_LEVEL ( spoolss_DriverInfo , r . out . info , r . in . level , needed , 4 ) ;
2009-12-12 03:51:13 +03:00
2009-07-04 00:01:01 +04:00
return true ;
}
2013-12-04 17:01:52 +04:00
# endif
2009-07-04 00:01:01 +04:00
2010-04-20 18:25:27 +04:00
static bool test_GetPrinterDriver2_level ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * driver_name ,
const char * architecture ,
uint32_t level ,
uint32_t client_major_version ,
uint32_t client_minor_version ,
2010-04-20 21:50:37 +04:00
union spoolss_DriverInfo * info_p ,
WERROR * result_p )
2010-04-20 18:25:27 +04:00
2003-11-30 14:57:40 +03:00
{
struct spoolss_GetPrinterDriver2 r ;
2009-02-06 15:28:48 +03:00
uint32_t needed ;
uint32_t server_major_version ;
uint32_t server_minor_version ;
2003-11-30 14:57:40 +03:00
r . in . handle = handle ;
2010-02-25 21:06:39 +03:00
r . in . architecture = architecture ;
2010-04-20 18:25:27 +04:00
r . in . client_major_version = client_major_version ;
r . in . client_minor_version = client_minor_version ;
r . in . buffer = NULL ;
r . in . offered = 0 ;
r . in . level = level ;
2009-02-06 15:28:48 +03:00
r . out . needed = & needed ;
r . out . server_major_version = & server_major_version ;
r . out . server_minor_version = & server_minor_version ;
2003-11-30 14:57:40 +03:00
2010-04-20 18:25:27 +04:00
torture_comment ( tctx , " Testing GetPrinterDriver2(%s) level %d \n " ,
driver_name , r . in . level ) ;
2009-12-16 00:26:39 +03:00
2010-04-20 18:25:27 +04:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetPrinterDriver2_r ( b , tctx , & r ) ,
" failed to call GetPrinterDriver2 " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
r . in . buffer = & blob ;
r . in . offered = needed ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetPrinterDriver2_r ( b , tctx , & r ) ,
2009-07-04 00:01:01 +04:00
" failed to call GetPrinterDriver2 " ) ;
2010-04-20 18:25:27 +04:00
}
2005-02-25 08:39:01 +03:00
2010-04-20 21:50:37 +04:00
if ( result_p ) {
* result_p = r . out . result ;
}
2010-04-20 18:25:27 +04:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_INVALID_LEVEL ) ) {
switch ( r . in . level ) {
case 101 :
case 8 :
torture_comment ( tctx ,
" level %d not implemented, not considering as an error \n " ,
r . in . level ) ;
return true ;
default :
break ;
2009-12-16 00:26:39 +03:00
}
2010-04-20 18:25:27 +04:00
}
torture_assert_werr_ok ( tctx , r . out . result ,
" failed to call GetPrinterDriver2 " ) ;
2010-05-09 19:20:01 +04:00
CHECK_NEEDED_SIZE_LEVEL ( spoolss_DriverInfo , r . out . info , r . in . level , needed , 4 ) ;
2010-04-20 18:25:27 +04:00
if ( info_p ) {
* info_p = * r . out . info ;
}
return true ;
}
static bool test_GetPrinterDriver2 ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle ,
const char * driver_name ,
const char * architecture )
{
uint16_t levels [ ] = { 1 , 2 , 3 , 4 , 5 , 6 , 8 , 101 } ;
int i ;
2003-11-30 14:57:40 +03:00
2009-12-16 00:26:39 +03:00
2010-04-20 18:25:27 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
torture_assert ( tctx ,
2010-04-20 21:50:37 +04:00
test_GetPrinterDriver2_level ( tctx , b , handle , driver_name , architecture , levels [ i ] , 3 , 0 , NULL , NULL ) ,
2010-04-20 18:25:27 +04:00
" " ) ;
2009-12-16 00:26:39 +03:00
}
2009-12-12 03:51:13 +03:00
2007-10-07 02:28:14 +04:00
return true ;
2003-11-30 14:57:40 +03:00
}
2005-04-02 10:51:54 +04:00
2009-06-30 13:38:41 +04:00
static bool test_EnumPrinterDrivers_old ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2003-11-30 14:57:40 +03:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
2005-02-24 17:05:52 +03:00
uint16_t levels [ ] = { 1 , 2 , 3 , 4 , 5 , 6 } ;
2003-11-30 14:57:40 +03:00
int i ;
2010-05-19 01:40:43 +04:00
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-04-21 17:08:40 +04:00
const char * server_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2003-11-30 14:57:40 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
2009-02-16 18:42:21 +03:00
uint32_t count ;
2009-03-02 19:32:24 +03:00
union spoolss_DriverInfo * info ;
2009-02-06 19:09:30 +03:00
2010-04-21 17:08:40 +04:00
torture_assert ( tctx ,
2010-05-19 01:40:43 +04:00
test_EnumPrinterDrivers_args ( tctx , b , server_name , ctx - > environment , levels [ i ] , & count , & info ) ,
2010-04-21 17:08:40 +04:00
" failed to enumerate drivers " ) ;
2003-11-30 14:57:40 +03:00
2009-03-02 19:32:24 +03:00
if ( ! info ) {
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " No printer drivers returned \n " ) ;
2005-02-21 16:54:06 +03:00
break ;
2003-11-30 14:57:40 +03:00
}
}
2005-02-21 16:54:06 +03:00
2007-09-03 17:13:25 +04:00
return true ;
}
2009-07-03 11:56:28 +04:00
static bool test_DeletePrinter ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-07-03 11:56:28 +04:00
struct policy_handle * handle )
{
struct spoolss_DeletePrinter r ;
torture_comment ( tctx , " Testing DeletePrinter \n " ) ;
r . in . handle = handle ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_DeletePrinter_r ( b , tctx , & r ) ,
2009-07-03 11:56:28 +04:00
" failed to delete printer " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" failed to delete printer " ) ;
return true ;
}
static bool test_EnumPrinters_findname ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-07-03 11:56:28 +04:00
uint32_t flags ,
uint32_t level ,
const char * name ,
bool * found )
{
struct spoolss_EnumPrinters e ;
uint32_t count ;
union spoolss_PrinterInfo * info ;
uint32_t needed ;
int i ;
* found = false ;
e . in . flags = flags ;
e . in . server = NULL ;
e . in . level = level ;
e . in . buffer = NULL ;
e . in . offered = 0 ;
e . out . count = & count ;
e . out . info = & info ;
e . out . needed = & needed ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_EnumPrinters_r ( b , tctx , & e ) ,
2009-07-03 11:56:28 +04:00
" failed to enum printers " ) ;
if ( W_ERROR_EQUAL ( e . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
2010-04-08 13:56:27 +04:00
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
2009-07-03 11:56:28 +04:00
e . in . buffer = & blob ;
e . in . offered = needed ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_EnumPrinters_r ( b , tctx , & e ) ,
2009-07-03 11:56:28 +04:00
" failed to enum printers " ) ;
}
torture_assert_werr_ok ( tctx , e . out . result ,
" failed to enum printers " ) ;
for ( i = 0 ; i < count ; i + + ) {
const char * current = NULL ;
2010-03-10 04:50:32 +03:00
const char * q ;
2009-07-03 11:56:28 +04:00
switch ( level ) {
case 1 :
current = info [ i ] . info1 . name ;
break ;
}
if ( strequal ( current , name ) ) {
* found = true ;
break ;
}
2010-02-18 03:43:08 +03:00
2010-03-10 04:50:32 +03:00
q = strrchr ( current , ' \\ ' ) ;
if ( q ) {
2010-02-18 03:43:08 +03:00
if ( ! e . in . server ) {
torture_warning ( tctx ,
" server returns printername %s incl. servername although we did not set servername " , current ) ;
}
2010-03-10 04:50:32 +03:00
q + + ;
if ( strequal ( q , name ) ) {
2010-02-18 03:43:08 +03:00
* found = true ;
break ;
}
}
2009-07-03 11:56:28 +04:00
}
return true ;
}
static bool test_AddPrinter_wellknown ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
const char * printername ,
bool ex )
{
WERROR result ;
struct spoolss_AddPrinter r ;
struct spoolss_AddPrinterEx rex ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_SetPrinterInfo1 info1 ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
struct spoolss_UserLevelCtr userlevel_ctr ;
struct policy_handle handle ;
bool found = false ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-07-03 11:56:28 +04:00
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
ZERO_STRUCT ( userlevel_ctr ) ;
ZERO_STRUCT ( info1 ) ;
2010-05-04 12:21:52 +04:00
torture_comment ( tctx , " Testing AddPrinter%s(%s) level 1 \n " ,
ex ? " Ex " : " " , printername ) ;
2009-07-03 11:56:28 +04:00
/* try to add printer to wellknown printer list (level 1) */
userlevel_ctr . level = 1 ;
info_ctr . info . info1 = & info1 ;
info_ctr . level = 1 ;
rex . in . server = NULL ;
rex . in . info_ctr = & info_ctr ;
rex . in . devmode_ctr = & devmode_ctr ;
rex . in . secdesc_ctr = & secdesc_ctr ;
rex . in . userlevel_ctr = & userlevel_ctr ;
rex . out . handle = & handle ;
r . in . server = NULL ;
r . in . info_ctr = & info_ctr ;
r . in . devmode_ctr = & devmode_ctr ;
r . in . secdesc_ctr = & secdesc_ctr ;
r . out . handle = & handle ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , ex ? dcerpc_spoolss_AddPrinterEx_r ( b , tctx , & rex ) :
dcerpc_spoolss_AddPrinter_r ( b , tctx , & r ) ,
2009-07-03 11:56:28 +04:00
" failed to add printer " ) ;
result = ex ? rex . out . result : r . out . result ;
torture_assert_werr_equal ( tctx , result , WERR_INVALID_PRINTER_NAME ,
" unexpected result code " ) ;
info1 . name = printername ;
info1 . flags = PRINTER_ATTRIBUTE_SHARED ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , ex ? dcerpc_spoolss_AddPrinterEx_r ( b , tctx , & rex ) :
dcerpc_spoolss_AddPrinter_r ( b , tctx , & r ) ,
2009-07-03 11:56:28 +04:00
" failed to add printer " ) ;
result = ex ? rex . out . result : r . out . result ;
torture_assert_werr_equal ( tctx , result , WERR_PRINTER_ALREADY_EXISTS ,
" unexpected result code " ) ;
/* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
better do a real check to see the printer is really there */
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_EnumPrinters_findname ( tctx , b ,
2009-07-03 11:56:28 +04:00
PRINTER_ENUM_NETWORK , 1 ,
printername ,
& found ) ,
" failed to enum printers " ) ;
torture_assert ( tctx , found , " failed to find newly added printer " ) ;
info1 . flags = 0 ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , ex ? dcerpc_spoolss_AddPrinterEx_r ( b , tctx , & rex ) :
dcerpc_spoolss_AddPrinter_r ( b , tctx , & r ) ,
2009-07-03 11:56:28 +04:00
" failed to add printer " ) ;
result = ex ? rex . out . result : r . out . result ;
torture_assert_werr_equal ( tctx , result , WERR_PRINTER_ALREADY_EXISTS ,
" unexpected result code " ) ;
/* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
better do a real check to see the printer has really been removed
from the well known printer list */
found = false ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_EnumPrinters_findname ( tctx , b ,
2009-07-03 11:56:28 +04:00
PRINTER_ENUM_NETWORK , 1 ,
printername ,
& found ) ,
" failed to enum printers " ) ;
#if 0
torture_assert ( tctx , ! found , " printer still in well known printer list " ) ;
# endif
return true ;
}
static bool test_AddPrinter_normal ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle_p ,
const char * printername ,
const char * drivername ,
const char * portname ,
2010-04-28 19:00:53 +04:00
struct spoolss_DeviceMode * devmode ,
2009-07-03 11:56:28 +04:00
bool ex )
{
WERROR result ;
struct spoolss_AddPrinter r ;
struct spoolss_AddPrinterEx rex ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_SetPrinterInfo2 info2 ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
struct spoolss_UserLevelCtr userlevel_ctr ;
struct policy_handle handle ;
bool found = false ;
2010-02-17 22:45:26 +03:00
bool existing_printer_deleted = false ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-07-03 11:56:28 +04:00
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
ZERO_STRUCT ( userlevel_ctr ) ;
2010-05-04 12:21:52 +04:00
torture_comment ( tctx , " Testing AddPrinter%s(%s) level 2 \n " ,
ex ? " Ex " : " " , printername ) ;
2009-07-03 11:56:28 +04:00
2010-04-28 19:00:53 +04:00
devmode_ctr . devmode = devmode ;
2009-07-03 11:56:28 +04:00
userlevel_ctr . level = 1 ;
rex . in . server = NULL ;
rex . in . info_ctr = & info_ctr ;
rex . in . devmode_ctr = & devmode_ctr ;
rex . in . secdesc_ctr = & secdesc_ctr ;
rex . in . userlevel_ctr = & userlevel_ctr ;
rex . out . handle = & handle ;
r . in . server = NULL ;
r . in . info_ctr = & info_ctr ;
r . in . devmode_ctr = & devmode_ctr ;
r . in . secdesc_ctr = & secdesc_ctr ;
r . out . handle = & handle ;
again :
/* try to add printer to printer list (level 2) */
ZERO_STRUCT ( info2 ) ;
info_ctr . info . info2 = & info2 ;
info_ctr . level = 2 ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , ex ? dcerpc_spoolss_AddPrinterEx_r ( b , tctx , & rex ) :
dcerpc_spoolss_AddPrinter_r ( b , tctx , & r ) ,
2009-07-03 11:56:28 +04:00
" failed to add printer " ) ;
result = ex ? rex . out . result : r . out . result ;
torture_assert_werr_equal ( tctx , result , WERR_INVALID_PRINTER_NAME ,
" unexpected result code " ) ;
info2 . printername = printername ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , ex ? dcerpc_spoolss_AddPrinterEx_r ( b , tctx , & rex ) :
dcerpc_spoolss_AddPrinter_r ( b , tctx , & r ) ,
2009-07-03 11:56:28 +04:00
" failed to add printer " ) ;
result = ex ? rex . out . result : r . out . result ;
if ( W_ERROR_EQUAL ( result , WERR_PRINTER_ALREADY_EXISTS ) ) {
struct policy_handle printer_handle ;
2010-02-17 22:45:26 +03:00
if ( existing_printer_deleted ) {
torture_fail ( tctx , " already deleted printer still existing? " ) ;
}
2010-02-16 05:26:10 +03:00
torture_assert ( tctx , call_OpenPrinterEx ( tctx , p , printername , NULL , & printer_handle ) ,
2009-07-03 11:56:28 +04:00
" failed to open printer handle " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_DeletePrinter ( tctx , b , & printer_handle ) ,
2009-07-03 11:56:28 +04:00
" failed to delete printer " ) ;
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_ClosePrinter ( tctx , b , & printer_handle ) ,
2009-07-03 11:56:28 +04:00
" failed to close server handle " ) ;
2010-02-17 22:45:26 +03:00
existing_printer_deleted = true ;
2009-07-03 11:56:28 +04:00
goto again ;
}
torture_assert_werr_equal ( tctx , result , WERR_UNKNOWN_PORT ,
" unexpected result code " ) ;
info2 . portname = portname ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , ex ? dcerpc_spoolss_AddPrinterEx_r ( b , tctx , & rex ) :
dcerpc_spoolss_AddPrinter_r ( b , tctx , & r ) ,
2009-07-03 11:56:28 +04:00
" failed to add printer " ) ;
result = ex ? rex . out . result : r . out . result ;
torture_assert_werr_equal ( tctx , result , WERR_UNKNOWN_PRINTER_DRIVER ,
" unexpected result code " ) ;
info2 . drivername = drivername ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , ex ? dcerpc_spoolss_AddPrinterEx_r ( b , tctx , & rex ) :
dcerpc_spoolss_AddPrinter_r ( b , tctx , & r ) ,
2009-07-03 11:56:28 +04:00
" failed to add printer " ) ;
result = ex ? rex . out . result : r . out . result ;
2015-07-27 00:02:57 +03:00
/* w2k8r2 allows one to add printer w/o defining printprocessor */
2009-07-03 11:56:28 +04:00
2010-02-15 21:23:35 +03:00
if ( ! W_ERROR_IS_OK ( result ) ) {
torture_assert_werr_equal ( tctx , result , WERR_UNKNOWN_PRINTPROCESSOR ,
" unexpected result code " ) ;
info2 . printprocessor = " winprint " ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , ex ? dcerpc_spoolss_AddPrinterEx_r ( b , tctx , & rex ) :
dcerpc_spoolss_AddPrinter_r ( b , tctx , & r ) ,
2010-02-15 21:23:35 +03:00
" failed to add printer " ) ;
result = ex ? rex . out . result : r . out . result ;
torture_assert_werr_ok ( tctx , result ,
" failed to add printer " ) ;
}
2009-07-03 11:56:28 +04:00
* handle_p = handle ;
/* we are paranoid, really check if the printer is there now */
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_EnumPrinters_findname ( tctx , b ,
2009-07-03 11:56:28 +04:00
PRINTER_ENUM_LOCAL , 1 ,
printername ,
& found ) ,
" failed to enum printers " ) ;
torture_assert ( tctx , found , " failed to find newly added printer " ) ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , ex ? dcerpc_spoolss_AddPrinterEx_r ( b , tctx , & rex ) :
dcerpc_spoolss_AddPrinter_r ( b , tctx , & r ) ,
2009-07-03 11:56:28 +04:00
" failed to add printer " ) ;
result = ex ? rex . out . result : r . out . result ;
torture_assert_werr_equal ( tctx , result , WERR_PRINTER_ALREADY_EXISTS ,
" unexpected result code " ) ;
return true ;
}
static bool test_printer_info ( struct torture_context * tctx ,
2010-06-03 23:39:51 +04:00
void * private_data )
2009-07-03 11:56:28 +04:00
{
2010-06-03 23:39:51 +04:00
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-07-03 11:56:28 +04:00
bool ret = true ;
2010-02-18 03:45:06 +03:00
if ( torture_setting_bool ( tctx , " samba3 " , false ) ) {
torture_skip ( tctx , " skipping printer info cross tests against samba 3 " ) ;
}
2010-06-03 23:39:51 +04:00
if ( ! test_PrinterInfo ( tctx , b , & t - > handle ) ) {
2009-07-03 11:56:28 +04:00
ret = false ;
}
2010-06-03 23:39:51 +04:00
if ( ! test_SetPrinter_errors ( tctx , b , & t - > handle ) ) {
2009-07-03 11:56:28 +04:00
ret = false ;
}
return ret ;
}
2009-12-04 04:54:33 +03:00
static bool test_EnumPrinterKey ( struct torture_context * tctx ,
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b ,
2009-12-04 04:54:33 +03:00
struct policy_handle * handle ,
const char * key_name ,
const char * * * array )
2009-11-20 18:33:29 +03:00
{
2009-12-04 04:54:33 +03:00
struct spoolss_EnumPrinterKey r ;
2009-12-10 16:21:12 +03:00
uint32_t needed = 0 ;
union spoolss_KeyNames key_buffer ;
int32_t offered [ ] = { 0 , 1 , 2 , 3 , 4 , 5 , - 1 , - 2 , - 3 , - 4 , - 5 , 256 , 512 , 1024 , 2048 } ;
uint32_t _ndr_size ;
2009-12-09 17:31:51 +03:00
int i ;
2009-11-20 18:33:29 +03:00
2009-12-04 04:54:33 +03:00
r . in . handle = handle ;
r . in . key_name = key_name ;
r . out . key_buffer = & key_buffer ;
r . out . needed = & needed ;
2009-12-10 16:21:12 +03:00
r . out . _ndr_size = & _ndr_size ;
2009-11-20 18:33:29 +03:00
2009-12-09 17:31:51 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( offered ) ; i + + ) {
2009-12-10 16:21:12 +03:00
if ( offered [ i ] < 0 & & needed ) {
if ( needed < = 4 ) {
continue ;
}
r . in . offered = needed + offered [ i ] ;
} else {
r . in . offered = offered [ i ] ;
}
ZERO_STRUCT ( key_buffer ) ;
2009-12-09 17:31:51 +03:00
torture_comment ( tctx , " Testing EnumPrinterKey(%s) with %d offered \n " , r . in . key_name , r . in . offered ) ;
2009-11-20 18:33:29 +03:00
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_EnumPrinterKey_r ( b , tctx , & r ) ,
2009-11-20 18:33:29 +03:00
" failed to call EnumPrinterKey " ) ;
2009-12-09 17:31:51 +03:00
if ( W_ERROR_EQUAL ( r . out . result , WERR_MORE_DATA ) ) {
2009-12-10 16:21:12 +03:00
torture_assert ( tctx , ( _ndr_size = = r . in . offered / 2 ) ,
talloc_asprintf ( tctx , " EnumPrinterKey size mismatch, _ndr_size %d (expected %d) " ,
_ndr_size , r . in . offered / 2 ) ) ;
2009-12-09 17:31:51 +03:00
r . in . offered = needed ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_EnumPrinterKey_r ( b , tctx , & r ) ,
2009-12-09 17:31:51 +03:00
" failed to call EnumPrinterKey " ) ;
}
2009-12-10 16:21:12 +03:00
if ( offered [ i ] > 0 ) {
torture_assert_werr_ok ( tctx , r . out . result ,
" failed to call EnumPrinterKey " ) ;
}
torture_assert ( tctx , ( _ndr_size = = r . in . offered / 2 ) ,
2009-12-09 17:31:51 +03:00
talloc_asprintf ( tctx , " EnumPrinterKey size mismatch, _ndr_size %d (expected %d) " ,
2009-12-10 16:21:12 +03:00
_ndr_size , r . in . offered / 2 ) ) ;
2009-11-20 18:33:29 +03:00
2009-12-09 17:31:51 +03:00
torture_assert ( tctx , ( * r . out . needed < = r . in . offered ) ,
talloc_asprintf ( tctx , " EnumPrinterKey size mismatch: needed %d is not <= offered %d " , * r . out . needed , r . in . offered ) ) ;
2009-12-10 16:21:12 +03:00
torture_assert ( tctx , ( * r . out . needed < = _ndr_size * 2 ) ,
talloc_asprintf ( tctx , " EnumPrinterKey size mismatch: needed %d is not <= _ndr_size %d * 2 " , * r . out . needed , _ndr_size ) ) ;
2009-12-09 17:31:51 +03:00
2009-12-10 16:21:12 +03:00
if ( key_buffer . string_array ) {
uint32_t calc_needed = 0 ;
int s ;
for ( s = 0 ; key_buffer . string_array [ s ] ; s + + ) {
calc_needed + = strlen_m_term ( key_buffer . string_array [ s ] ) * 2 ;
}
if ( ! key_buffer . string_array [ 0 ] ) {
calc_needed + = 2 ;
}
calc_needed + = 2 ;
torture_assert_int_equal ( tctx , * r . out . needed , calc_needed ,
" EnumPrinterKey unexpected size " ) ;
}
2009-12-09 17:31:51 +03:00
}
2009-12-03 01:38:05 +03:00
2009-12-04 04:54:33 +03:00
if ( array ) {
2009-12-10 16:21:12 +03:00
* array = key_buffer . string_array ;
2009-11-20 18:33:29 +03:00
}
2009-12-04 04:54:33 +03:00
return true ;
}
2010-06-03 23:39:51 +04:00
bool test_printer_all_keys ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle )
2009-12-04 04:54:33 +03:00
{
const char * * key_array = NULL ;
int i ;
2010-03-16 15:52:48 +03:00
torture_comment ( tctx , " Testing Printer Keys \n " ) ;
2010-02-19 17:25:42 +03:00
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_EnumPrinterKey ( tctx , b , handle , " " , & key_array ) ,
2009-12-04 04:54:33 +03:00
" failed to call test_EnumPrinterKey " ) ;
for ( i = 0 ; key_array & & key_array [ i ] ; i + + ) {
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_EnumPrinterKey ( tctx , b , handle , key_array [ i ] , NULL ) ,
2009-12-04 04:54:33 +03:00
" failed to call test_EnumPrinterKey " ) ;
}
2009-12-03 01:38:05 +03:00
for ( i = 0 ; key_array & & key_array [ i ] ; i + + ) {
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_EnumPrinterDataEx ( tctx , b , handle , key_array [ i ] , NULL , NULL ) ,
2009-12-04 00:38:38 +03:00
" failed to call test_EnumPrinterDataEx " ) ;
2009-11-20 18:33:29 +03:00
}
2010-03-16 15:52:48 +03:00
torture_comment ( tctx , " Printer Keys test succeeded \n \n " ) ;
2009-11-20 18:33:29 +03:00
return true ;
}
2010-10-03 00:13:44 +04:00
static bool test_openprinter_wrap ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
const char * printername = t - > info2 . printername ;
return test_openprinter ( tctx , b , printername ) ;
}
2010-06-03 23:39:51 +04:00
static bool test_csetprinter ( struct torture_context * tctx ,
void * private_data )
2010-02-17 13:21:56 +03:00
{
2010-06-03 23:39:51 +04:00
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
2010-03-15 19:08:23 +03:00
2010-06-03 23:39:51 +04:00
const char * printername = talloc_asprintf ( tctx , " %s2 " , t - > info2 . printername ) ;
const char * drivername = t - > added_driver ? t - > driver . info8 . driver_name : t - > info2 . drivername ;
const char * portname = t - > info2 . portname ;
2010-02-17 13:21:56 +03:00
2010-04-20 16:15:24 +04:00
union spoolss_PrinterInfo info ;
struct policy_handle new_handle , new_handle2 ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
torture_comment ( tctx , " Testing c_setprinter \n " ) ;
torture_assert ( tctx ,
2010-06-03 23:39:51 +04:00
test_GetPrinter_level ( tctx , b , & t - > handle , 0 , & info ) ,
2010-04-20 16:15:24 +04:00
" failed to get level 0 printer info " ) ;
torture_comment ( tctx , " csetprinter on initial printer handle: %d \n " ,
info . info0 . c_setprinter ) ;
/* check if c_setprinter on 1st handle increases after a printer has
* been added */
torture_assert ( tctx ,
2010-04-28 19:00:53 +04:00
test_AddPrinter_normal ( tctx , p , & new_handle , printername , drivername , portname , NULL , false ) ,
2010-04-20 16:15:24 +04:00
" failed to add new printer " ) ;
torture_assert ( tctx ,
2010-06-03 23:39:51 +04:00
test_GetPrinter_level ( tctx , b , & t - > handle , 0 , & info ) ,
2010-04-20 16:15:24 +04:00
" failed to get level 0 printer info " ) ;
torture_comment ( tctx , " csetprinter on initial printer handle (after add): %d \n " ,
info . info0 . c_setprinter ) ;
/* check if c_setprinter on new handle increases after a printer has
* been added */
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , & new_handle , 0 , & info ) ,
" failed to get level 0 printer info " ) ;
torture_comment ( tctx , " csetprinter on created handle: %d \n " ,
info . info0 . c_setprinter ) ;
/* open the new printer and check if c_setprinter increases */
torture_assert ( tctx ,
call_OpenPrinterEx ( tctx , p , printername , NULL , & new_handle2 ) ,
" failed to open created printer " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , & new_handle2 , 0 , & info ) ,
" failed to get level 0 printer info " ) ;
torture_comment ( tctx , " csetprinter on new handle (after openprinter): %d \n " ,
info . info0 . c_setprinter ) ;
/* cleanup */
torture_assert ( tctx ,
test_ClosePrinter ( tctx , b , & new_handle2 ) ,
" failed to close printer " ) ;
torture_assert ( tctx ,
test_DeletePrinter ( tctx , b , & new_handle ) ,
" failed to delete new printer " ) ;
return true ;
}
2010-04-27 13:30:35 +04:00
static bool compose_local_driver_directory ( struct torture_context * tctx ,
const char * environment ,
const char * local_dir ,
const char * * path )
{
char * p ;
p = strrchr ( local_dir , ' / ' ) ;
if ( ! p ) {
return NULL ;
}
p + + ;
2017-01-10 20:20:18 +03:00
if ( strequal ( environment , SPOOLSS_ARCHITECTURE_x64 ) ) {
2010-04-27 13:30:35 +04:00
if ( ! strequal ( p , " x64 " ) ) {
* path = talloc_asprintf ( tctx , " %s/x64 " , local_dir ) ;
}
2017-01-10 20:20:18 +03:00
} else if ( strequal ( environment , SPOOLSS_ARCHITECTURE_NT_X86 ) ) {
2010-04-27 13:30:35 +04:00
if ( ! strequal ( p , " i386 " ) ) {
* path = talloc_asprintf ( tctx , " %s/i386 " , local_dir ) ;
}
} else {
torture_assert ( tctx , " unknown environment: '%s' \n " , environment ) ;
}
return true ;
}
2013-12-04 17:01:52 +04:00
#if 0
2010-04-28 19:00:53 +04:00
static struct spoolss_DeviceMode * torture_devicemode ( TALLOC_CTX * mem_ctx ,
const char * devicename )
{
struct spoolss_DeviceMode * r ;
r = talloc_zero ( mem_ctx , struct spoolss_DeviceMode ) ;
if ( r = = NULL ) {
return NULL ;
}
r - > devicename = talloc_strdup ( r , devicename ) ;
r - > specversion = DMSPEC_NT4_AND_ABOVE ;
r - > driverversion = 0x0600 ;
r - > size = 0x00dc ;
r - > __driverextra_length = 0 ;
r - > fields = DEVMODE_FORMNAME |
DEVMODE_TTOPTION |
DEVMODE_PRINTQUALITY |
DEVMODE_DEFAULTSOURCE |
DEVMODE_COPIES |
DEVMODE_SCALE |
DEVMODE_PAPERSIZE |
DEVMODE_ORIENTATION ;
r - > orientation = DMORIENT_PORTRAIT ;
r - > papersize = DMPAPER_LETTER ;
r - > paperlength = 0 ;
r - > paperwidth = 0 ;
r - > scale = 100 ;
r - > copies = 55 ;
r - > defaultsource = DMBIN_FORMSOURCE ;
r - > printquality = DMRES_HIGH ;
r - > color = DMRES_MONOCHROME ;
r - > duplex = DMDUP_SIMPLEX ;
r - > yresolution = 0 ;
r - > ttoption = DMTT_SUBDEV ;
r - > collate = DMCOLLATE_FALSE ;
r - > formname = talloc_strdup ( r , " Letter " ) ;
return r ;
}
2013-12-04 17:01:52 +04:00
# endif
2010-04-28 19:00:53 +04:00
2010-02-23 15:05:52 +03:00
static bool test_architecture_buffer ( struct torture_context * tctx ,
2010-05-19 01:40:43 +04:00
void * private_data )
2010-02-23 15:05:52 +03:00
{
2010-05-19 01:40:43 +04:00
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
2010-02-23 15:05:52 +03:00
struct spoolss_OpenPrinterEx r ;
struct spoolss_UserLevel1 u1 ;
struct policy_handle handle ;
uint32_t architectures [ ] = {
PROCESSOR_ARCHITECTURE_INTEL ,
PROCESSOR_ARCHITECTURE_IA64 ,
PROCESSOR_ARCHITECTURE_AMD64
} ;
uint32_t needed [ 3 ] ;
int i ;
2010-05-19 01:40:43 +04:00
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
2010-03-16 13:45:51 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-02-23 15:05:52 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( architectures ) ; i + + ) {
torture_comment ( tctx , " Testing OpenPrinterEx with architecture %d \n " , architectures [ i ] ) ;
u1 . size = 0 ;
u1 . client = NULL ;
u1 . user = NULL ;
u1 . build = 0 ;
u1 . major = 3 ;
u1 . minor = 0 ;
u1 . processor = architectures [ i ] ;
r . in . printername = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
r . in . datatype = NULL ;
r . in . devmode_ctr . devmode = NULL ;
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
2013-01-14 20:26:31 +04:00
r . in . userlevel_ctr . level = 1 ;
r . in . userlevel_ctr . user_info . level1 = & u1 ;
2010-02-23 15:05:52 +03:00
r . out . handle = & handle ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_OpenPrinterEx_r ( b , tctx , & r ) , " " ) ;
2010-02-23 15:05:52 +03:00
torture_assert_werr_ok ( tctx , r . out . result , " " ) ;
{
struct spoolss_EnumPrinters e ;
uint32_t count ;
union spoolss_PrinterInfo * info ;
e . in . flags = PRINTER_ENUM_LOCAL ;
e . in . server = NULL ;
e . in . level = 2 ;
e . in . buffer = NULL ;
e . in . offered = 0 ;
e . out . count = & count ;
e . out . info = & info ;
e . out . needed = & needed [ i ] ;
2010-03-16 13:45:51 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_EnumPrinters_r ( b , tctx , & e ) , " " ) ;
2010-02-23 15:05:52 +03:00
#if 0
torture_comment ( tctx , " needed was %d \n " , needed [ i ] ) ;
# endif
}
2010-03-16 13:45:51 +03:00
torture_assert ( tctx , test_ClosePrinter ( tctx , b , & handle ) , " " ) ;
2010-02-23 15:05:52 +03:00
}
for ( i = 1 ; i < ARRAY_SIZE ( architectures ) ; i + + ) {
if ( needed [ i - 1 ] ! = needed [ i ] ) {
torture_fail ( tctx ,
talloc_asprintf ( tctx , " needed size %d for architecture %d != needed size %d for architecture %d \n " ,
needed [ i - 1 ] , architectures [ i - 1 ] , needed [ i ] , architectures [ i ] ) ) ;
}
}
return true ;
}
2016-08-20 00:27:19 +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 spoolss_GetCorePrinterDrivers r ;
struct spoolss_CorePrinterDriver core_printer_drivers ;
DATA_BLOB blob ;
const char * * s ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct GUID guid ;
s = talloc_zero_array ( tctx , const char * , 2 ) ;
r . in . servername = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
r . in . architecture = " foobar " ;
r . in . core_driver_size = 0 ;
r . in . core_driver_dependencies = " " ;
r . in . core_printer_driver_count = 0 ;
r . out . core_printer_drivers = & core_printer_drivers ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetCorePrinterDrivers_r ( b , tctx , & r ) ,
" spoolss_GetCorePrinterDrivers failed " ) ;
torture_assert_hresult_equal ( tctx , r . out . result , HRES_E_INVALIDARG ,
" spoolss_GetCorePrinterDrivers failed " ) ;
guid = GUID_random ( ) ;
s [ 0 ] = GUID_string2 ( tctx , & guid ) ;
torture_assert ( tctx ,
push_reg_multi_sz ( tctx , & blob , s ) ,
" push_reg_multi_sz failed " ) ;
r . in . core_driver_size = blob . length ;
r . in . core_driver_dependencies = s [ 0 ] ;
r . in . core_printer_driver_count = 1 ;
r . out . core_printer_drivers = talloc_zero_array ( tctx , struct spoolss_CorePrinterDriver , r . in . core_printer_driver_count ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetCorePrinterDrivers_r ( b , tctx , & r ) ,
" spoolss_GetCorePrinterDrivers failed " ) ;
torture_assert_werr_equal ( tctx ,
W_ERROR ( WIN32_FROM_HRESULT ( r . out . result ) ) , WERR_INVALID_ENVIRONMENT ,
" spoolss_GetCorePrinterDrivers failed " ) ;
r . in . architecture = architecture ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetCorePrinterDrivers_r ( b , tctx , & r ) ,
" spoolss_GetCorePrinterDrivers failed " ) ;
torture_assert_werr_equal ( tctx ,
W_ERROR ( WIN32_FROM_HRESULT ( r . out . result ) ) , WERR_NOT_FOUND ,
" spoolss_GetCorePrinterDrivers failed " ) ;
s [ 0 ] = talloc_strdup ( s , guid_str ) ;
torture_assert ( tctx ,
push_reg_multi_sz ( tctx , & blob , s ) ,
" push_reg_multi_sz failed " ) ;
r . in . core_driver_size = blob . length ;
r . in . core_driver_dependencies = s [ 0 ] ;
r . in . core_printer_driver_count = 1 ;
r . out . core_printer_drivers = talloc_zero_array ( tctx , struct spoolss_CorePrinterDriver , r . in . core_printer_driver_count ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetCorePrinterDrivers_r ( b , tctx , & r ) ,
" spoolss_GetCorePrinterDrivers failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" spoolss_GetCorePrinterDrivers failed " ) ;
if ( package_id ) {
* package_id = r . out . core_printer_drivers [ 0 ] . szPackageID ;
}
return true ;
}
static bool test_get_core_printer_drivers ( struct torture_context * tctx ,
void * private_data )
{
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
const char * architectures [ ] = {
SPOOLSS_ARCHITECTURE_NT_X86 ,
SPOOLSS_ARCHITECTURE_x64
} ;
int i ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
for ( i = 0 ; i < ARRAY_SIZE ( architectures ) ; i + + ) {
torture_comment ( tctx , " Testing GetCorePrinterDrivers( \" %s \" , \" %s \" ) \n " ,
architectures [ i ] ,
SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV ) ;
torture_assert ( tctx ,
test_get_core_printer_drivers_arch_guid ( tctx , p ,
architectures [ i ] ,
SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV ,
NULL ) ,
" " ) ;
}
return true ;
}
2016-08-20 01:01:52 +03:00
static bool test_get_printer_driver_package_path ( struct torture_context * tctx ,
void * private_data )
{
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
const char * architectures [ ] = {
SPOOLSS_ARCHITECTURE_NT_X86 ,
SPOOLSS_ARCHITECTURE_x64
} ;
int i ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
for ( i = 0 ; i < ARRAY_SIZE ( architectures ) ; i + + ) {
struct spoolss_GetPrinterDriverPackagePath r ;
uint32_t required = 0 ;
const char * package_id = NULL ;
test_get_core_printer_drivers_arch_guid ( tctx , p ,
architectures [ i ] ,
SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV ,
& package_id ) ,
torture_comment ( tctx , " Testing GetPrinterDriverPackagePath( \" %s \" , \" %s \" ) \n " ,
architectures [ i ] , package_id ) ;
r . in . servername = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
r . in . architecture = " foobar " ;
r . in . language = NULL ;
r . in . package_id = " " ;
r . in . driver_package_cab_size = 0 ;
r . in . driver_package_cab = NULL ;
r . out . required = & required ;
r . out . driver_package_cab = NULL ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetPrinterDriverPackagePath_r ( b , tctx , & r ) ,
" spoolss_GetPrinterDriverPackagePath failed " ) ;
torture_assert_werr_equal ( tctx ,
W_ERROR ( WIN32_FROM_HRESULT ( r . out . result ) ) , WERR_INVALID_ENVIRONMENT ,
" spoolss_GetPrinterDriverPackagePath failed " ) ;
r . in . architecture = architectures [ i ] ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetPrinterDriverPackagePath_r ( b , tctx , & r ) ,
" spoolss_GetPrinterDriverPackagePath failed " ) ;
torture_assert_werr_equal ( tctx ,
W_ERROR ( WIN32_FROM_HRESULT ( r . out . result ) ) , WERR_FILE_NOT_FOUND ,
" spoolss_GetPrinterDriverPackagePath failed " ) ;
r . in . package_id = package_id ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetPrinterDriverPackagePath_r ( b , tctx , & r ) ,
" spoolss_GetPrinterDriverPackagePath failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" spoolss_GetPrinterDriverPackagePath failed " ) ;
r . in . driver_package_cab_size = required ;
r . in . driver_package_cab = talloc_zero_array ( tctx , char , required ) ;
r . out . driver_package_cab = talloc_zero_array ( tctx , char , required ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetPrinterDriverPackagePath_r ( b , tctx , & r ) ,
" spoolss_GetPrinterDriverPackagePath failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" spoolss_GetPrinterDriverPackagePath failed " ) ;
2016-09-08 22:09:42 +03:00
r . in . servername = NULL ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetPrinterDriverPackagePath_r ( b , tctx , & r ) ,
" spoolss_GetPrinterDriverPackagePath failed " ) ;
torture_assert_werr_equal ( tctx ,
W_ERROR ( WIN32_FROM_HRESULT ( r . out . result ) ) , WERR_INSUFFICIENT_BUFFER ,
" spoolss_GetPrinterDriverPackagePath failed " ) ;
r . in . driver_package_cab_size = required ;
r . in . driver_package_cab = talloc_zero_array ( tctx , char , required ) ;
r . out . driver_package_cab = talloc_zero_array ( tctx , char , required ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetPrinterDriverPackagePath_r ( b , tctx , & r ) ,
" spoolss_GetPrinterDriverPackagePath failed " ) ;
torture_assert_hresult_ok ( tctx , r . out . result ,
" spoolss_GetPrinterDriverPackagePath failed " ) ;
2016-08-20 01:01:52 +03:00
}
return true ;
}
2016-09-09 17:00:38 +03:00
static bool test_get_printer_printserverhandle ( struct torture_context * tctx ,
void * private_data )
{
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
uint32_t levels [ ] = { 0 , 1 , 2 , /* 3,*/ 4 , 5 , 6 , 7 , 8 } ;
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
torture_assert ( tctx ,
test_GetPrinter_level_exp ( tctx , b , & ctx - > server_handle ,
levels [ i ] , WERR_INVALID_LEVEL ,
NULL ) ,
" failed to call GetPrinter " ) ;
}
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , & ctx - > server_handle , 3 , NULL ) ,
" failed to call GetPrinter " ) ;
return true ;
}
2016-09-10 12:07:06 +03:00
# define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
static bool test_set_printer_printserverhandle ( struct torture_context * tctx ,
void * private_data )
{
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
union spoolss_PrinterInfo info ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_SetPrinterInfo3 info3 ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
struct security_descriptor * sd ;
struct security_ace * ace ;
struct dom_sid sid ;
int i ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , & ctx - > server_handle , 3 , & info ) ,
" failed to call GetPrinter " ) ;
secdesc_ctr . sd = info . info3 . secdesc ;
secdesc_ctr . sd - > owner_sid = NULL ;
secdesc_ctr . sd - > group_sid = NULL ;
sd = security_descriptor_copy ( tctx , secdesc_ctr . sd ) ;
if ( sd = = NULL ) {
return false ;
}
ace = security_ace_create ( tctx ,
TEST_SID ,
SEC_ACE_TYPE_ACCESS_ALLOWED ,
SEC_STD_REQUIRED ,
SEC_ACE_FLAG_CONTAINER_INHERIT ) ;
torture_assert ( tctx , ace , " failed to create ace " ) ;
torture_assert_ntstatus_ok ( tctx ,
security_descriptor_dacl_add ( sd , ace ) ,
" failed to add ace " ) ;
secdesc_ctr . sd = sd ;
2016-11-11 18:29:20 +03:00
info3 . sec_desc_ptr = 0 ;
2016-09-10 12:07:06 +03:00
info_ctr . level = 3 ;
info_ctr . info . info3 = & info3 ;
ZERO_STRUCT ( devmode_ctr ) ;
torture_assert ( tctx ,
test_SetPrinter ( tctx , b , & ctx - > server_handle , & info_ctr ,
& devmode_ctr , & secdesc_ctr , 0 ) ,
" failed to call SetPrinter " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , & ctx - > server_handle , 3 , & info ) ,
" failed to call GetPrinter " ) ;
for ( i = 0 ; i < info . info3 . secdesc - > dacl - > num_aces ; i + + ) {
if ( security_ace_equal ( & info . info3 . secdesc - > dacl - > aces [ i ] , ace ) ) {
break ;
}
}
if ( i = = info . info3 . secdesc - > dacl - > num_aces ) {
torture_fail ( tctx , " ace not present " ) ;
}
torture_assert ( tctx ,
dom_sid_parse ( TEST_SID , & sid ) ,
" failed to parse sid " ) ;
torture_assert_ntstatus_ok ( tctx ,
security_descriptor_dacl_del ( info . info3 . secdesc , & sid ) ,
" failed to remove ace from sd " ) ;
secdesc_ctr . sd = info . info3 . secdesc ;
torture_assert ( tctx ,
test_SetPrinter ( tctx , b , & ctx - > server_handle , & info_ctr ,
& devmode_ctr , & secdesc_ctr , 0 ) ,
" failed to call SetPrinter " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , & ctx - > server_handle , 3 , & info ) ,
" failed to call GetPrinter " ) ;
for ( i = 0 ; i < info . info3 . secdesc - > dacl - > num_aces ; i + + ) {
if ( security_ace_equal ( & info . info3 . secdesc - > dacl - > aces [ i ] , ace ) ) {
torture_fail ( tctx , " ace still present " ) ;
}
}
return true ;
}
2016-09-09 17:00:38 +03:00
2010-05-19 01:40:43 +04:00
static bool test_PrintServer_Forms_Winreg ( struct torture_context * tctx ,
void * private_data )
{
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
return test_Forms_winreg ( tctx , b , & ctx - > server_handle , true , NULL ) ;
}
static bool test_PrintServer_Forms ( struct torture_context * tctx ,
void * private_data )
{
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
return test_Forms ( tctx , b , & ctx - > server_handle , true , NULL , NULL , NULL ) ;
}
static bool test_PrintServer_EnumForms ( struct torture_context * tctx ,
void * private_data )
{
struct test_spoolss_context * ctx =
talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = ctx - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
return test_EnumForms_all ( tctx , b , & ctx - > server_handle , true ) ;
}
static bool torture_rpc_spoolss_setup_common ( struct torture_context * tctx , struct test_spoolss_context * t )
2003-11-15 08:42:49 +03:00
{
2007-09-03 17:13:25 +04:00
NTSTATUS status ;
2003-11-15 08:42:49 +03:00
2010-05-19 01:40:43 +04:00
status = torture_rpc_connection ( tctx , & t - > spoolss_pipe , & ndr_table_spoolss ) ;
torture_assert_ntstatus_ok ( tctx , status , " Error connecting to server " ) ;
torture_assert ( tctx ,
test_OpenPrinter_server ( tctx , t - > spoolss_pipe , & t - > server_handle ) ,
" failed to open printserver " ) ;
torture_assert ( tctx ,
test_get_environment ( tctx , t - > spoolss_pipe - > binding_handle , & t - > server_handle , & t - > environment ) ,
" failed to get environment " ) ;
return true ;
}
static bool torture_rpc_spoolss_setup ( struct torture_context * tctx , void * * data )
{
struct test_spoolss_context * t ;
* data = t = talloc_zero ( tctx , struct test_spoolss_context ) ;
return torture_rpc_spoolss_setup_common ( tctx , t ) ;
}
static bool torture_rpc_spoolss_teardown_common ( struct torture_context * tctx , struct test_spoolss_context * t )
{
test_ClosePrinter ( tctx , t - > spoolss_pipe - > binding_handle , & t - > server_handle ) ;
return true ;
}
static bool torture_rpc_spoolss_teardown ( struct torture_context * tctx , void * data )
{
struct test_spoolss_context * t = talloc_get_type ( data , struct test_spoolss_context ) ;
bool ret ;
ret = torture_rpc_spoolss_teardown_common ( tctx , t ) ;
talloc_free ( t ) ;
2003-11-22 11:11:32 +03:00
2003-11-15 08:42:49 +03:00
return ret ;
}
2009-07-03 11:56:28 +04:00
2010-06-03 23:39:51 +04:00
static bool torture_rpc_spoolss_printer_setup_common ( struct torture_context * tctx , struct torture_printer_context * t )
2010-05-19 01:40:43 +04:00
{
2010-06-03 23:39:51 +04:00
struct dcerpc_pipe * p ;
struct dcerpc_binding_handle * b ;
const char * server_name_slash ;
const char * driver_name ;
const char * printer_name ;
const char * port_name ;
2010-05-19 01:40:43 +04:00
2010-06-03 23:39:51 +04:00
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection ( tctx , & t - > spoolss_pipe , & ndr_table_spoolss ) ,
" Error connecting to server " ) ;
2010-05-19 01:40:43 +04:00
2010-06-03 23:39:51 +04:00
p = t - > spoolss_pipe ;
b = p - > binding_handle ;
server_name_slash = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2010-04-27 13:30:35 +04:00
2010-04-27 17:56:09 +04:00
t - > driver . info8 . version = SPOOLSS_DRIVER_VERSION_200X ;
t - > driver . info8 . driver_name = TORTURE_DRIVER ;
t - > driver . info8 . driver_path = " pscript5.dll " ;
t - > driver . info8 . data_file = " cups6.ppd " ;
t - > driver . info8 . config_file = " ps5ui.dll " ;
t - > driver . info8 . help_file = " pscript.hlp " ;
t - > driver . info8 . default_datatype = " RAW " ;
t - > driver . info8 . dependent_files = talloc_zero ( t , struct spoolss_StringArray ) ;
t - > driver . info8 . dependent_files - > string = talloc_zero_array ( t , const char * , 8 + 1 ) ;
t - > driver . info8 . dependent_files - > string [ 0 ] = " pscript5.dll " ;
t - > driver . info8 . dependent_files - > string [ 1 ] = " cups6.ppd " ;
t - > driver . info8 . dependent_files - > string [ 2 ] = " ps5ui.dll " ;
t - > driver . info8 . dependent_files - > string [ 3 ] = " pscript.hlp " ;
t - > driver . info8 . dependent_files - > string [ 4 ] = " pscript.ntf " ;
t - > driver . info8 . dependent_files - > string [ 5 ] = " cups6.ini " ;
t - > driver . info8 . dependent_files - > string [ 6 ] = " cupsps6.dll " ;
t - > driver . info8 . dependent_files - > string [ 7 ] = " cupsui6.dll " ;
t - > driver . local . driver_directory = " /usr/share/cups/drivers " ;
2010-04-27 13:30:35 +04:00
t - > info2 . portname = " LPT1: " ;
2010-06-03 23:39:51 +04:00
printer_name = t - > info2 . printername ;
port_name = t - > info2 . portname ;
torture_assert ( tctx ,
fillup_printserver_info ( tctx , p , & t - > driver ) ,
" failed to fillup printserver info " ) ;
t - > driver . info8 . architecture = talloc_strdup ( t , t - > driver . remote . environment ) ;
torture_assert ( tctx ,
compose_local_driver_directory ( tctx , t - > driver . remote . environment ,
t - > driver . local . driver_directory ,
& t - > driver . local . driver_directory ) ,
" failed to compose local driver directory " ) ;
2013-02-01 01:06:20 +04:00
t - > info2 . drivername = " Microsoft XPS Document Writer " ;
2010-12-15 19:44:56 +03:00
if ( test_EnumPrinterDrivers_findone ( tctx , b , server_name_slash , t - > driver . remote . environment , 3 , t - > info2 . drivername , NULL ) ) {
2010-06-03 23:39:51 +04:00
torture_comment ( tctx , " driver '%s' (architecture: %s, version: 3) is present on server \n " ,
t - > info2 . drivername , t - > driver . remote . environment ) ;
t - > have_driver = true ;
goto try_add ;
}
torture_comment ( tctx , " driver '%s' (architecture: %s, version: 3) does not exist on the server \n " ,
t - > info2 . drivername , t - > driver . remote . environment ) ;
2013-02-01 01:06:20 +04:00
t - > info2 . drivername = " Microsoft XPS Document Writer v4 " ;
if ( test_EnumPrinterDrivers_findone ( tctx , b , server_name_slash , t - > driver . remote . environment , 3 , t - > info2 . drivername , NULL ) ) {
torture_comment ( tctx , " driver '%s' (architecture: %s, version: 4) is present on server \n " ,
t - > info2 . drivername , t - > driver . remote . environment ) ;
t - > have_driver = true ;
goto try_add ;
}
2010-06-03 23:39:51 +04:00
torture_comment ( tctx , " trying to upload own driver \n " ) ;
if ( ! directory_exist ( t - > driver . local . driver_directory ) ) {
torture_warning ( tctx , " no local driver is available! " ) ;
t - > have_driver = false ;
goto try_add ;
}
torture_assert ( tctx ,
upload_printer_driver ( tctx , dcerpc_server_name ( p ) , & t - > driver ) ,
" failed to upload printer driver " ) ;
torture_assert ( tctx ,
2010-12-15 19:44:56 +03:00
test_AddPrinterDriver_args_level_3 ( tctx , b , server_name_slash , & t - > driver . info8 , 0 , false , NULL ) ,
2010-06-03 23:39:51 +04:00
" failed to add driver " ) ;
t - > added_driver = true ;
t - > have_driver = true ;
try_add :
driver_name = t - > added_driver ? t - > driver . info8 . driver_name : t - > info2 . drivername ;
if ( t - > wellknown ) {
torture_assert ( tctx ,
test_AddPrinter_wellknown ( tctx , p , printer_name , t - > ex ) ,
" failed to add wellknown printer " ) ;
} else {
torture_assert ( tctx ,
test_AddPrinter_normal ( tctx , p , & t - > handle , printer_name , driver_name , port_name , t - > devmode , t - > ex ) ,
" failed to add printer " ) ;
}
return true ;
}
static bool torture_rpc_spoolss_printer_setup ( struct torture_context * tctx , void * * data )
{
struct torture_printer_context * t ;
* data = t = talloc_zero ( tctx , struct torture_printer_context ) ;
t - > ex = false ;
t - > wellknown = false ;
t - > info2 . printername = TORTURE_PRINTER ;
t - > devmode = NULL ;
return torture_rpc_spoolss_printer_setup_common ( tctx , t ) ;
}
static bool torture_rpc_spoolss_printerex_setup ( struct torture_context * tctx , void * * data )
{
struct torture_printer_context * t ;
* data = t = talloc_zero ( tctx , struct torture_printer_context ) ;
t - > ex = true ;
t - > wellknown = false ;
t - > info2 . printername = TORTURE_PRINTER_EX ;
t - > devmode = NULL ;
return torture_rpc_spoolss_printer_setup_common ( tctx , t ) ;
}
static bool torture_rpc_spoolss_printerwkn_setup ( struct torture_context * tctx , void * * data )
{
struct torture_printer_context * t ;
* data = t = talloc_zero ( tctx , struct torture_printer_context ) ;
t - > ex = false ;
t - > wellknown = true ;
t - > info2 . printername = TORTURE_WELLKNOWN_PRINTER ;
t - > devmode = NULL ;
2010-12-22 13:30:51 +03:00
/* FIXME */
if ( t - > wellknown ) {
torture_skip ( tctx , " skipping AddPrinter level 1 " ) ;
2010-06-03 23:39:51 +04:00
}
return torture_rpc_spoolss_printer_setup_common ( tctx , t ) ;
}
static bool torture_rpc_spoolss_printerexwkn_setup ( struct torture_context * tctx , void * * data )
{
struct torture_printer_context * t ;
* data = t = talloc_zero ( tctx , struct torture_printer_context ) ;
t - > ex = true ;
t - > wellknown = true ;
t - > info2 . printername = TORTURE_WELLKNOWN_PRINTER_EX ;
t - > devmode = NULL ;
2010-12-22 13:30:51 +03:00
/* FIXME */
if ( t - > wellknown ) {
torture_skip ( tctx , " skipping AddPrinterEx level 1 " ) ;
2010-06-03 23:39:51 +04:00
}
return torture_rpc_spoolss_printer_setup_common ( tctx , t ) ;
}
2013-12-04 17:01:52 +04:00
#if 0
2010-06-03 23:39:51 +04:00
static bool torture_rpc_spoolss_printerdm_setup ( struct torture_context * tctx , void * * data )
{
struct torture_printer_context * t ;
* data = t = talloc_zero ( tctx , struct torture_printer_context ) ;
t - > ex = true ;
t - > wellknown = false ;
t - > info2 . printername = TORTURE_PRINTER_EX ;
t - > devmode = torture_devicemode ( t , TORTURE_PRINTER_EX ) ;
return torture_rpc_spoolss_printer_setup_common ( tctx , t ) ;
}
2013-12-04 17:01:52 +04:00
# endif
2010-06-03 23:39:51 +04:00
2017-01-10 20:23:14 +03:00
static bool test_DeletePrinterDriverEx_exp ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server ,
const char * driver ,
const char * environment ,
uint32_t delete_flags ,
uint32_t version ,
WERROR expected_result ) ;
2010-06-03 23:39:51 +04:00
static bool torture_rpc_spoolss_printer_teardown_common ( struct torture_context * tctx , struct torture_printer_context * t )
{
bool found = false ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
2017-06-22 11:25:09 +03:00
struct dcerpc_binding_handle * b = NULL ;
2017-01-10 20:23:14 +03:00
const char * server_name_slash ;
2017-08-08 13:05:24 +03:00
bool ok = true ;
2017-01-10 20:23:14 +03:00
2017-06-22 11:25:09 +03:00
if ( p = = NULL ) {
return true ;
}
b = p - > binding_handle ;
2017-01-10 20:23:14 +03:00
server_name_slash = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2010-06-03 23:39:51 +04:00
2017-08-08 11:40:19 +03:00
if ( ! t - > wellknown ) {
const char * printer_name = t - > info2 . printername ;
2017-08-08 13:05:24 +03:00
torture_assert_goto ( tctx ,
2017-08-08 11:40:19 +03:00
test_DeletePrinter ( tctx , b , & t - > handle ) ,
2017-08-08 13:05:24 +03:00
ok ,
remove_driver ,
2017-08-08 11:40:19 +03:00
" failed to delete printer " ) ;
2017-08-08 13:05:24 +03:00
torture_assert_goto ( tctx ,
2017-08-08 11:40:19 +03:00
test_EnumPrinters_findname ( tctx , b , PRINTER_ENUM_LOCAL , 1 ,
printer_name , & found ) ,
2017-08-08 13:05:24 +03:00
ok ,
remove_driver ,
2017-08-08 11:40:19 +03:00
" failed to enumerate printers " ) ;
2017-08-08 13:05:24 +03:00
torture_assert_goto ( tctx ,
! found ,
ok ,
remove_driver ,
" deleted printer still there " ) ;
2017-08-08 11:40:19 +03:00
}
2017-08-08 13:05:24 +03:00
remove_driver :
2010-06-03 23:39:51 +04:00
if ( t - > added_driver ) {
2017-08-08 13:05:24 +03:00
ok = remove_printer_driver ( tctx ,
dcerpc_server_name ( p ) ,
& t - > driver ) ;
if ( ! ok ) {
torture_warning ( tctx ,
" failed to remove printer driver \n " ) ;
}
2017-01-10 20:23:14 +03:00
2017-08-08 13:05:24 +03:00
ok = test_DeletePrinterDriverEx_exp ( tctx , b ,
server_name_slash ,
t - > driver . info8 . driver_name ,
t - > driver . info8 . architecture ,
DPD_DELETE_ALL_FILES ,
t - > driver . info8 . version ,
WERR_OK ) ;
if ( ! ok ) {
torture_warning ( tctx ,
" failed to delete printer driver via "
" spoolss \n " ) ;
}
2010-06-03 23:39:51 +04:00
}
2017-08-08 13:05:24 +03:00
return ok ;
2010-06-03 23:39:51 +04:00
}
static bool torture_rpc_spoolss_printer_teardown ( struct torture_context * tctx , void * data )
{
struct torture_printer_context * t = talloc_get_type ( data , struct torture_printer_context ) ;
bool ret ;
ret = torture_rpc_spoolss_printer_teardown_common ( tctx , t ) ;
talloc_free ( t ) ;
return ret ;
}
static bool test_print_test ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
torture_assert ( tctx ,
test_PausePrinter ( tctx , b , & t - > handle ) ,
" failed to pause printer " ) ;
torture_assert ( tctx ,
test_DoPrintTest ( tctx , b , & t - > handle ) ,
" failed to do print test " ) ;
torture_assert ( tctx ,
test_ResumePrinter ( tctx , b , & t - > handle ) ,
" failed to resume printer " ) ;
return true ;
}
static bool test_print_test_extended ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
bool ret = true ;
torture_assert ( tctx ,
test_PausePrinter ( tctx , b , & t - > handle ) ,
" failed to pause printer " ) ;
ret = test_DoPrintTest_extended ( tctx , b , & t - > handle ) ;
if ( ret = = false ) {
torture_comment ( tctx , " WARNING! failed to do extended print test \n " ) ;
if ( torture_setting_bool ( tctx , " samba3 " , false ) ) {
torture_comment ( tctx , " non-critical for samba3 \n " ) ;
ret = true ;
tctx - > last_result = TORTURE_SKIP ;
}
}
torture_assert ( tctx ,
test_ResumePrinter ( tctx , b , & t - > handle ) ,
" failed to resume printer " ) ;
return ret ;
}
2013-01-22 01:09:22 +04:00
static bool test_print_test_properties ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
if ( torture_setting_bool ( tctx , " samba3 " , false ) ) {
torture_skip ( tctx , " skip printer job property tests against samba " ) ;
}
torture_assert ( tctx ,
test_PausePrinter ( tctx , b , & t - > handle ) ,
" failed to pause printer " ) ;
torture_assert ( tctx ,
test_DoPrintTest_properties ( tctx , b , & t - > handle ) ,
" failed to test print job properties " ) ;
torture_assert ( tctx ,
test_ResumePrinter ( tctx , b , & t - > handle ) ,
" failed to resume printer " ) ;
return true ;
}
2012-06-21 19:12:23 +04:00
/* use smbd file IO to spool a print job */
static bool test_print_test_smbd ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
NTSTATUS status ;
uint32_t count ;
union spoolss_JobInfo * info = NULL ;
int i ;
struct smb2_tree * tree ;
struct smb2_handle job_h ;
struct smbcli_options options ;
TALLOC_CTX * mem_ctx = talloc_new ( tctx ) ;
2012-06-22 20:49:50 +04:00
/*
* Do not test against the dynamically added printers , printing via
* smbd means that a different spoolss process may handle the
* OpenPrinter request to the one that handled the AddPrinter request .
* This currently leads to an ugly race condition where one process
* sees the new printer and one doesn ' t .
*/
const char * share = TORTURE_PRINTER_STATIC1 ;
2012-06-21 19:12:23 +04:00
torture_comment ( tctx , " Testing smbd job spooling \n " ) ;
lpcfg_smbcli_options ( tctx - > lp_ctx , & options ) ;
2013-09-25 08:21:38 +04:00
status = smb2_connect ( mem_ctx ,
torture_setting_string ( tctx , " host " , NULL ) ,
lpcfg_smb_ports ( tctx - > lp_ctx ) ,
share ,
lpcfg_resolve_context ( tctx - > lp_ctx ) ,
2017-05-10 02:28:53 +03:00
popt_get_cmdline_credentials ( ) ,
2013-09-25 08:21:38 +04:00
& tree ,
tctx - > ev ,
& options ,
lpcfg_socket_options ( tctx - > lp_ctx ) ,
lpcfg_gensec_settings ( tctx , tctx - > lp_ctx ) ) ;
2012-06-21 19:12:23 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to connect to SMB2 printer %s - %s \n " ,
share , nt_errstr ( status ) ) ;
return false ;
}
status = torture_smb2_testfile ( tree , " smbd_spooler_job " , & job_h ) ;
torture_assert_ntstatus_ok ( tctx , status , " smbd spool job create " ) ;
status = smb2_util_write ( tree , job_h , " exciting print job data " , 0 ,
sizeof ( " exciting print job data " ) ) ;
torture_assert_ntstatus_ok ( tctx , status , " smbd spool job write " ) ;
/* check back end spoolss job was created */
torture_assert ( tctx ,
2014-10-27 22:13:57 +03:00
test_EnumJobs_args ( tctx , b , & t - > handle , 1 , WERR_OK ,
& count , & info ) ,
2012-06-21 19:12:23 +04:00
" EnumJobs level 1 failed " ) ;
for ( i = 0 ; i < count ; i + + ) {
if ( ! strcmp ( info [ i ] . info1 . document_name , " smbd_spooler_job " ) ) {
break ;
}
}
torture_assert ( tctx , ( i ! = count ) , " smbd_spooler_job not found " ) ;
status = smb2_util_close ( tree , job_h ) ;
torture_assert_ntstatus_ok ( tctx , status , " smbd spool job close " ) ;
/* disconnect from printer share */
talloc_free ( mem_ctx ) ;
return true ;
}
2014-05-21 23:55:59 +04:00
static bool test_print_test_purge ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data ,
struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
uint32_t num_jobs = 8 ;
uint32_t * job_ids ;
int i ;
bool ret = true ;
uint32_t count ;
union spoolss_JobInfo * info ;
torture_assert ( tctx ,
test_PausePrinter ( tctx , b , & t - > handle ) ,
" failed to pause printer " ) ;
job_ids = talloc_zero_array ( tctx , uint32_t , num_jobs ) ;
for ( i = 0 ; i < num_jobs ; i + + ) {
ret = test_DoPrintTest_add_one_job ( tctx , b , & t - > handle ,
" TorturePrintJob " ,
& job_ids [ i ] ) ;
torture_assert ( tctx , ret , " failed to add print job " ) ;
}
torture_assert ( tctx ,
2014-10-27 22:13:57 +03:00
test_EnumJobs_args ( tctx , b , & t - > handle , 1 , WERR_OK ,
& count , & info ) ,
2014-05-21 23:55:59 +04:00
" EnumJobs level 1 failed " ) ;
torture_assert_int_equal ( tctx , count , num_jobs ,
" unexpected number of jobs in queue " ) ;
torture_assert ( tctx ,
test_printer_purge ( tctx , b , & t - > handle ) ,
" failed to purge printer " ) ;
torture_assert ( tctx ,
2014-10-27 22:13:57 +03:00
test_EnumJobs_args ( tctx , b , & t - > handle , 1 , WERR_OK ,
& count , & info ) ,
2014-05-21 23:55:59 +04:00
" EnumJobs level 1 failed " ) ;
torture_assert_int_equal ( tctx , count , 0 ,
" unexpected number of jobs in queue " ) ;
torture_assert ( tctx ,
test_ResumePrinter ( tctx , b , & t - > handle ) ,
" failed to resume printer " ) ;
return true ;
}
2010-06-03 23:39:51 +04:00
static bool test_printer_sd ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
torture_assert ( tctx ,
test_PrinterInfo_SD ( tctx , b , & t - > handle ) ,
" failed to test security descriptors " ) ;
return true ;
}
static bool test_printer_dm ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
torture_assert ( tctx ,
test_PrinterInfo_DevMode ( tctx , p , & t - > handle , t - > info2 . printername , t - > devmode ) ,
" failed to test devicemodes " ) ;
return true ;
}
static bool test_printer_info_winreg ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
torture_assert ( tctx ,
test_PrinterInfo_winreg ( tctx , p , & t - > handle , t - > info2 . printername ) ,
" failed to test printer info winreg " ) ;
return true ;
}
2016-09-13 10:28:03 +03:00
static bool test_printserver_info_winreg ( struct torture_context * tctx ,
void * private_data )
{
struct test_spoolss_context * t =
( struct test_spoolss_context * ) talloc_get_type_abort ( private_data , struct test_spoolss_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
torture_assert ( tctx ,
test_PrintserverInfo_winreg ( tctx , p , & t - > server_handle ) ,
" failed to test printserver info winreg " ) ;
return true ;
}
2010-06-03 23:39:51 +04:00
static bool test_printer_change_id ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
torture_assert ( tctx ,
test_ChangeID ( tctx , p , & t - > handle ) ,
" failed to test change id " ) ;
return true ;
}
static bool test_printer_keys ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
torture_assert ( tctx ,
test_printer_all_keys ( tctx , b , & t - > handle ) ,
" failed to test printer keys " ) ;
return true ;
}
static bool test_printer_data_consistency ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
torture_assert ( tctx ,
test_EnumPrinterData_consistency ( tctx , p , & t - > handle ) ,
" failed to test printer data consistency " ) ;
return true ;
}
2010-06-22 16:55:20 +04:00
static bool test_printer_data_keys ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
torture_assert ( tctx ,
test_SetPrinterDataEx_keys ( tctx , p , & t - > handle ) ,
" failed to test printer data keys " ) ;
return true ;
}
2010-06-22 17:45:45 +04:00
static bool test_printer_data_values ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
torture_assert ( tctx ,
test_SetPrinterDataEx_values ( tctx , p , & t - > handle ) ,
" failed to test printer data values " ) ;
return true ;
}
2010-06-03 23:39:51 +04:00
static bool test_printer_data_set ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
torture_assert ( tctx ,
test_SetPrinterDataEx_matrix ( tctx , p , & t - > handle , t - > info2 . printername , NULL , NULL ) ,
" failed to test printer data set " ) ;
return true ;
}
static bool test_printer_data_winreg ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
torture_assert ( tctx ,
test_PrinterData_winreg ( tctx , p , & t - > handle , t - > info2 . printername ) ,
" failed to test printer data winreg " ) ;
return true ;
}
static bool test_printer_data_dsspooler ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
torture_assert ( tctx ,
test_PrinterData_DsSpooler ( tctx , p , & t - > handle , t - > info2 . printername ) ,
" failed to test printer data winreg dsspooler " ) ;
return true ;
}
2013-01-23 13:33:21 +04:00
static bool test_printer_ic ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
talloc_get_type_abort ( private_data ,
struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct policy_handle gdi_handle ;
if ( torture_setting_bool ( tctx , " samba3 " , false ) ) {
torture_skip ( tctx , " skip printer information context tests against samba " ) ;
}
{
struct spoolss_CreatePrinterIC r ;
struct spoolss_DevmodeContainer devmode_ctr ;
ZERO_STRUCT ( devmode_ctr ) ;
r . in . handle = & t - > handle ;
r . in . devmode_ctr = & devmode_ctr ;
r . out . gdi_handle = & gdi_handle ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_CreatePrinterIC_r ( b , tctx , & r ) ,
" CreatePrinterIC failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" CreatePrinterIC failed " ) ;
}
{
struct spoolss_PlayGDIScriptOnPrinterIC r ;
DATA_BLOB in , out ;
int i ;
uint32_t num_fonts = 0 ;
in = data_blob_string_const ( " " ) ;
r . in . gdi_handle = & gdi_handle ;
r . in . pIn = in . data ;
r . in . cIn = in . length ;
r . in . ul = 0 ;
for ( i = 0 ; i < 4 ; i + + ) {
out = data_blob_talloc_zero ( tctx , i ) ;
r . in . cOut = out . length ;
r . out . pOut = out . data ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_PlayGDIScriptOnPrinterIC_r ( b , tctx , & r ) ,
" PlayGDIScriptOnPrinterIC failed " ) ;
2015-12-03 17:24:20 +03:00
torture_assert_werr_equal ( tctx , r . out . result , WERR_NOT_ENOUGH_MEMORY ,
2013-01-23 13:33:21 +04:00
" PlayGDIScriptOnPrinterIC failed " ) ;
}
out = data_blob_talloc_zero ( tctx , 4 ) ;
r . in . cOut = out . length ;
r . out . pOut = out . data ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_PlayGDIScriptOnPrinterIC_r ( b , tctx , & r ) ,
" PlayGDIScriptOnPrinterIC failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , WERR_OK ,
" PlayGDIScriptOnPrinterIC failed " ) ;
/* now we should have the required length, so retry with a
* buffer which is large enough to carry all font ids */
num_fonts = IVAL ( r . out . pOut , 0 ) ;
torture_comment ( tctx , " PlayGDIScriptOnPrinterIC gave font count of %d \n " , num_fonts ) ;
out = data_blob_talloc_zero ( tctx ,
num_fonts * sizeof ( struct UNIVERSAL_FONT_ID ) + 4 ) ;
r . in . cOut = out . length ;
r . out . pOut = out . data ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_PlayGDIScriptOnPrinterIC_r ( b , tctx , & r ) ,
" PlayGDIScriptOnPrinterIC failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , WERR_OK ,
" PlayGDIScriptOnPrinterIC failed " ) ;
}
{
struct spoolss_DeletePrinterIC r ;
r . in . gdi_handle = & gdi_handle ;
r . out . gdi_handle = & gdi_handle ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_DeletePrinterIC_r ( b , tctx , & r ) ,
" DeletePrinterIC failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" DeletePrinterIC failed " ) ;
}
return true ;
}
2013-01-31 23:44:54 +04:00
static bool test_printer_bidi ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
talloc_get_type_abort ( private_data ,
struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
2016-08-29 15:05:34 +03:00
struct spoolss_SendRecvBidiData r ;
2013-01-31 23:44:54 +04:00
struct RPC_BIDI_REQUEST_CONTAINER bidi_req ;
struct RPC_BIDI_RESPONSE_CONTAINER * bidi_rep = NULL ;
if ( torture_setting_bool ( tctx , " samba3 " , false ) ) {
torture_skip ( tctx , " skip printer bidirectional tests against samba " ) ;
}
ZERO_STRUCT ( bidi_req ) ;
r . in . hPrinter = t - > handle ;
r . in . pAction = " foobar " ;
r . in . pReqData = & bidi_req ;
r . out . ppRespData = & bidi_rep ;
torture_assert_ntstatus_ok ( tctx ,
2016-08-29 15:05:34 +03:00
dcerpc_spoolss_SendRecvBidiData_r ( b , tctx , & r ) ,
" SendRecvBidiData failed " ) ;
2013-01-31 23:44:54 +04:00
torture_assert_werr_equal ( tctx , r . out . result , WERR_NOT_SUPPORTED ,
2016-08-29 15:05:34 +03:00
" SendRecvBidiData failed " ) ;
2013-01-31 23:44:54 +04:00
if ( ! ( t - > info2 . attributes & PRINTER_ATTRIBUTE_ENABLE_BIDI ) ) {
torture_skip ( tctx , " skipping further tests as printer is not BIDI enabled " ) ;
}
r . in . pAction = BIDI_ACTION_ENUM_SCHEMA ;
torture_assert_ntstatus_ok ( tctx ,
2016-08-29 15:05:34 +03:00
dcerpc_spoolss_SendRecvBidiData_r ( b , tctx , & r ) ,
" SendRecvBidiData failed " ) ;
2013-01-31 23:44:54 +04:00
torture_assert_werr_ok ( tctx , r . out . result ,
2016-08-29 15:05:34 +03:00
" SendRecvBidiData failed " ) ;
2013-01-31 23:44:54 +04:00
return true ;
}
2013-01-23 13:33:21 +04:00
2013-05-29 12:43:34 +04:00
static bool test_printer_set_publish ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle )
{
union spoolss_PrinterInfo info ;
struct spoolss_SetPrinterInfo7 info7 ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
info7 . guid = " " ;
info7 . action = DSPRINT_PUBLISH ;
ZERO_STRUCT ( info_ctr ) ;
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
info_ctr . level = 7 ;
info_ctr . info . info7 = & info7 ;
torture_assert ( tctx ,
test_SetPrinter ( tctx , b , handle , & info_ctr ,
& devmode_ctr , & secdesc_ctr , 0 ) , " " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , handle , 2 , & info ) ,
" " ) ;
torture_assert ( tctx ,
( info . info2 . attributes & PRINTER_ATTRIBUTE_PUBLISHED ) ,
" info2 publish flag not set " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , handle , 7 , & info ) ,
" " ) ;
2013-05-29 12:43:35 +04:00
if ( info . info7 . action & DSPRINT_PENDING ) {
torture_comment ( tctx , " publish is pending \n " ) ;
torture_assert_int_equal ( tctx ,
info . info7 . action ,
( DSPRINT_PENDING | DSPRINT_PUBLISH ) ,
" info7 publish flag not set " ) ;
} else {
struct GUID guid ;
2017-10-05 20:22:29 +03:00
char * ref_guid ;
2013-05-29 12:43:35 +04:00
torture_assert_int_equal ( tctx ,
info . info7 . action ,
DSPRINT_PUBLISH ,
" info7 publish flag not set " ) ;
2017-10-05 20:22:29 +03:00
/* GUID_from_string is able to parse both plain and
* curly - braced guids */
2013-05-29 12:43:35 +04:00
torture_assert_ntstatus_ok ( tctx ,
GUID_from_string ( info . info7 . guid ,
& guid ) ,
" invalid published printer GUID " ) ;
2017-10-05 20:22:29 +03:00
/* Build reference GUID string */
ref_guid = GUID_string2 ( tctx , & guid ) ;
torture_assert_not_null ( tctx , ref_guid , " ENOMEM " ) ;
ref_guid = talloc_strdup_upper ( tctx , ref_guid ) ;
torture_assert_not_null ( tctx , ref_guid , " ENOMEM " ) ;
torture_assert_str_equal ( tctx , info . info7 . guid , ref_guid ,
" invalid GUID format " ) ;
2013-05-29 12:43:35 +04:00
}
2013-05-29 12:43:34 +04:00
return true ;
}
static bool test_printer_set_unpublish ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
struct policy_handle * handle )
{
union spoolss_PrinterInfo info ;
struct spoolss_SetPrinterInfo7 info7 ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
info7 . action = DSPRINT_UNPUBLISH ;
info7 . guid = " " ;
ZERO_STRUCT ( info_ctr ) ;
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
info_ctr . level = 7 ;
info_ctr . info . info7 = & info7 ;
torture_assert ( tctx ,
test_SetPrinter ( tctx , b , handle , & info_ctr ,
& devmode_ctr , & secdesc_ctr , 0 ) , " " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , handle , 2 , & info ) ,
" " ) ;
torture_assert ( tctx ,
! ( info . info2 . attributes & PRINTER_ATTRIBUTE_PUBLISHED ) ,
" info2 publish flag still set " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , handle , 7 , & info ) ,
" " ) ;
2013-05-29 12:43:35 +04:00
if ( info . info7 . action & DSPRINT_PENDING ) {
struct GUID guid ;
torture_comment ( tctx , " unpublish is pending \n " ) ;
torture_assert_int_equal ( tctx ,
info . info7 . action ,
( DSPRINT_PENDING | DSPRINT_UNPUBLISH ) ,
" info7 unpublish flag not set " ) ;
torture_assert_ntstatus_ok ( tctx ,
GUID_from_string ( info . info7 . guid ,
& guid ) ,
" invalid printer GUID " ) ;
} else {
torture_assert_int_equal ( tctx ,
info . info7 . action , DSPRINT_UNPUBLISH ,
" info7 unpublish flag not set " ) ;
}
2013-05-29 12:43:34 +04:00
return true ;
}
static bool test_printer_publish_toggle ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
talloc_get_type_abort ( private_data ,
struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct policy_handle * handle = & t - > handle ;
union spoolss_PrinterInfo info7 ;
union spoolss_PrinterInfo info2 ;
/* check publish status via level 7 and level 2 */
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 7 , & info7 ) ,
" " ) ;
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info2 ) ,
" " ) ;
if ( info2 . info2 . attributes & PRINTER_ATTRIBUTE_PUBLISHED ) {
torture_assert_int_equal ( tctx ,
info7 . info7 . action , DSPRINT_PUBLISH ,
" info7 publish flag not set " ) ;
torture_assert ( tctx , test_printer_set_unpublish ( tctx , b , handle ) , " " ) ;
torture_assert ( tctx , test_printer_set_publish ( tctx , b , handle ) , " " ) ;
} else {
torture_assert_int_equal ( tctx ,
info7 . info7 . action , DSPRINT_UNPUBLISH ,
" info7 unpublish flag not set " ) ;
torture_assert ( tctx , test_printer_set_publish ( tctx , b , handle ) , " " ) ;
torture_assert ( tctx , test_printer_set_unpublish ( tctx , b , handle ) , " " ) ;
}
return true ;
}
2010-06-03 23:39:51 +04:00
static bool test_driver_info_winreg ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
const char * driver_name = t - > added_driver ? t - > driver . info8 . driver_name : t - > info2 . drivername ;
if ( ! t - > have_driver ) {
torture_skip ( tctx , " skipping driver info winreg test as we don't have a driver " ) ;
}
torture_assert ( tctx ,
2010-12-16 17:59:19 +03:00
test_DriverInfo_winreg ( tctx , p , & t - > handle , t - > info2 . printername , driver_name , t - > driver . remote . environment , 3 ) ,
2010-06-03 23:39:51 +04:00
" failed to test driver info winreg " ) ;
return true ;
}
2014-10-27 22:13:58 +03:00
static bool test_print_job_enum ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
bool ret = true ;
uint32_t num_jobs = 8 ;
uint32_t * job_ids ;
int i ;
union spoolss_JobInfo * info = NULL ;
uint32_t count ;
torture_assert ( tctx ,
test_PausePrinter ( tctx , b , & t - > handle ) ,
" failed to pause printer " ) ;
2014-10-29 13:54:19 +03:00
/* purge in case of any jobs from previous tests */
torture_assert ( tctx ,
test_printer_purge ( tctx , b , & t - > handle ) ,
" failed to purge printer " ) ;
2014-10-27 22:13:58 +03:00
/* enum before jobs, valid level */
torture_assert ( tctx ,
test_EnumJobs_args ( tctx , b , & t - > handle , 1 , WERR_OK ,
& count , & info ) ,
" EnumJobs with valid level " ) ;
torture_assert_int_equal ( tctx , count , 0 , " EnumJobs count " ) ;
torture_assert ( tctx ,
test_EnumJobs_args ( tctx , b , & t - > handle , 2 , WERR_OK ,
& count , & info ) ,
" EnumJobs with valid level " ) ;
torture_assert_int_equal ( tctx , count , 0 , " EnumJobs count " ) ;
/* enum before jobs, invalid level - expect failure */
torture_assert ( tctx ,
test_EnumJobs_args ( tctx , b , & t - > handle , 100 ,
WERR_INVALID_LEVEL ,
& count , & info ) ,
" EnumJobs with invalid level " ) ;
job_ids = talloc_zero_array ( tctx , uint32_t , num_jobs ) ;
for ( i = 0 ; i < num_jobs ; i + + ) {
ret = test_DoPrintTest_add_one_job ( tctx , b , & t - > handle ,
" TorturePrintJob " ,
& job_ids [ i ] ) ;
torture_assert ( tctx , ret , " failed to add print job " ) ;
}
/* enum after jobs, valid level */
torture_assert ( tctx ,
test_EnumJobs_args ( tctx , b , & t - > handle , 1 , WERR_OK ,
& count , & info ) ,
" EnumJobs with valid level " ) ;
torture_assert_int_equal ( tctx , count , num_jobs , " EnumJobs count " ) ;
torture_assert ( tctx ,
test_EnumJobs_args ( tctx , b , & t - > handle , 2 , WERR_OK ,
& count , & info ) ,
" EnumJobs with valid level " ) ;
torture_assert_int_equal ( tctx , count , num_jobs , " EnumJobs count " ) ;
/* enum after jobs, invalid level - expect failure */
torture_assert ( tctx ,
test_EnumJobs_args ( tctx , b , & t - > handle , 100 ,
WERR_INVALID_LEVEL ,
& count , & info ) ,
" EnumJobs with invalid level " ) ;
2014-10-29 13:54:19 +03:00
for ( i = 0 ; i < num_jobs ; i + + ) {
test_SetJob ( tctx , b , & t - > handle , job_ids [ i ] , NULL ,
SPOOLSS_JOB_CONTROL_DELETE ) ;
}
2014-10-27 22:13:58 +03:00
torture_assert ( tctx ,
test_ResumePrinter ( tctx , b , & t - > handle ) ,
" failed to resume printer " ) ;
return true ;
}
2016-09-06 13:11:26 +03:00
static bool test_printer_log_jobinfo ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct spoolss_BranchOfficeJobDataContainer info ;
int i ;
struct spoolss_LogJobInfoForBranchOffice r ;
torture_comment ( tctx , " Testing LogJobInfoForBranchOffice \n " ) ;
info . cJobDataEntries = 0 ;
info . JobData = NULL ;
r . in . hPrinter = & t - > handle ;
r . in . pBranchOfficeJobDataContainer = & info ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_LogJobInfoForBranchOffice_r ( b , tctx , & r ) ,
" LogJobInfoForBranchOffice failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , WERR_INVALID_PARAMETER ,
" LogJobInfoForBranchOffice failed " ) ;
info . cJobDataEntries = 1 ;
info . JobData = talloc_zero_array ( tctx , struct spoolss_BranchOfficeJobData , info . cJobDataEntries ) ;
info . JobData [ 0 ] . eEventType = kLogOfflineFileFull ;
info . JobData [ 0 ] . JobId = 42 ;
info . JobData [ 0 ] . JobInfo . LogOfflineFileFull . pMachineName = talloc_strdup ( tctx , " mthelena " ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_LogJobInfoForBranchOffice_r ( b , tctx , & r ) ,
" LogJobInfoForBranchOffice failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , WERR_OK ,
" LogJobInfoForBranchOffice failed " ) ;
info . cJobDataEntries = 42 ;
info . JobData = talloc_zero_array ( tctx , struct spoolss_BranchOfficeJobData , info . cJobDataEntries ) ;
for ( i = 0 ; i < info . cJobDataEntries ; i + + ) {
info . JobData [ i ] . eEventType = kLogOfflineFileFull ;
info . JobData [ i ] . JobId = i ;
info . JobData [ i ] . JobInfo . LogOfflineFileFull . pMachineName = talloc_asprintf ( tctx , " torture_%d " , i ) ;
}
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_LogJobInfoForBranchOffice_r ( b , tctx , & r ) ,
" LogJobInfoForBranchOffice failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , WERR_OK ,
" LogJobInfoForBranchOffice failed " ) ;
return true ;
}
2016-11-18 13:59:05 +03:00
static bool test_printer_os_versions ( struct torture_context * tctx ,
void * private_data )
{
struct torture_printer_context * t =
( struct torture_printer_context * ) talloc_get_type_abort ( private_data , struct torture_printer_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
union spoolss_PrinterInfo info ;
DATA_BLOB blob ;
uint8_t * data ;
uint32_t length ;
struct spoolss_OSVersion osversion ;
uint8_t os_major , os_minor ;
uint16_t os_build ;
struct policy_handle server_handle ;
torture_comment ( tctx , " Testing OSVersion vs. PRINTER_INFO_STRESS \n " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , & t - > handle , 0 , & info ) ,
" failed to get level 0 printer info " ) ;
torture_assert ( tctx ,
test_OpenPrinter_server ( tctx , p , & server_handle ) ,
" failed to open printserver " ) ;
torture_assert ( tctx ,
test_GetPrinterData_checktype ( tctx , b , & server_handle , " OSVersion " ,
NULL , NULL , & data , & length ) ,
" failed to fetch OSVersion printer data " ) ;
test_ClosePrinter ( tctx , b , & server_handle ) ;
blob = data_blob_const ( data , length ) ;
torture_assert_ndr_success ( tctx ,
ndr_pull_struct_blob ( & blob , tctx , & osversion ,
( ndr_pull_flags_fn_t ) ndr_pull_spoolss_OSVersion ) ,
" failed to pull OSVersion " ) ;
os_major = CVAL ( & info . info0 . version , 0 ) ;
os_minor = CVAL ( & info . info0 . version , 1 ) ;
os_build = SVAL ( & info . info0 . version , 2 ) ;
torture_assert_int_equal ( tctx , os_major , osversion . major , " major " ) ;
torture_assert_int_equal ( tctx , os_minor , osversion . minor , " minor " ) ;
torture_assert_int_equal ( tctx , os_build , osversion . build , " build " ) ;
return true ;
}
2010-06-03 23:39:51 +04:00
void torture_tcase_printer ( struct torture_tcase * tcase )
{
2010-10-03 00:13:44 +04:00
torture_tcase_add_simple_test ( tcase , " openprinter " , test_openprinter_wrap ) ;
2010-06-03 23:39:51 +04:00
torture_tcase_add_simple_test ( tcase , " csetprinter " , test_csetprinter ) ;
torture_tcase_add_simple_test ( tcase , " print_test " , test_print_test ) ;
torture_tcase_add_simple_test ( tcase , " print_test_extended " , test_print_test_extended ) ;
2012-06-21 19:12:23 +04:00
torture_tcase_add_simple_test ( tcase , " print_test_smbd " , test_print_test_smbd ) ;
2013-01-22 01:09:22 +04:00
torture_tcase_add_simple_test ( tcase , " print_test_properties " , test_print_test_properties ) ;
2014-05-21 23:55:59 +04:00
torture_tcase_add_simple_test ( tcase , " print_test_purge " , test_print_test_purge ) ;
2010-06-03 23:39:51 +04:00
torture_tcase_add_simple_test ( tcase , " printer_info " , test_printer_info ) ;
torture_tcase_add_simple_test ( tcase , " sd " , test_printer_sd ) ;
torture_tcase_add_simple_test ( tcase , " dm " , test_printer_dm ) ;
torture_tcase_add_simple_test ( tcase , " printer_info_winreg " , test_printer_info_winreg ) ;
torture_tcase_add_simple_test ( tcase , " change_id " , test_printer_change_id ) ;
torture_tcase_add_simple_test ( tcase , " keys " , test_printer_keys ) ;
torture_tcase_add_simple_test ( tcase , " printerdata_consistency " , test_printer_data_consistency ) ;
2010-06-22 16:55:20 +04:00
torture_tcase_add_simple_test ( tcase , " printerdata_keys " , test_printer_data_keys ) ;
2010-06-22 17:45:45 +04:00
torture_tcase_add_simple_test ( tcase , " printerdata_values " , test_printer_data_values ) ;
2010-06-03 23:39:51 +04:00
torture_tcase_add_simple_test ( tcase , " printerdata_set " , test_printer_data_set ) ;
torture_tcase_add_simple_test ( tcase , " printerdata_winreg " , test_printer_data_winreg ) ;
torture_tcase_add_simple_test ( tcase , " printerdata_dsspooler " , test_printer_data_dsspooler ) ;
torture_tcase_add_simple_test ( tcase , " driver_info_winreg " , test_driver_info_winreg ) ;
torture_tcase_add_simple_test ( tcase , " printer_rename " , test_printer_rename ) ;
2013-01-23 13:33:21 +04:00
torture_tcase_add_simple_test ( tcase , " printer_ic " , test_printer_ic ) ;
2013-01-31 23:44:54 +04:00
torture_tcase_add_simple_test ( tcase , " bidi " , test_printer_bidi ) ;
2013-05-29 12:43:34 +04:00
torture_tcase_add_simple_test ( tcase , " publish_toggle " ,
test_printer_publish_toggle ) ;
2014-10-27 22:13:58 +03:00
torture_tcase_add_simple_test ( tcase , " print_job_enum " , test_print_job_enum ) ;
2016-09-06 13:11:26 +03:00
torture_tcase_add_simple_test ( tcase , " log_jobinfo " , test_printer_log_jobinfo ) ;
2016-11-18 13:59:05 +03:00
torture_tcase_add_simple_test ( tcase , " os_versions " , test_printer_os_versions ) ;
2010-06-03 23:39:51 +04:00
}
struct torture_suite * torture_rpc_spoolss_printer ( TALLOC_CTX * mem_ctx )
{
2010-12-11 05:26:31 +03:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " printer " ) ;
2010-06-03 23:39:51 +04:00
struct torture_tcase * tcase ;
tcase = torture_suite_add_tcase ( suite , " addprinter " ) ;
torture_tcase_set_fixture ( tcase ,
torture_rpc_spoolss_printer_setup ,
torture_rpc_spoolss_printer_teardown ) ;
torture_tcase_printer ( tcase ) ;
tcase = torture_suite_add_tcase ( suite , " addprinterex " ) ;
torture_tcase_set_fixture ( tcase ,
torture_rpc_spoolss_printerex_setup ,
torture_rpc_spoolss_printer_teardown ) ;
torture_tcase_printer ( tcase ) ;
tcase = torture_suite_add_tcase ( suite , " addprinterwkn " ) ;
torture_tcase_set_fixture ( tcase ,
torture_rpc_spoolss_printerwkn_setup ,
torture_rpc_spoolss_printer_teardown ) ;
tcase = torture_suite_add_tcase ( suite , " addprinterexwkn " ) ;
torture_tcase_set_fixture ( tcase ,
torture_rpc_spoolss_printerexwkn_setup ,
torture_rpc_spoolss_printer_teardown ) ;
#if 0
/* test is not correct */
tcase = torture_suite_add_tcase ( suite , " addprinterdm " ) ;
torture_tcase_set_fixture ( tcase ,
torture_rpc_spoolss_printerdm_setup ,
torture_rpc_spoolss_printer_teardown ) ;
torture_tcase_printer ( tcase ) ;
# endif
return suite ;
}
struct torture_suite * torture_rpc_spoolss ( TALLOC_CTX * mem_ctx )
{
2010-12-11 05:26:31 +03:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " spoolss " ) ;
struct torture_tcase * tcase = torture_suite_add_tcase ( suite , " printserver " ) ;
2010-06-03 23:39:51 +04:00
torture_tcase_set_fixture ( tcase ,
torture_rpc_spoolss_setup ,
torture_rpc_spoolss_teardown ) ;
torture_tcase_add_simple_test ( tcase , " openprinter_badnamelist " , test_OpenPrinter_badname_list ) ;
torture_tcase_add_simple_test ( tcase , " printer_data_list " , test_GetPrinterData_list ) ;
torture_tcase_add_simple_test ( tcase , " enum_forms " , test_PrintServer_EnumForms ) ;
torture_tcase_add_simple_test ( tcase , " forms " , test_PrintServer_Forms ) ;
torture_tcase_add_simple_test ( tcase , " forms_winreg " , test_PrintServer_Forms_Winreg ) ;
torture_tcase_add_simple_test ( tcase , " enum_ports " , test_EnumPorts ) ;
torture_tcase_add_simple_test ( tcase , " add_port " , test_AddPort ) ;
torture_tcase_add_simple_test ( tcase , " get_printer_driver_directory " , test_GetPrinterDriverDirectory ) ;
torture_tcase_add_simple_test ( tcase , " get_print_processor_directory " , test_GetPrintProcessorDirectory ) ;
torture_tcase_add_simple_test ( tcase , " enum_printer_drivers " , test_EnumPrinterDrivers ) ;
torture_tcase_add_simple_test ( tcase , " enum_monitors " , test_EnumMonitors ) ;
torture_tcase_add_simple_test ( tcase , " enum_print_processors " , test_EnumPrintProcessors ) ;
torture_tcase_add_simple_test ( tcase , " print_processors_winreg " , test_print_processors_winreg ) ;
2013-02-01 17:07:50 +04:00
torture_tcase_add_simple_test ( tcase , " add_processor " , test_add_print_processor ) ;
2016-08-26 02:05:20 +03:00
torture_tcase_add_simple_test ( tcase , " enum_printprocdata " , test_EnumPrintProcessorDataTypes ) ;
2010-06-03 23:39:51 +04:00
torture_tcase_add_simple_test ( tcase , " enum_printers " , test_EnumPrinters ) ;
torture_tcase_add_simple_test ( tcase , " enum_ports_old " , test_EnumPorts_old ) ;
torture_tcase_add_simple_test ( tcase , " enum_printers_old " , test_EnumPrinters_old ) ;
2010-09-29 06:49:57 +04:00
torture_tcase_add_simple_test ( tcase , " enum_printers_servername " , test_EnumPrinters_servername ) ;
2010-06-03 23:39:51 +04:00
torture_tcase_add_simple_test ( tcase , " enum_printer_drivers_old " , test_EnumPrinterDrivers_old ) ;
torture_tcase_add_simple_test ( tcase , " architecture_buffer " , test_architecture_buffer ) ;
2016-08-20 00:27:19 +03:00
torture_tcase_add_simple_test ( tcase , " get_core_printer_drivers " , test_get_core_printer_drivers ) ;
2016-08-20 01:01:52 +03:00
torture_tcase_add_simple_test ( tcase , " get_printer_driver_package_path " , test_get_printer_driver_package_path ) ;
2016-09-09 17:00:38 +03:00
torture_tcase_add_simple_test ( tcase , " get_printer " , test_get_printer_printserverhandle ) ;
2016-09-10 12:07:06 +03:00
torture_tcase_add_simple_test ( tcase , " set_printer " , test_set_printer_printserverhandle ) ;
2016-09-13 10:28:03 +03:00
torture_tcase_add_simple_test ( tcase , " printserver_info_winreg " , test_printserver_info_winreg ) ;
2009-07-03 11:56:28 +04:00
2010-06-03 23:39:51 +04:00
torture_suite_add_suite ( suite , torture_rpc_spoolss_printer ( suite ) ) ;
2010-04-28 19:00:53 +04:00
2009-07-03 11:56:28 +04:00
return suite ;
}
2009-07-02 23:49:15 +04:00
static bool test_GetPrinterDriverDirectory_getdir ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server ,
const char * environment ,
const char * * dir_p )
{
struct spoolss_GetPrinterDriverDirectory r ;
uint32_t needed ;
r . in . server = server ;
r . in . environment = environment ;
r . in . level = 1 ;
r . in . buffer = NULL ;
r . in . offered = 0 ;
r . out . needed = & needed ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetPrinterDriverDirectory_r ( b , tctx , & r ) ,
" failed to query driver directory " ) ;
if ( W_ERROR_EQUAL ( r . out . result , WERR_INSUFFICIENT_BUFFER ) ) {
DATA_BLOB blob = data_blob_talloc_zero ( tctx , needed ) ;
r . in . buffer = & blob ;
r . in . offered = needed ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_GetPrinterDriverDirectory_r ( b , tctx , & r ) ,
" failed to query driver directory " ) ;
}
torture_assert_werr_ok ( tctx , r . out . result ,
" failed to query driver directory " ) ;
if ( dir_p ) {
* dir_p = r . out . info - > info1 . directory_name ;
}
return true ;
}
static const char * get_driver_from_info ( struct spoolss_AddDriverInfoCtr * info_ctr )
{
if ( info_ctr = = NULL ) {
return NULL ;
}
switch ( info_ctr - > level ) {
case 1 :
return info_ctr - > info . info1 - > driver_name ;
case 2 :
return info_ctr - > info . info2 - > driver_name ;
case 3 :
return info_ctr - > info . info3 - > driver_name ;
case 4 :
return info_ctr - > info . info4 - > driver_name ;
case 6 :
return info_ctr - > info . info6 - > driver_name ;
case 8 :
return info_ctr - > info . info8 - > driver_name ;
default :
return NULL ;
}
}
2010-04-27 16:13:12 +04:00
static const char * get_environment_from_info ( struct spoolss_AddDriverInfoCtr * info_ctr )
{
if ( info_ctr = = NULL ) {
return NULL ;
}
switch ( info_ctr - > level ) {
case 2 :
return info_ctr - > info . info2 - > architecture ;
case 3 :
return info_ctr - > info . info3 - > architecture ;
case 4 :
return info_ctr - > info . info4 - > architecture ;
case 6 :
return info_ctr - > info . info6 - > architecture ;
case 8 :
return info_ctr - > info . info8 - > architecture ;
default :
return NULL ;
}
}
2009-07-02 23:49:15 +04:00
static bool test_AddPrinterDriver_exp ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * servername ,
struct spoolss_AddDriverInfoCtr * info_ctr ,
WERROR expected_result )
{
struct spoolss_AddPrinterDriver r ;
const char * drivername = get_driver_from_info ( info_ctr ) ;
2010-04-27 16:13:12 +04:00
const char * environment = get_environment_from_info ( info_ctr ) ;
2009-07-02 23:49:15 +04:00
r . in . servername = servername ;
r . in . info_ctr = info_ctr ;
2010-04-27 16:13:12 +04:00
torture_comment ( tctx , " Testing AddPrinterDriver(%s) level: %d, environment: '%s' \n " ,
drivername , info_ctr - > level , environment ) ;
2009-07-02 23:49:15 +04:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_AddPrinterDriver_r ( b , tctx , & r ) ,
" spoolss_AddPrinterDriver failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , expected_result ,
" spoolss_AddPrinterDriver failed with unexpected result " ) ;
return true ;
}
static bool test_AddPrinterDriverEx_exp ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * servername ,
struct spoolss_AddDriverInfoCtr * info_ctr ,
uint32_t flags ,
WERROR expected_result )
{
struct spoolss_AddPrinterDriverEx r ;
const char * drivername = get_driver_from_info ( info_ctr ) ;
2010-04-27 16:13:12 +04:00
const char * environment = get_environment_from_info ( info_ctr ) ;
2009-07-02 23:49:15 +04:00
r . in . servername = servername ;
r . in . info_ctr = info_ctr ;
r . in . flags = flags ;
2010-04-27 16:13:12 +04:00
torture_comment ( tctx , " Testing AddPrinterDriverEx(%s) level: %d, environment: '%s' \n " ,
drivername , info_ctr - > level , environment ) ;
2009-07-02 23:49:15 +04:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_AddPrinterDriverEx_r ( b , tctx , & r ) ,
" AddPrinterDriverEx failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , expected_result ,
" AddPrinterDriverEx failed with unexpected result " ) ;
return true ;
}
2010-12-15 19:44:56 +03:00
# define ASSERT_DRIVER_PATH(tctx, path, driver_dir, cmt) \
if ( path & & strlen ( path ) ) { \
torture_assert_strn_equal ( tctx , path , driver_dir , strlen ( driver_dir ) , cmt ) ; \
}
2009-07-02 23:49:15 +04:00
static bool test_AddPrinterDriver_args_level_1 ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server_name ,
struct spoolss_AddDriverInfo8 * r ,
uint32_t flags ,
2010-12-15 19:44:56 +03:00
bool ex ,
const char * remote_driver_dir )
2009-07-02 23:49:15 +04:00
{
struct spoolss_AddDriverInfoCtr info_ctr ;
struct spoolss_AddDriverInfo1 info1 ;
ZERO_STRUCT ( info1 ) ;
info_ctr . level = 1 ;
info_ctr . info . info1 = & info1 ;
if ( ex ) {
torture_assert ( tctx ,
2015-12-03 17:24:43 +03:00
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_INVALID_LEVEL ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriverEx level 1 " ) ;
} else {
torture_assert ( tctx ,
2015-12-03 17:24:43 +03:00
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_INVALID_LEVEL ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriver level 1 " ) ;
}
info1 . driver_name = r - > driver_name ;
if ( ex ) {
torture_assert ( tctx ,
2015-12-03 17:24:43 +03:00
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_INVALID_LEVEL ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriverEx level 1 " ) ;
} else {
torture_assert ( tctx ,
2015-12-03 17:24:43 +03:00
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_INVALID_LEVEL ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriver level 1 " ) ;
}
return true ;
}
static bool test_AddPrinterDriver_args_level_2 ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server_name ,
struct spoolss_AddDriverInfo8 * r ,
uint32_t flags ,
2010-12-15 19:44:56 +03:00
bool ex ,
const char * remote_driver_dir )
2009-07-02 23:49:15 +04:00
{
struct spoolss_AddDriverInfoCtr info_ctr ;
struct spoolss_AddDriverInfo2 info2 ;
2010-12-15 19:44:56 +03:00
union spoolss_DriverInfo info ;
2009-07-02 23:49:15 +04:00
ZERO_STRUCT ( info2 ) ;
info_ctr . level = 2 ;
info_ctr . info . info2 = & info2 ;
if ( ex ) {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriverEx level 2 " ) ;
} else {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriver level 2 " ) ;
}
info2 . driver_name = r - > driver_name ;
if ( ex ) {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriverEx level 2 " ) ;
} else {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriver level 2 " ) ;
}
info2 . version = r - > version ;
if ( ex ) {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriverEx level 2 " ) ;
} else {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriver level 2 " ) ;
}
info2 . architecture = r - > architecture ;
if ( ex ) {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriverEx level 2 " ) ;
} else {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriver level 2 " ) ;
}
info2 . driver_path = r - > driver_path ;
if ( ex ) {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriverEx level 2 " ) ;
} else {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriver level 2 " ) ;
}
info2 . data_file = r - > data_file ;
if ( ex ) {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriverEx level 2 " ) ;
} else {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriver level 2 " ) ;
}
info2 . config_file = r - > config_file ;
if ( ex ) {
torture_assert ( tctx ,
2015-12-03 17:24:27 +03:00
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , 0 , WERR_INVALID_PARAMETER ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriverEx " ) ;
}
if ( ex ) {
torture_assert ( tctx ,
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_OK ) ,
" failed to test AddPrinterDriverEx level 2 " ) ;
} else {
torture_assert ( tctx ,
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_OK ) ,
" failed to test AddPrinterDriver level 2 " ) ;
}
torture_assert ( tctx ,
2010-12-15 19:44:56 +03:00
test_EnumPrinterDrivers_findone ( tctx , b , server_name , r - > architecture , 2 , r - > driver_name , & info ) ,
2009-07-02 23:49:15 +04:00
" failed to find added printer driver " ) ;
2010-12-15 19:44:56 +03:00
if ( remote_driver_dir ) {
ASSERT_DRIVER_PATH ( tctx , info . info2 . driver_path , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info2 . data_file , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info2 . config_file , remote_driver_dir , " unexpected path " ) ;
}
2009-07-02 23:49:15 +04:00
return true ;
}
static bool test_AddPrinterDriver_args_level_3 ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server_name ,
struct spoolss_AddDriverInfo8 * r ,
uint32_t flags ,
2010-12-15 19:44:56 +03:00
bool ex ,
const char * remote_driver_dir )
2009-07-02 23:49:15 +04:00
{
struct spoolss_AddDriverInfoCtr info_ctr ;
struct spoolss_AddDriverInfo3 info3 ;
2010-12-15 19:44:56 +03:00
union spoolss_DriverInfo info ;
2009-07-02 23:49:15 +04:00
info3 . driver_name = r - > driver_name ;
info3 . version = r - > version ;
info3 . architecture = r - > architecture ;
info3 . driver_path = r - > driver_path ;
info3 . data_file = r - > data_file ;
info3 . config_file = r - > config_file ;
2010-04-27 15:15:04 +04:00
info3 . help_file = r - > help_file ;
info3 . monitor_name = r - > monitor_name ;
info3 . default_datatype = r - > default_datatype ;
info3 . _ndr_size_dependent_files = r - > _ndr_size_dependent_files ;
info3 . dependent_files = r - > dependent_files ;
2009-07-02 23:49:15 +04:00
info_ctr . level = 3 ;
info_ctr . info . info3 = & info3 ;
if ( ex ) {
torture_assert ( tctx ,
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_OK ) ,
" failed to test AddPrinterDriverEx level 3 " ) ;
} else {
torture_assert ( tctx ,
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_OK ) ,
" failed to test AddPrinterDriver level 3 " ) ;
}
torture_assert ( tctx ,
2010-12-15 19:44:56 +03:00
test_EnumPrinterDrivers_findone ( tctx , b , server_name , r - > architecture , 3 , r - > driver_name , & info ) ,
2009-07-02 23:49:15 +04:00
" failed to find added printer driver " ) ;
2010-12-15 19:44:56 +03:00
if ( remote_driver_dir ) {
int i ;
ASSERT_DRIVER_PATH ( tctx , info . info3 . driver_path , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info3 . data_file , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info3 . config_file , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info3 . help_file , remote_driver_dir , " unexpected path " ) ;
for ( i = 0 ; info . info3 . dependent_files & & info . info3 . dependent_files [ i ] ! = NULL ; i + + ) {
ASSERT_DRIVER_PATH ( tctx , info . info3 . dependent_files [ i ] , remote_driver_dir , " unexpected path " ) ;
}
}
2009-07-02 23:49:15 +04:00
return true ;
}
static bool test_AddPrinterDriver_args_level_4 ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server_name ,
struct spoolss_AddDriverInfo8 * r ,
uint32_t flags ,
2010-12-15 19:44:56 +03:00
bool ex ,
const char * remote_driver_dir )
2009-07-02 23:49:15 +04:00
{
struct spoolss_AddDriverInfoCtr info_ctr ;
struct spoolss_AddDriverInfo4 info4 ;
2010-12-15 19:44:56 +03:00
union spoolss_DriverInfo info ;
2009-07-02 23:49:15 +04:00
info4 . version = r - > version ;
2010-04-27 15:15:04 +04:00
info4 . driver_name = r - > driver_name ;
2009-07-02 23:49:15 +04:00
info4 . architecture = r - > architecture ;
info4 . driver_path = r - > driver_path ;
info4 . data_file = r - > data_file ;
info4 . config_file = r - > config_file ;
2010-04-27 15:15:04 +04:00
info4 . help_file = r - > help_file ;
info4 . monitor_name = r - > monitor_name ;
info4 . default_datatype = r - > default_datatype ;
info4 . _ndr_size_dependent_files = r - > _ndr_size_dependent_files ;
info4 . dependent_files = r - > dependent_files ;
info4 . _ndr_size_previous_names = r - > _ndr_size_previous_names ;
info4 . previous_names = r - > previous_names ;
2009-07-02 23:49:15 +04:00
info_ctr . level = 4 ;
info_ctr . info . info4 = & info4 ;
if ( ex ) {
torture_assert ( tctx ,
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_OK ) ,
" failed to test AddPrinterDriverEx level 4 " ) ;
} else {
torture_assert ( tctx ,
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_OK ) ,
" failed to test AddPrinterDriver level 4 " ) ;
}
torture_assert ( tctx ,
2010-12-15 19:44:56 +03:00
test_EnumPrinterDrivers_findone ( tctx , b , server_name , r - > architecture , 4 , r - > driver_name , & info ) ,
2009-07-02 23:49:15 +04:00
" failed to find added printer driver " ) ;
2010-12-15 19:44:56 +03:00
if ( remote_driver_dir ) {
int i ;
ASSERT_DRIVER_PATH ( tctx , info . info4 . driver_path , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info4 . data_file , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info4 . config_file , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info4 . help_file , remote_driver_dir , " unexpected path " ) ;
for ( i = 0 ; info . info4 . dependent_files & & info . info4 . dependent_files [ i ] ! = NULL ; i + + ) {
ASSERT_DRIVER_PATH ( tctx , info . info4 . dependent_files [ i ] , remote_driver_dir , " unexpected path " ) ;
}
}
2009-07-02 23:49:15 +04:00
return true ;
}
static bool test_AddPrinterDriver_args_level_6 ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server_name ,
struct spoolss_AddDriverInfo8 * r ,
uint32_t flags ,
2010-12-15 19:44:56 +03:00
bool ex ,
const char * remote_driver_dir )
2009-07-02 23:49:15 +04:00
{
struct spoolss_AddDriverInfoCtr info_ctr ;
struct spoolss_AddDriverInfo6 info6 ;
2010-12-15 19:44:56 +03:00
union spoolss_DriverInfo info ;
2009-07-02 23:49:15 +04:00
info6 . version = r - > version ;
2010-04-27 15:15:04 +04:00
info6 . driver_name = r - > driver_name ;
2009-07-02 23:49:15 +04:00
info6 . architecture = r - > architecture ;
info6 . driver_path = r - > driver_path ;
info6 . data_file = r - > data_file ;
info6 . config_file = r - > config_file ;
2010-04-27 15:15:04 +04:00
info6 . help_file = r - > help_file ;
info6 . monitor_name = r - > monitor_name ;
info6 . default_datatype = r - > default_datatype ;
info6 . _ndr_size_dependent_files = r - > _ndr_size_dependent_files ;
info6 . dependent_files = r - > dependent_files ;
info6 . _ndr_size_previous_names = r - > _ndr_size_previous_names ;
info6 . previous_names = r - > previous_names ;
info6 . driver_date = r - > driver_date ;
info6 . driver_version = r - > driver_version ;
info6 . manufacturer_name = r - > manufacturer_name ;
info6 . manufacturer_url = r - > manufacturer_url ;
info6 . hardware_id = r - > hardware_id ;
info6 . provider = r - > provider ;
2009-07-02 23:49:15 +04:00
info_ctr . level = 6 ;
info_ctr . info . info6 = & info6 ;
if ( ex ) {
torture_assert ( tctx ,
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_OK ) ,
" failed to test AddPrinterDriverEx level 6 " ) ;
} else {
torture_assert ( tctx ,
2015-12-03 17:24:43 +03:00
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_INVALID_LEVEL ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriver level 6 " ) ;
}
/* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
if ( ! ex ) {
return true ;
}
torture_assert ( tctx ,
2010-12-15 19:44:56 +03:00
test_EnumPrinterDrivers_findone ( tctx , b , server_name , r - > architecture , 6 , r - > driver_name , & info ) ,
2009-07-02 23:49:15 +04:00
" failed to find added printer driver " ) ;
2010-12-15 19:44:56 +03:00
if ( remote_driver_dir ) {
int i ;
ASSERT_DRIVER_PATH ( tctx , info . info6 . driver_path , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info6 . data_file , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info6 . config_file , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info6 . help_file , remote_driver_dir , " unexpected path " ) ;
for ( i = 0 ; info . info6 . dependent_files & & info . info6 . dependent_files [ i ] ! = NULL ; i + + ) {
ASSERT_DRIVER_PATH ( tctx , info . info6 . dependent_files [ i ] , remote_driver_dir , " unexpected path " ) ;
}
}
2010-12-21 18:14:48 +03:00
torture_assert_nttime_equal ( tctx , info . info6 . driver_date , info6 . driver_date , " driverdate mismatch " ) ;
2010-12-24 03:55:08 +03:00
torture_assert_u64_equal ( tctx , info . info6 . driver_version , info6 . driver_version , " driverversion mismatch " ) ;
2010-12-21 18:14:48 +03:00
2009-07-02 23:49:15 +04:00
return true ;
}
static bool test_AddPrinterDriver_args_level_8 ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server_name ,
struct spoolss_AddDriverInfo8 * r ,
uint32_t flags ,
2010-12-15 19:44:56 +03:00
bool ex ,
const char * remote_driver_dir )
2009-07-02 23:49:15 +04:00
{
struct spoolss_AddDriverInfoCtr info_ctr ;
2010-12-15 19:44:56 +03:00
union spoolss_DriverInfo info ;
2009-07-02 23:49:15 +04:00
info_ctr . level = 8 ;
2010-04-27 15:15:04 +04:00
info_ctr . info . info8 = r ;
2009-07-02 23:49:15 +04:00
if ( ex ) {
torture_assert ( tctx ,
test_AddPrinterDriverEx_exp ( tctx , b , server_name , & info_ctr , flags , WERR_OK ) ,
" failed to test AddPrinterDriverEx level 8 " ) ;
} else {
torture_assert ( tctx ,
2015-12-03 17:24:43 +03:00
test_AddPrinterDriver_exp ( tctx , b , server_name , & info_ctr , WERR_INVALID_LEVEL ) ,
2009-07-02 23:49:15 +04:00
" failed to test AddPrinterDriver level 8 " ) ;
}
/* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
if ( ! ex ) {
return true ;
}
torture_assert ( tctx ,
2010-12-15 19:44:56 +03:00
test_EnumPrinterDrivers_findone ( tctx , b , server_name , r - > architecture , 8 , r - > driver_name , & info ) ,
2009-07-02 23:49:15 +04:00
" failed to find added printer driver " ) ;
2010-12-15 19:44:56 +03:00
if ( remote_driver_dir ) {
int i ;
ASSERT_DRIVER_PATH ( tctx , info . info8 . driver_path , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info8 . data_file , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info8 . config_file , remote_driver_dir , " unexpected path " ) ;
ASSERT_DRIVER_PATH ( tctx , info . info8 . help_file , remote_driver_dir , " unexpected path " ) ;
for ( i = 0 ; info . info8 . dependent_files & & info . info8 . dependent_files [ i ] ! = NULL ; i + + ) {
ASSERT_DRIVER_PATH ( tctx , info . info8 . dependent_files [ i ] , remote_driver_dir , " unexpected path " ) ;
}
}
2010-12-21 18:14:48 +03:00
torture_assert_nttime_equal ( tctx , info . info8 . driver_date , r - > driver_date , " driverdate mismatch " ) ;
2010-12-24 03:55:08 +03:00
torture_assert_u64_equal ( tctx , info . info8 . driver_version , r - > driver_version , " driverversion mismatch " ) ;
2010-12-21 18:14:48 +03:00
2009-07-02 23:49:15 +04:00
return true ;
}
2010-12-15 19:44:56 +03:00
# undef ASSERT_DRIVER_PATH
2009-07-02 23:49:15 +04:00
static bool test_DeletePrinterDriver_exp ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
2010-04-23 13:39:12 +04:00
const char * server ,
2009-07-02 23:49:15 +04:00
const char * driver ,
const char * environment ,
WERROR expected_result )
{
struct spoolss_DeletePrinterDriver r ;
2010-04-23 13:39:12 +04:00
r . in . server = server ;
2009-07-02 23:49:15 +04:00
r . in . architecture = environment ;
r . in . driver = driver ;
torture_comment ( tctx , " Testing DeletePrinterDriver(%s) \n " , driver ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_DeletePrinterDriver_r ( b , tctx , & r ) ,
" DeletePrinterDriver failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , expected_result ,
" DeletePrinterDriver failed with unexpected result " ) ;
return true ;
}
static bool test_DeletePrinterDriverEx_exp ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
2010-04-23 13:39:12 +04:00
const char * server ,
2009-07-02 23:49:15 +04:00
const char * driver ,
const char * environment ,
uint32_t delete_flags ,
uint32_t version ,
WERROR expected_result )
{
struct spoolss_DeletePrinterDriverEx r ;
2010-04-23 13:39:12 +04:00
r . in . server = server ;
2009-07-02 23:49:15 +04:00
r . in . architecture = environment ;
r . in . driver = driver ;
r . in . delete_flags = delete_flags ;
r . in . version = version ;
torture_comment ( tctx , " Testing DeletePrinterDriverEx(%s) \n " , driver ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_DeletePrinterDriverEx_r ( b , tctx , & r ) ,
" DeletePrinterDriverEx failed " ) ;
torture_assert_werr_equal ( tctx , r . out . result , expected_result ,
" DeletePrinterDriverEx failed with unexpected result " ) ;
return true ;
}
static bool test_DeletePrinterDriver ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
2010-04-23 13:39:12 +04:00
const char * server_name ,
2009-07-02 23:49:15 +04:00
const char * driver ,
const char * environment )
{
torture_assert ( tctx ,
2010-04-23 13:39:12 +04:00
test_DeletePrinterDriver_exp ( tctx , b , server_name , driver , " FOOBAR " , WERR_INVALID_ENVIRONMENT ) ,
2009-07-02 23:49:15 +04:00
" failed to delete driver " ) ;
torture_assert ( tctx ,
2010-04-23 13:39:12 +04:00
test_DeletePrinterDriver_exp ( tctx , b , server_name , driver , environment , WERR_OK ) ,
2009-07-02 23:49:15 +04:00
" failed to delete driver " ) ;
2010-12-15 19:44:56 +03:00
if ( test_EnumPrinterDrivers_findone ( tctx , b , server_name , environment , 1 , driver , NULL ) ) {
2009-07-02 23:49:15 +04:00
torture_fail ( tctx , " deleted driver still enumerated " ) ;
}
torture_assert ( tctx ,
2010-04-23 13:39:12 +04:00
test_DeletePrinterDriver_exp ( tctx , b , server_name , driver , environment , WERR_UNKNOWN_PRINTER_DRIVER ) ,
2009-07-02 23:49:15 +04:00
" 2nd delete failed " ) ;
return true ;
}
static bool test_DeletePrinterDriverEx ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
2010-04-23 13:39:12 +04:00
const char * server_name ,
2009-07-02 23:49:15 +04:00
const char * driver ,
const char * environment ,
uint32_t delete_flags ,
uint32_t version )
{
torture_assert ( tctx ,
2010-04-23 13:39:12 +04:00
test_DeletePrinterDriverEx_exp ( tctx , b , server_name , driver , " FOOBAR " , delete_flags , version , WERR_INVALID_ENVIRONMENT ) ,
2009-07-02 23:49:15 +04:00
" failed to delete driver " ) ;
torture_assert ( tctx ,
2010-04-23 13:39:12 +04:00
test_DeletePrinterDriverEx_exp ( tctx , b , server_name , driver , environment , delete_flags , version , WERR_OK ) ,
2009-07-02 23:49:15 +04:00
" failed to delete driver " ) ;
2010-12-15 19:44:56 +03:00
if ( test_EnumPrinterDrivers_findone ( tctx , b , server_name , environment , 1 , driver , NULL ) ) {
2009-07-02 23:49:15 +04:00
torture_fail ( tctx , " deleted driver still enumerated " ) ;
}
torture_assert ( tctx ,
2010-04-23 13:39:12 +04:00
test_DeletePrinterDriverEx_exp ( tctx , b , server_name , driver , environment , delete_flags , version , WERR_UNKNOWN_PRINTER_DRIVER ) ,
2009-07-02 23:49:15 +04:00
" 2nd delete failed " ) ;
return true ;
}
static bool test_PrinterDriver_args ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
const char * server_name ,
uint32_t level ,
struct spoolss_AddDriverInfo8 * r ,
uint32_t add_flags ,
uint32_t delete_flags ,
uint32_t delete_version ,
2010-12-15 19:44:56 +03:00
bool ex ,
const char * remote_driver_dir )
2009-07-02 23:49:15 +04:00
{
bool ret = true ;
switch ( level ) {
case 1 :
2010-12-15 19:44:56 +03:00
ret = test_AddPrinterDriver_args_level_1 ( tctx , b , server_name , r , add_flags , ex , remote_driver_dir ) ;
2009-07-02 23:49:15 +04:00
break ;
case 2 :
2010-12-15 19:44:56 +03:00
ret = test_AddPrinterDriver_args_level_2 ( tctx , b , server_name , r , add_flags , ex , remote_driver_dir ) ;
2009-07-02 23:49:15 +04:00
break ;
case 3 :
2010-12-15 19:44:56 +03:00
ret = test_AddPrinterDriver_args_level_3 ( tctx , b , server_name , r , add_flags , ex , remote_driver_dir ) ;
2009-07-02 23:49:15 +04:00
break ;
case 4 :
2010-12-15 19:44:56 +03:00
ret = test_AddPrinterDriver_args_level_4 ( tctx , b , server_name , r , add_flags , ex , remote_driver_dir ) ;
2009-07-02 23:49:15 +04:00
break ;
case 6 :
2010-12-15 19:44:56 +03:00
ret = test_AddPrinterDriver_args_level_6 ( tctx , b , server_name , r , add_flags , ex , remote_driver_dir ) ;
2009-07-02 23:49:15 +04:00
break ;
case 8 :
2010-12-15 19:44:56 +03:00
ret = test_AddPrinterDriver_args_level_8 ( tctx , b , server_name , r , add_flags , ex , remote_driver_dir ) ;
2009-07-02 23:49:15 +04:00
break ;
default :
return false ;
}
if ( ret = = false ) {
return ret ;
}
if ( level = = 1 ) {
return ret ;
}
/* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
if ( ! ex & & ( level = = 6 | | level = = 8 ) ) {
return ret ;
}
2010-12-17 18:34:47 +03:00
{
struct dcerpc_pipe * p2 ;
struct policy_handle hive_handle ;
struct dcerpc_binding_handle * b2 ;
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection ( tctx , & p2 , & ndr_table_winreg ) ,
" could not open winreg pipe " ) ;
b2 = p2 - > binding_handle ;
torture_assert ( tctx , test_winreg_OpenHKLM ( tctx , b2 , & hive_handle ) , " " ) ;
ret = test_GetDriverInfo_winreg ( tctx , b , NULL , NULL , r - > driver_name , r - > architecture , r - > version , b2 , & hive_handle , server_name ) ;
test_winreg_CloseKey ( tctx , b2 , & hive_handle ) ;
talloc_free ( p2 ) ;
}
2009-07-02 23:49:15 +04:00
if ( ex ) {
2010-04-23 13:39:12 +04:00
return test_DeletePrinterDriverEx ( tctx , b , server_name , r - > driver_name , r - > architecture , delete_flags , r - > version ) ;
2009-07-02 23:49:15 +04:00
} else {
2010-04-23 13:39:12 +04:00
return test_DeletePrinterDriver ( tctx , b , server_name , r - > driver_name , r - > architecture ) ;
2009-07-02 23:49:15 +04:00
}
}
static bool fillup_printserver_info ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct torture_driver_context * d )
{
struct policy_handle server_handle ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
const char * server_name_slash = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
torture_assert ( tctx ,
test_OpenPrinter_server ( tctx , p , & server_handle ) ,
" failed to open printserver " ) ;
torture_assert ( tctx ,
test_get_environment ( tctx , b , & server_handle , & d - > remote . environment ) ,
" failed to get environment " ) ;
torture_assert ( tctx ,
test_ClosePrinter ( tctx , b , & server_handle ) ,
" failed to close printserver " ) ;
torture_assert ( tctx ,
2010-04-23 03:58:02 +04:00
test_GetPrinterDriverDirectory_getdir ( tctx , b , server_name_slash ,
d - > local . environment ? d - > local . environment : d - > remote . environment ,
& d - > remote . driver_directory ) ,
2009-07-02 23:49:15 +04:00
" failed to get driver directory " ) ;
return true ;
}
2010-04-22 20:47:27 +04:00
static const char * driver_directory_dir ( const char * driver_directory )
{
char * p ;
p = strrchr ( driver_directory , ' \\ ' ) ;
if ( p ) {
return p + 1 ;
}
return NULL ;
}
static const char * driver_directory_share ( struct torture_context * tctx ,
const char * driver_directory )
{
const char * p ;
char * tok ;
if ( driver_directory [ 0 ] = = ' \\ ' & & driver_directory [ 1 ] = = ' \\ ' ) {
driver_directory + = 2 ;
}
p = talloc_strdup ( tctx , driver_directory ) ;
torture_assert ( tctx ,
next_token_talloc ( tctx , & p , & tok , " \\ " ) ,
" cannot explode uri " ) ;
torture_assert ( tctx ,
next_token_talloc ( tctx , & p , & tok , " \\ " ) ,
" cannot explode uri " ) ;
return tok ;
}
2016-11-15 20:34:22 +03:00
# define CREATE_PRINTER_DRIVER_PATH(_d, _file) \
talloc_asprintf ( ( _d ) , " %s \\ %s \\ %s " , ( _d ) - > remote . driver_directory , ( _d ) - > remote . driver_upload_directory , ( _file ) )
static bool create_printer_driver_directory ( struct torture_context * tctx ,
struct smbcli_state * cli ,
struct torture_driver_context * d )
{
char * driver_dir ;
if ( d - > remote . driver_upload_directory = = NULL ) {
return true ;
}
driver_dir = talloc_asprintf ( tctx ,
" %s \\ %s " ,
driver_directory_dir ( d - > remote . driver_directory ) ,
d - > remote . driver_upload_directory ) ;
torture_assert_not_null ( tctx , driver_dir , " ENOMEM " ) ;
torture_comment ( tctx ,
" Create remote driver directory: %s \n " ,
driver_dir ) ;
torture_assert_ntstatus_ok ( tctx ,
smbcli_mkdir ( cli - > tree ,
driver_dir ) ,
" Failed to create driver directory " ) ;
return true ;
}
2010-04-22 20:47:27 +04:00
static bool upload_printer_driver_file ( struct torture_context * tctx ,
struct smbcli_state * cli ,
struct torture_driver_context * d ,
const char * file_name )
{
2016-11-26 00:01:38 +03:00
FILE * f ;
2010-04-22 20:47:27 +04:00
int fnum ;
uint8_t * buf ;
int maxwrite = 64512 ;
off_t nread = 0 ;
size_t start = 0 ;
const char * remote_dir = driver_directory_dir ( d - > remote . driver_directory ) ;
2016-11-15 20:34:22 +03:00
const char * remote_name ;
const char * local_name ;
const char * p ;
2010-04-22 20:47:27 +04:00
2010-11-29 19:07:02 +03:00
if ( ! file_name | | strlen ( file_name ) = = 0 ) {
2010-04-23 13:27:51 +04:00
return true ;
}
2016-11-15 20:34:22 +03:00
p = strrchr ( file_name , ' \\ ' ) ;
if ( p = = NULL ) {
p = file_name ;
} else {
p + + ;
}
local_name = talloc_asprintf ( tctx , " %s/%s " , d - > local . driver_directory , p ) ;
torture_assert_not_null ( tctx , local_name , " ENOMEM " ) ;
if ( d - > remote . driver_upload_directory ! = NULL ) {
remote_name = talloc_asprintf ( tctx ,
" %s \\ %s \\ %s " ,
remote_dir ,
d - > remote . driver_upload_directory ,
p ) ;
} else {
remote_name = talloc_asprintf ( tctx , " %s \\ %s " , remote_dir , p ) ;
}
torture_assert_not_null ( tctx , remote_name , " ENOMEM " ) ;
2010-04-22 20:47:27 +04:00
torture_comment ( tctx , " Uploading %s to %s \n " , local_name , remote_name ) ;
fnum = smbcli_open ( cli - > tree , remote_name , O_RDWR | O_CREAT | O_TRUNC , DENY_NONE ) ;
if ( fnum = = - 1 ) {
torture_fail ( tctx , talloc_asprintf ( tctx , " failed to open remote file: %s \n " , remote_name ) ) ;
}
2016-11-26 00:01:38 +03:00
f = fopen ( local_name , " r " ) ;
2010-04-22 20:47:27 +04:00
if ( f = = NULL ) {
torture_fail ( tctx , talloc_asprintf ( tctx , " failed to open local file: %s \n " , local_name ) ) ;
}
buf = talloc_array ( tctx , uint8_t , maxwrite ) ;
if ( ! buf ) {
2016-11-26 00:01:38 +03:00
fclose ( f ) ;
2010-04-22 20:47:27 +04:00
return false ;
}
2016-11-26 00:01:38 +03:00
while ( ! feof ( f ) ) {
2010-04-22 20:47:27 +04:00
int n = maxwrite ;
int ret ;
2016-11-26 00:01:38 +03:00
if ( ( n = fread ( buf , 1 , n , f ) ) < 1 ) {
if ( ( n = = 0 ) & & feof ( f ) )
2010-04-22 20:47:27 +04:00
break ; /* Empty local file. */
torture_warning ( tctx ,
" failed to read file: %s \n " , strerror ( errno ) ) ;
break ;
}
ret = smbcli_write ( cli - > tree , fnum , 0 , buf , nread + start , n ) ;
if ( n ! = ret ) {
torture_warning ( tctx ,
" failed to write file: %s \n " , smbcli_errstr ( cli - > tree ) ) ;
break ;
}
nread + = n ;
}
2016-11-26 00:01:38 +03:00
fclose ( f ) ;
2010-04-22 20:47:27 +04:00
torture_assert_ntstatus_ok ( tctx ,
smbcli_close ( cli - > tree , fnum ) ,
" failed to close file " ) ;
return true ;
}
static bool connect_printer_driver_share ( struct torture_context * tctx ,
const char * server_name ,
const char * share_name ,
struct smbcli_state * * cli )
{
struct smbcli_options smb_options ;
struct smbcli_session_options smb_session_options ;
2010-04-27 13:30:35 +04:00
torture_comment ( tctx , " Connecting printer driver share '%s' on '%s' \n " ,
share_name , server_name ) ;
2010-04-22 20:47:27 +04:00
2010-07-16 08:32:42 +04:00
lpcfg_smbcli_options ( tctx - > lp_ctx , & smb_options ) ;
lpcfg_smbcli_session_options ( tctx - > lp_ctx , & smb_session_options ) ;
2010-04-22 20:47:27 +04:00
torture_assert_ntstatus_ok ( tctx ,
smbcli_full_connection ( tctx , cli , server_name ,
2010-07-16 08:32:42 +04:00
lpcfg_smb_ports ( tctx - > lp_ctx ) ,
2010-04-22 20:47:27 +04:00
share_name , NULL ,
2010-07-16 08:32:42 +04:00
lpcfg_socket_options ( tctx - > lp_ctx ) ,
2017-05-10 02:10:03 +03:00
popt_get_cmdline_credentials ( ) ,
2010-07-16 08:32:42 +04:00
lpcfg_resolve_context ( tctx - > lp_ctx ) ,
2010-04-22 20:47:27 +04:00
tctx - > ev ,
& smb_options ,
& smb_session_options ,
2010-07-16 08:32:42 +04:00
lpcfg_gensec_settings ( tctx , tctx - > lp_ctx ) ) ,
2010-04-22 20:47:27 +04:00
" failed to open driver share " ) ;
return true ;
}
static bool upload_printer_driver ( struct torture_context * tctx ,
const char * server_name ,
struct torture_driver_context * d )
{
struct smbcli_state * cli ;
const char * share_name = driver_directory_share ( tctx , d - > remote . driver_directory ) ;
2010-04-23 13:27:51 +04:00
int i ;
2010-04-22 20:47:27 +04:00
torture_assert ( tctx ,
connect_printer_driver_share ( tctx , server_name , share_name , & cli ) ,
" failed to connect to driver share " ) ;
torture_comment ( tctx , " Uploading printer driver files to \\ \\ %s \\ %s \n " ,
server_name , share_name ) ;
2016-11-15 20:34:22 +03:00
torture_assert ( tctx ,
create_printer_driver_directory ( tctx , cli , d ) ,
" failed to create driver directory " ) ;
2010-04-22 20:47:27 +04:00
torture_assert ( tctx ,
upload_printer_driver_file ( tctx , cli , d , d - > info8 . driver_path ) ,
" failed to upload driver_path " ) ;
torture_assert ( tctx ,
upload_printer_driver_file ( tctx , cli , d , d - > info8 . data_file ) ,
" failed to upload data_file " ) ;
torture_assert ( tctx ,
upload_printer_driver_file ( tctx , cli , d , d - > info8 . config_file ) ,
" failed to upload config_file " ) ;
2010-04-23 13:27:51 +04:00
torture_assert ( tctx ,
upload_printer_driver_file ( tctx , cli , d , d - > info8 . help_file ) ,
" failed to upload help_file " ) ;
if ( d - > info8 . dependent_files ) {
for ( i = 0 ; d - > info8 . dependent_files - > string & & d - > info8 . dependent_files - > string [ i ] ! = NULL ; i + + ) {
torture_assert ( tctx ,
upload_printer_driver_file ( tctx , cli , d , d - > info8 . dependent_files - > string [ i ] ) ,
" failed to upload dependent_files " ) ;
}
}
2010-04-22 20:47:27 +04:00
talloc_free ( cli ) ;
return true ;
}
2012-01-17 18:20:51 +04:00
static bool check_printer_driver_file ( struct torture_context * tctx ,
struct smbcli_state * cli ,
struct torture_driver_context * d ,
const char * file_name )
{
const char * remote_arch_dir = driver_directory_dir ( d - > remote . driver_directory ) ;
const char * remote_name = talloc_asprintf ( tctx , " %s \\ %d \\ %s " ,
remote_arch_dir ,
d - > info8 . version ,
file_name ) ;
int fnum ;
torture_assert ( tctx , ( file_name & & strlen ( file_name ) ! = 0 ) , " invalid filename " ) ;
torture_comment ( tctx , " checking for driver file at %s \n " , remote_name ) ;
fnum = smbcli_open ( cli - > tree , remote_name , O_RDONLY , DENY_NONE ) ;
if ( fnum = = - 1 ) {
return false ;
}
torture_assert_ntstatus_ok ( tctx ,
smbcli_close ( cli - > tree , fnum ) ,
" failed to close driver file " ) ;
return true ;
}
static bool check_printer_driver_files ( struct torture_context * tctx ,
const char * server_name ,
struct torture_driver_context * d ,
bool expect_exist )
{
struct smbcli_state * cli ;
const char * share_name = driver_directory_share ( tctx , d - > remote . driver_directory ) ;
int i ;
torture_assert ( tctx ,
connect_printer_driver_share ( tctx , server_name , share_name , & cli ) ,
" failed to connect to driver share " ) ;
torture_comment ( tctx , " checking %sexistent driver files at \\ \\ %s \\ %s \n " ,
( expect_exist ? " " : " non- " ) ,
server_name , share_name ) ;
if ( d - > info8 . driver_path & & d - > info8 . driver_path [ 0 ] ) {
torture_assert ( tctx ,
check_printer_driver_file ( tctx , cli , d , d - > info8 . driver_path ) = = expect_exist ,
" failed driver_path check " ) ;
}
if ( d - > info8 . data_file & & d - > info8 . data_file [ 0 ] ) {
torture_assert ( tctx ,
check_printer_driver_file ( tctx , cli , d , d - > info8 . data_file ) = = expect_exist ,
" failed data_file check " ) ;
}
if ( d - > info8 . config_file & & d - > info8 . config_file [ 0 ] ) {
torture_assert ( tctx ,
check_printer_driver_file ( tctx , cli , d , d - > info8 . config_file ) = = expect_exist ,
" failed config_file check " ) ;
}
if ( d - > info8 . help_file & & d - > info8 . help_file [ 0 ] ) {
torture_assert ( tctx ,
check_printer_driver_file ( tctx , cli , d , d - > info8 . help_file ) = = expect_exist ,
" failed help_file check " ) ;
}
if ( d - > info8 . dependent_files ) {
for ( i = 0 ; d - > info8 . dependent_files - > string & & d - > info8 . dependent_files - > string [ i ] ! = NULL ; i + + ) {
torture_assert ( tctx ,
check_printer_driver_file ( tctx , cli , d , d - > info8 . dependent_files - > string [ i ] ) = = expect_exist ,
" failed dependent_files check " ) ;
}
}
talloc_free ( cli ) ;
return true ;
}
2010-04-22 20:47:27 +04:00
static bool remove_printer_driver_file ( struct torture_context * tctx ,
struct smbcli_state * cli ,
struct torture_driver_context * d ,
const char * file_name )
{
const char * remote_name ;
const char * remote_dir = driver_directory_dir ( d - > remote . driver_directory ) ;
2010-11-29 19:07:02 +03:00
if ( ! file_name | | strlen ( file_name ) = = 0 ) {
2010-04-23 13:27:51 +04:00
return true ;
}
2010-04-22 20:47:27 +04:00
remote_name = talloc_asprintf ( tctx , " %s \\ %s " , remote_dir , file_name ) ;
torture_comment ( tctx , " Removing %s \n " , remote_name ) ;
torture_assert_ntstatus_ok ( tctx ,
smbcli_unlink ( cli - > tree , remote_name ) ,
" failed to unlink " ) ;
return true ;
}
static bool remove_printer_driver ( struct torture_context * tctx ,
const char * server_name ,
struct torture_driver_context * d )
{
struct smbcli_state * cli ;
const char * share_name = driver_directory_share ( tctx , d - > remote . driver_directory ) ;
2010-04-23 13:27:51 +04:00
int i ;
2010-04-22 20:47:27 +04:00
torture_assert ( tctx ,
connect_printer_driver_share ( tctx , server_name , share_name , & cli ) ,
" failed to connect to driver share " ) ;
torture_comment ( tctx , " Removing printer driver files from \\ \\ %s \\ %s \n " ,
server_name , share_name ) ;
torture_assert ( tctx ,
remove_printer_driver_file ( tctx , cli , d , d - > info8 . driver_path ) ,
" failed to remove driver_path " ) ;
torture_assert ( tctx ,
remove_printer_driver_file ( tctx , cli , d , d - > info8 . data_file ) ,
" failed to remove data_file " ) ;
2010-11-29 17:08:01 +03:00
if ( ! strequal ( d - > info8 . config_file , d - > info8 . driver_path ) ) {
torture_assert ( tctx ,
remove_printer_driver_file ( tctx , cli , d , d - > info8 . config_file ) ,
" failed to remove config_file " ) ;
}
2010-04-23 13:27:51 +04:00
torture_assert ( tctx ,
remove_printer_driver_file ( tctx , cli , d , d - > info8 . help_file ) ,
" failed to remove help_file " ) ;
if ( d - > info8 . dependent_files ) {
for ( i = 0 ; d - > info8 . dependent_files - > string & & d - > info8 . dependent_files - > string [ i ] ! = NULL ; i + + ) {
2010-04-27 17:48:52 +04:00
if ( strequal ( d - > info8 . dependent_files - > string [ i ] , d - > info8 . driver_path ) | |
strequal ( d - > info8 . dependent_files - > string [ i ] , d - > info8 . data_file ) | |
strequal ( d - > info8 . dependent_files - > string [ i ] , d - > info8 . config_file ) | |
strequal ( d - > info8 . dependent_files - > string [ i ] , d - > info8 . help_file ) ) {
continue ;
}
2010-04-23 13:27:51 +04:00
torture_assert ( tctx ,
remove_printer_driver_file ( tctx , cli , d , d - > info8 . dependent_files - > string [ i ] ) ,
" failed to remove dependent_files " ) ;
}
}
2010-04-22 20:47:27 +04:00
talloc_free ( cli ) ;
return true ;
}
2010-04-23 03:58:02 +04:00
static bool test_add_driver_arg ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct torture_driver_context * d )
2009-07-02 23:49:15 +04:00
{
bool ret = true ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
const char * server_name_slash = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
uint32_t levels [ ] = { 1 , 2 , 3 , 4 , 6 , 8 } ;
int i ;
struct spoolss_AddDriverInfo8 info8 ;
2010-04-23 03:58:02 +04:00
uint32_t add_flags = APD_COPY_NEW_FILES ;
uint32_t delete_flags = 0 ;
2010-04-27 19:52:47 +04:00
ZERO_STRUCT ( info8 ) ;
2010-04-23 03:58:02 +04:00
torture_comment ( tctx , " Testing PrinterDriver%s '%s' for environment '%s' \n " ,
d - > ex ? " Ex " : " " , d - > info8 . driver_name , d - > local . environment ) ;
2009-07-02 23:49:15 +04:00
torture_assert ( tctx ,
fillup_printserver_info ( tctx , p , d ) ,
" failed to fillup printserver info " ) ;
2010-04-23 15:52:19 +04:00
if ( ! directory_exist ( d - > local . driver_directory ) ) {
torture_skip ( tctx , " Skipping Printer Driver test as no local driver is available " ) ;
}
2010-04-22 20:47:27 +04:00
torture_assert ( tctx ,
upload_printer_driver ( tctx , dcerpc_server_name ( p ) , d ) ,
" failed to upload printer driver " ) ;
2010-12-24 03:25:49 +03:00
info8 = d - > info8 ;
if ( d - > info8 . dependent_files ) {
info8 . dependent_files = talloc_zero ( tctx , struct spoolss_StringArray ) ;
if ( d - > info8 . dependent_files - > string ) {
for ( i = 0 ; d - > info8 . dependent_files - > string [ i ] ! = NULL ; i + + ) {
}
info8 . dependent_files - > string = talloc_zero_array ( info8 . dependent_files , const char * , i + 1 ) ;
for ( i = 0 ; d - > info8 . dependent_files - > string [ i ] ! = NULL ; i + + ) {
info8 . dependent_files - > string [ i ] = talloc_strdup ( info8 . dependent_files - > string , d - > info8 . dependent_files - > string [ i ] ) ;
}
}
}
2009-07-02 23:49:15 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
2010-04-23 04:49:42 +04:00
if ( torture_setting_bool ( tctx , " samba3 " , false ) ) {
switch ( levels [ i ] ) {
case 2 :
case 4 :
torture_comment ( tctx , " skipping level %d against samba \n " , levels [ i ] ) ;
continue ;
default :
break ;
}
}
2010-12-16 13:58:36 +03:00
if ( torture_setting_bool ( tctx , " w2k3 " , false ) ) {
switch ( levels [ i ] ) {
case 8 :
torture_comment ( tctx , " skipping level %d against w2k3 \n " , levels [ i ] ) ;
continue ;
default :
break ;
}
}
2010-04-23 04:49:42 +04:00
2009-07-02 23:49:15 +04:00
torture_comment ( tctx ,
2010-04-23 03:58:02 +04:00
" Testing PrinterDriver%s '%s' add & delete level %d \n " ,
d - > ex ? " Ex " : " " , info8 . driver_name , levels [ i ] ) ;
2009-07-02 23:49:15 +04:00
2010-12-15 19:44:56 +03:00
ret & = test_PrinterDriver_args ( tctx , b , server_name_slash , levels [ i ] , & info8 , add_flags , delete_flags , d - > info8 . version , d - > ex , d - > remote . driver_directory ) ;
2009-07-02 23:49:15 +04:00
}
info8 . driver_path = talloc_asprintf ( tctx , " %s \\ %s " , d - > remote . driver_directory , d - > info8 . driver_path ) ;
info8 . data_file = talloc_asprintf ( tctx , " %s \\ %s " , d - > remote . driver_directory , d - > info8 . data_file ) ;
2010-11-29 19:48:42 +03:00
if ( d - > info8 . config_file ) {
info8 . config_file = talloc_asprintf ( tctx , " %s \\ %s " , d - > remote . driver_directory , d - > info8 . config_file ) ;
}
2010-12-24 03:22:24 +03:00
if ( d - > info8 . help_file ) {
info8 . help_file = talloc_asprintf ( tctx , " %s \\ %s " , d - > remote . driver_directory , d - > info8 . help_file ) ;
}
if ( d - > info8 . dependent_files & & d - > info8 . dependent_files - > string ) {
for ( i = 0 ; d - > info8 . dependent_files - > string [ i ] ! = NULL ; i + + ) {
info8 . dependent_files - > string [ i ] = talloc_asprintf ( tctx , " %s \\ %s " , d - > remote . driver_directory , d - > info8 . dependent_files - > string [ i ] ) ;
}
}
2009-07-02 23:49:15 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
2010-04-23 04:49:42 +04:00
if ( torture_setting_bool ( tctx , " samba3 " , false ) ) {
switch ( levels [ i ] ) {
case 2 :
case 4 :
continue ;
default :
break ;
}
}
2010-12-16 13:58:36 +03:00
if ( torture_setting_bool ( tctx , " w2k3 " , false ) ) {
switch ( levels [ i ] ) {
case 8 :
torture_comment ( tctx , " skipping level %d against w2k3 \n " , levels [ i ] ) ;
continue ;
default :
break ;
}
}
2010-04-23 04:49:42 +04:00
2009-07-02 23:49:15 +04:00
torture_comment ( tctx ,
2010-04-23 03:58:02 +04:00
" Testing PrinterDriver%s '%s' add & delete level %d (full unc paths) \n " ,
d - > ex ? " Ex " : " " , info8 . driver_name , levels [ i ] ) ;
2009-07-02 23:49:15 +04:00
2010-12-15 19:44:56 +03:00
ret & = test_PrinterDriver_args ( tctx , b , server_name_slash , levels [ i ] , & info8 , add_flags , delete_flags , d - > info8 . version , d - > ex , d - > remote . driver_directory ) ;
2009-07-02 23:49:15 +04:00
}
2010-04-22 20:47:27 +04:00
torture_assert ( tctx ,
remove_printer_driver ( tctx , dcerpc_server_name ( p ) , d ) ,
" failed to remove printer driver " ) ;
2010-04-23 03:58:02 +04:00
torture_comment ( tctx , " \n " ) ;
2009-07-02 23:49:15 +04:00
return ret ;
}
2010-04-23 03:58:02 +04:00
static bool test_add_driver_ex_64 ( struct torture_context * tctx ,
2010-11-29 15:08:02 +03:00
struct dcerpc_pipe * p )
2009-07-02 23:49:15 +04:00
{
2010-11-29 15:08:02 +03:00
struct torture_driver_context * d ;
d = talloc_zero ( tctx , struct torture_driver_context ) ;
2009-07-02 23:49:15 +04:00
2017-01-10 20:20:18 +03:00
d - > local . environment = talloc_strdup ( d , SPOOLSS_ARCHITECTURE_x64 ) ;
d - > local . driver_directory = talloc_strdup ( d , " /usr/share/cups/drivers/x64 " ) ;
2010-11-29 15:08:02 +03:00
d - > info8 . version = SPOOLSS_DRIVER_VERSION_200X ;
d - > info8 . driver_name = TORTURE_DRIVER_EX ;
2017-01-10 20:20:18 +03:00
d - > info8 . architecture = d - > local . environment ;
2010-11-29 15:08:02 +03:00
d - > info8 . driver_path = talloc_strdup ( d , " pscript5.dll " ) ;
d - > info8 . data_file = talloc_strdup ( d , " cups6.ppd " ) ;
d - > info8 . config_file = talloc_strdup ( d , " cupsui6.dll " ) ;
2010-04-23 03:58:02 +04:00
d - > ex = true ;
2009-07-02 23:49:15 +04:00
2010-04-23 03:58:02 +04:00
return test_add_driver_arg ( tctx , p , d ) ;
}
2009-07-02 23:49:15 +04:00
2010-04-23 03:58:02 +04:00
static bool test_add_driver_ex_32 ( struct torture_context * tctx ,
2010-11-29 15:08:02 +03:00
struct dcerpc_pipe * p )
2010-04-23 03:58:02 +04:00
{
2010-11-29 15:08:02 +03:00
struct torture_driver_context * d ;
d = talloc_zero ( tctx , struct torture_driver_context ) ;
2009-07-02 23:49:15 +04:00
2017-01-10 20:20:18 +03:00
d - > local . environment = talloc_strdup ( d , SPOOLSS_ARCHITECTURE_NT_X86 ) ;
d - > local . driver_directory = talloc_strdup ( d , " /usr/share/cups/drivers/i386 " ) ;
2010-11-29 15:08:02 +03:00
d - > info8 . version = SPOOLSS_DRIVER_VERSION_200X ;
d - > info8 . driver_name = TORTURE_DRIVER_EX ;
2017-01-10 20:20:18 +03:00
d - > info8 . architecture = d - > local . environment ;
2010-11-29 15:08:02 +03:00
d - > info8 . driver_path = talloc_strdup ( d , " pscript5.dll " ) ;
d - > info8 . data_file = talloc_strdup ( d , " cups6.ppd " ) ;
d - > info8 . config_file = talloc_strdup ( d , " cupsui6.dll " ) ;
2010-04-23 03:58:02 +04:00
d - > ex = true ;
2009-07-02 23:49:15 +04:00
2010-04-23 03:58:02 +04:00
return test_add_driver_arg ( tctx , p , d ) ;
}
2009-07-02 23:49:15 +04:00
2010-04-23 03:58:02 +04:00
static bool test_add_driver_64 ( struct torture_context * tctx ,
2010-11-29 15:08:02 +03:00
struct dcerpc_pipe * p )
2010-04-23 03:58:02 +04:00
{
2010-11-29 15:08:02 +03:00
struct torture_driver_context * d ;
2009-07-02 23:49:15 +04:00
2010-11-29 15:08:02 +03:00
d = talloc_zero ( tctx , struct torture_driver_context ) ;
2017-01-10 20:20:18 +03:00
d - > local . environment = talloc_strdup ( d , SPOOLSS_ARCHITECTURE_x64 ) ;
d - > local . driver_directory = talloc_strdup ( d , " /usr/share/cups/drivers/x64 " ) ;
2010-11-29 15:08:02 +03:00
d - > info8 . version = SPOOLSS_DRIVER_VERSION_200X ;
2017-08-08 12:25:48 +03:00
d - > info8 . driver_name = TORTURE_DRIVER_ADD ;
2017-01-10 20:20:18 +03:00
d - > info8 . architecture = d - > local . environment ;
2010-11-29 15:08:02 +03:00
d - > info8 . driver_path = talloc_strdup ( d , " pscript5.dll " ) ;
d - > info8 . data_file = talloc_strdup ( d , " cups6.ppd " ) ;
d - > info8 . config_file = talloc_strdup ( d , " cupsui6.dll " ) ;
2010-04-23 03:58:02 +04:00
d - > ex = false ;
2009-07-02 23:49:15 +04:00
2010-04-23 03:58:02 +04:00
return test_add_driver_arg ( tctx , p , d ) ;
}
2009-07-02 23:49:15 +04:00
2010-04-23 03:58:02 +04:00
static bool test_add_driver_32 ( struct torture_context * tctx ,
2010-11-29 15:08:02 +03:00
struct dcerpc_pipe * p )
2010-04-23 03:58:02 +04:00
{
2010-11-29 15:08:02 +03:00
struct torture_driver_context * d ;
d = talloc_zero ( tctx , struct torture_driver_context ) ;
2009-07-02 23:49:15 +04:00
2017-01-10 20:20:18 +03:00
d - > local . environment = talloc_strdup ( d , SPOOLSS_ARCHITECTURE_NT_X86 ) ;
d - > local . driver_directory = talloc_strdup ( d , " /usr/share/cups/drivers/i386 " ) ;
2010-11-29 15:08:02 +03:00
d - > info8 . version = SPOOLSS_DRIVER_VERSION_200X ;
2017-08-08 12:25:48 +03:00
d - > info8 . driver_name = TORTURE_DRIVER_ADD ;
2017-01-10 20:20:18 +03:00
d - > info8 . architecture = d - > local . environment ;
2010-11-29 15:08:02 +03:00
d - > info8 . driver_path = talloc_strdup ( d , " pscript5.dll " ) ;
d - > info8 . data_file = talloc_strdup ( d , " cups6.ppd " ) ;
d - > info8 . config_file = talloc_strdup ( d , " cupsui6.dll " ) ;
2010-04-23 03:58:02 +04:00
d - > ex = false ;
2010-04-22 20:47:27 +04:00
2010-04-23 03:58:02 +04:00
return test_add_driver_arg ( tctx , p , d ) ;
2009-07-02 23:49:15 +04:00
}
2010-11-29 17:09:52 +03:00
static bool test_add_driver_adobe ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct torture_driver_context * d ;
2012-01-16 19:30:17 +04:00
if ( ! torture_setting_bool ( tctx , " samba3 " , false ) ) {
torture_skip ( tctx , " skipping adobe test which only works against samba3 " ) ;
}
2010-11-29 17:09:52 +03:00
d = talloc_zero ( tctx , struct torture_driver_context ) ;
2017-01-10 20:20:18 +03:00
d - > local . environment = talloc_strdup ( d , " Windows 4.0 " ) ;
d - > local . driver_directory = talloc_strdup ( d , " /usr/share/cups/drivers/adobe/ " ) ;
2010-11-29 17:09:52 +03:00
d - > info8 . version = SPOOLSS_DRIVER_VERSION_9X ;
d - > info8 . driver_name = TORTURE_DRIVER_ADOBE ;
2017-01-10 20:20:18 +03:00
d - > info8 . architecture = d - > local . environment ;
2010-11-29 17:09:52 +03:00
d - > info8 . driver_path = talloc_strdup ( d , " ADOBEPS4.DRV " ) ;
d - > info8 . data_file = talloc_strdup ( d , " DEFPRTR2.PPD " ) ;
d - > info8 . config_file = talloc_strdup ( d , " ADOBEPS4.DRV " ) ;
#if 0
d - > info8 . help_file = talloc_strdup ( d , " ADOBEPS4.HLP " ) ;
d - > info8 . monitor_name = talloc_strdup ( d , " PSMON.DLL " ) ;
# endif
d - > ex = false ;
return test_add_driver_arg ( tctx , p , d ) ;
}
2010-11-29 19:50:05 +03:00
static bool test_add_driver_adobe_cupsaddsmb ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct torture_driver_context * d ;
struct spoolss_StringArray * a ;
2010-11-29 19:59:31 +03:00
if ( ! torture_setting_bool ( tctx , " samba3 " , false ) ) {
torture_skip ( tctx , " skipping cupsaddsmb test which only works against samba3 " ) ;
}
2010-11-29 19:50:05 +03:00
d = talloc_zero ( tctx , struct torture_driver_context ) ;
2017-01-10 20:20:18 +03:00
d - > local . environment = talloc_strdup ( d , " Windows 4.0 " ) ;
d - > local . driver_directory = talloc_strdup ( d , " /usr/share/cups/drivers/adobe/ " ) ;
2010-11-29 19:50:05 +03:00
d - > info8 . version = SPOOLSS_DRIVER_VERSION_9X ;
d - > info8 . driver_name = TORTURE_DRIVER_ADOBE_CUPSADDSMB ;
2017-01-10 20:20:18 +03:00
d - > info8 . architecture = d - > local . environment ;
2010-11-29 19:50:05 +03:00
d - > info8 . driver_path = talloc_strdup ( d , " ADOBEPS4.DRV " ) ;
d - > info8 . data_file = talloc_strdup ( d , " DEFPRTR2.PPD " ) ;
d - > info8 . config_file = NULL ;
d - > info8 . help_file = talloc_strdup ( d , " ADOBEPS4.HLP " ) ;
d - > info8 . monitor_name = talloc_strdup ( d , " PSMON.DLL " ) ;
d - > info8 . default_datatype = talloc_strdup ( d , " RAW " ) ;
a = talloc_zero ( d , struct spoolss_StringArray ) ;
a - > string = talloc_zero_array ( a , const char * , 7 ) ;
a - > string [ 0 ] = talloc_strdup ( a - > string , " ADOBEPS4.DRV " ) ;
a - > string [ 1 ] = talloc_strdup ( a - > string , " DEFPRTR2.PPD " ) ;
a - > string [ 2 ] = talloc_strdup ( a - > string , " ADOBEPS4.HLP " ) ;
a - > string [ 3 ] = talloc_strdup ( a - > string , " PSMON.DLL " ) ;
a - > string [ 4 ] = talloc_strdup ( a - > string , " ADFONTS.MFM " ) ;
a - > string [ 5 ] = talloc_strdup ( a - > string , " ICONLIB.DLL " ) ;
d - > info8 . dependent_files = a ;
d - > ex = false ;
return test_add_driver_arg ( tctx , p , d ) ;
}
2010-12-24 01:50:23 +03:00
static bool test_add_driver_timestamps ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct torture_driver_context * d ;
struct timeval t = timeval_current ( ) ;
d = talloc_zero ( tctx , struct torture_driver_context ) ;
2017-01-10 20:20:18 +03:00
d - > local . environment = talloc_strdup ( d , SPOOLSS_ARCHITECTURE_NT_X86 ) ;
d - > local . driver_directory = talloc_strdup ( d , " /usr/share/cups/drivers/i386 " ) ;
2010-12-24 01:50:23 +03:00
d - > info8 . version = SPOOLSS_DRIVER_VERSION_200X ;
d - > info8 . driver_name = TORTURE_DRIVER_TIMESTAMPS ;
2017-01-10 20:20:18 +03:00
d - > info8 . architecture = d - > local . environment ;
2010-12-24 01:50:23 +03:00
d - > info8 . driver_path = talloc_strdup ( d , " pscript5.dll " ) ;
d - > info8 . data_file = talloc_strdup ( d , " cups6.ppd " ) ;
d - > info8 . config_file = talloc_strdup ( d , " cupsui6.dll " ) ;
d - > info8 . driver_date = timeval_to_nttime ( & t ) ;
d - > ex = true ;
torture_assert ( tctx ,
test_add_driver_arg ( tctx , p , d ) ,
" " ) ;
unix_to_nt_time ( & d - > info8 . driver_date , 1 ) ;
torture_assert ( tctx ,
test_add_driver_arg ( tctx , p , d ) ,
" " ) ;
return true ;
}
2011-02-08 19:16:51 +03:00
static bool test_multiple_drivers ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct torture_driver_context * d ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
const char * server_name_slash = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
int i ;
struct spoolss_AddDriverInfo8 info8 ;
uint32_t add_flags = APD_COPY_NEW_FILES ;
uint32_t delete_flags = 0 ;
d = talloc_zero ( tctx , struct torture_driver_context ) ;
2017-01-10 20:20:18 +03:00
d - > local . environment = talloc_strdup ( d , SPOOLSS_ARCHITECTURE_NT_X86 ) ;
d - > local . driver_directory = talloc_strdup ( d , " /usr/share/cups/drivers/i386 " ) ;
2011-02-08 19:16:51 +03:00
d - > info8 . version = SPOOLSS_DRIVER_VERSION_200X ;
d - > info8 . driver_path = talloc_strdup ( d , " pscript5.dll " ) ;
d - > info8 . data_file = talloc_strdup ( d , " cups6.ppd " ) ;
d - > info8 . config_file = talloc_strdup ( d , " cupsui6.dll " ) ;
2017-01-10 20:20:18 +03:00
d - > info8 . architecture = d - > local . environment ;
2011-02-08 19:16:51 +03:00
d - > ex = true ;
torture_assert ( tctx ,
fillup_printserver_info ( tctx , p , d ) ,
" failed to fillup printserver info " ) ;
if ( ! directory_exist ( d - > local . driver_directory ) ) {
torture_skip ( tctx , " Skipping Printer Driver test as no local driver is available " ) ;
}
torture_assert ( tctx ,
upload_printer_driver ( tctx , dcerpc_server_name ( p ) , d ) ,
" failed to upload printer driver " ) ;
info8 = d - > info8 ;
for ( i = 0 ; i < 3 ; i + + ) {
info8 . driver_name = talloc_asprintf ( d , " torture_test_driver_%d " , i ) ;
torture_assert ( tctx ,
test_AddPrinterDriver_args_level_3 ( tctx , b , server_name_slash , & info8 , add_flags , true , NULL ) ,
" failed to add driver " ) ;
}
torture_assert ( tctx ,
test_DeletePrinterDriverEx ( tctx , b , server_name_slash , " torture_test_driver_0 " , info8 . architecture , delete_flags , info8 . version ) ,
" failed to delete driver " ) ;
torture_assert ( tctx ,
test_EnumPrinterDrivers_findone ( tctx , b , server_name_slash , info8 . architecture , 3 , " torture_test_driver_1 " , NULL ) ,
" torture_test_driver_1 no longer on the server " ) ;
torture_assert ( tctx ,
test_EnumPrinterDrivers_findone ( tctx , b , server_name_slash , info8 . architecture , 3 , " torture_test_driver_2 " , NULL ) ,
" torture_test_driver_2 no longer on the server " ) ;
torture_assert ( tctx ,
test_DeletePrinterDriverEx ( tctx , b , server_name_slash , " torture_test_driver_1 " , info8 . architecture , delete_flags , info8 . version ) ,
" failed to delete driver " ) ;
torture_assert ( tctx ,
test_EnumPrinterDrivers_findone ( tctx , b , server_name_slash , info8 . architecture , 3 , " torture_test_driver_2 " , NULL ) ,
" torture_test_driver_2 no longer on the server " ) ;
torture_assert ( tctx ,
test_DeletePrinterDriverEx ( tctx , b , server_name_slash , " torture_test_driver_2 " , info8 . architecture , delete_flags , info8 . version ) ,
" failed to delete driver " ) ;
torture_assert ( tctx ,
remove_printer_driver ( tctx , dcerpc_server_name ( p ) , d ) ,
" failed to remove printer driver " ) ;
return true ;
}
2016-11-15 20:34:22 +03:00
static bool test_driver_copy_from_directory ( struct torture_context * tctx ,
2017-05-05 12:11:25 +03:00
struct dcerpc_pipe * p ,
const char * architecture )
2016-11-15 20:34:22 +03:00
{
struct torture_driver_context * d ;
struct spoolss_StringArray * a ;
uint32_t add_flags = APD_COPY_NEW_FILES | APD_COPY_FROM_DIRECTORY | APD_RETURN_BLOCKING_STATUS_CODE ;
uint32_t delete_flags = DPD_DELETE_ALL_FILES ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
const char * server_name_slash = talloc_asprintf ( tctx ,
" \\ \\ %s " ,
dcerpc_server_name ( p ) ) ;
struct GUID guid = GUID_random ( ) ;
bool ok = false ;
d = talloc_zero ( tctx , struct torture_driver_context ) ;
torture_assert_not_null ( tctx , d , " ENOMEM " ) ;
2017-05-05 12:11:25 +03:00
d - > local . environment = talloc_strdup ( d , architecture ) ;
2016-11-15 20:34:22 +03:00
torture_assert_not_null_goto ( tctx , d - > local . environment , ok , done , " ENOMEM " ) ;
2017-05-05 12:12:02 +03:00
if ( strequal ( architecture , SPOOLSS_ARCHITECTURE_x64 ) ) {
d - > local . driver_directory =
talloc_strdup ( d , " /usr/share/cups/drivers/x64 " ) ;
} else {
d - > local . driver_directory =
talloc_strdup ( d , " /usr/share/cups/drivers/i386 " ) ;
}
2016-11-15 20:34:22 +03:00
torture_assert_not_null_goto ( tctx , d - > local . driver_directory , ok , done , " ENOMEM " ) ;
d - > remote . driver_upload_directory = GUID_string2 ( d , & guid ) ;
torture_assert_not_null_goto ( tctx , d - > remote . driver_upload_directory , ok , done , " ENOMEM " ) ;
torture_assert ( tctx ,
fillup_printserver_info ( tctx , p , d ) ,
" failed to fillup printserver info " ) ;
d - > ex = true ;
d - > info8 . version = SPOOLSS_DRIVER_VERSION_200X ;
d - > info8 . driver_name = TORTURE_DRIVER_COPY_DIR ;
d - > info8 . architecture = d - > local . environment ;
d - > info8 . driver_path = CREATE_PRINTER_DRIVER_PATH ( d , " pscript5.dll " ) ;
torture_assert_not_null_goto ( tctx , d - > info8 . driver_path , ok , done , " ENOMEM " ) ;
d - > info8 . data_file = CREATE_PRINTER_DRIVER_PATH ( d , " cups6.ppd " ) ;
torture_assert_not_null_goto ( tctx , d - > info8 . data_file , ok , done , " ENOMEM " ) ;
d - > info8 . config_file = CREATE_PRINTER_DRIVER_PATH ( d , " cupsui6.dll " ) ;
torture_assert_not_null_goto ( tctx , d - > info8 . config_file , ok , done , " ENOMEM " ) ;
d - > info8 . help_file = CREATE_PRINTER_DRIVER_PATH ( d , " pscript.hlp " ) ;
torture_assert_not_null_goto ( tctx , d - > info8 . help_file , ok , done , " ENOMEM " ) ;
a = talloc_zero ( d , struct spoolss_StringArray ) ;
torture_assert_not_null_goto ( tctx , a , ok , done , " ENOMEM " ) ;
a - > string = talloc_zero_array ( a , const char * , 3 ) ;
torture_assert_not_null_goto ( tctx , a - > string , ok , done , " ENOMEM " ) ;
a - > string [ 0 ] = CREATE_PRINTER_DRIVER_PATH ( d , " cups6.inf " ) ;
torture_assert_not_null_goto ( tctx , a - > string [ 0 ] , ok , done , " ENOMEM " ) ;
a - > string [ 1 ] = CREATE_PRINTER_DRIVER_PATH ( d , " cups6.ini " ) ;
torture_assert_not_null_goto ( tctx , a - > string [ 1 ] , ok , done , " ENOMEM " ) ;
d - > info8 . dependent_files = a ;
if ( ! directory_exist ( d - > local . driver_directory ) ) {
torture_skip ( tctx ,
" Skipping Printer Driver test as no local drivers "
" are available " ) ;
}
torture_assert ( tctx ,
upload_printer_driver ( tctx , dcerpc_server_name ( p ) , d ) ,
" failed to upload printer driver " ) ;
torture_assert ( tctx ,
test_AddPrinterDriver_args_level_3 ( tctx ,
b ,
server_name_slash ,
& d - > info8 ,
add_flags ,
true ,
NULL ) ,
" failed to add driver " ) ;
torture_assert ( tctx ,
test_DeletePrinterDriverEx ( tctx ,
b ,
server_name_slash ,
d - > info8 . driver_name ,
d - > local . environment ,
delete_flags ,
d - > info8 . version ) ,
" failed to delete driver " ) ;
torture_assert ( tctx ,
check_printer_driver_files ( tctx ,
dcerpc_server_name ( p ) ,
d ,
false ) ,
" printer driver file check failed " ) ;
ok = true ;
done :
talloc_free ( d ) ;
return ok ;
}
2017-05-05 12:11:25 +03:00
static bool test_driver_copy_from_directory_64 ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
return test_driver_copy_from_directory ( tctx , p , SPOOLSS_ARCHITECTURE_x64 ) ;
}
2017-05-05 12:12:02 +03:00
static bool test_driver_copy_from_directory_32 ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
return test_driver_copy_from_directory ( tctx , p , SPOOLSS_ARCHITECTURE_NT_X86 ) ;
}
2012-01-16 19:30:17 +04:00
static bool test_del_driver_all_files ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct torture_driver_context * d ;
struct spoolss_StringArray * a ;
uint32_t add_flags = APD_COPY_NEW_FILES ;
uint32_t delete_flags = DPD_DELETE_ALL_FILES ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
const char * server_name_slash = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
d = talloc_zero ( tctx , struct torture_driver_context ) ;
2017-01-10 20:20:18 +03:00
d - > local . environment = talloc_strdup ( d , SPOOLSS_ARCHITECTURE_x64 ) ;
d - > local . driver_directory = talloc_strdup ( d , " /usr/share/cups/drivers/x64 " ) ;
2012-01-16 19:30:17 +04:00
d - > ex = true ;
d - > info8 . version = SPOOLSS_DRIVER_VERSION_200X ;
d - > info8 . driver_name = TORTURE_DRIVER_DELETER ;
2017-01-10 20:20:18 +03:00
d - > info8 . architecture = d - > local . environment ;
2012-01-16 19:30:17 +04:00
d - > info8 . driver_path = talloc_strdup ( d , " pscript5.dll " ) ;
d - > info8 . data_file = talloc_strdup ( d , " cups6.ppd " ) ;
d - > info8 . config_file = talloc_strdup ( d , " cupsui6.dll " ) ;
d - > info8 . help_file = talloc_strdup ( d , " pscript.hlp " ) ;
a = talloc_zero ( d , struct spoolss_StringArray ) ;
a - > string = talloc_zero_array ( a , const char * , 3 ) ;
a - > string [ 0 ] = talloc_strdup ( a - > string , " cups6.inf " ) ;
a - > string [ 1 ] = talloc_strdup ( a - > string , " cups6.ini " ) ;
d - > info8 . dependent_files = a ;
torture_assert ( tctx ,
fillup_printserver_info ( tctx , p , d ) ,
" failed to fillup printserver info " ) ;
if ( ! directory_exist ( d - > local . driver_directory ) ) {
torture_skip ( tctx , " Skipping Printer Driver test as no local driver is available " ) ;
}
torture_assert ( tctx ,
upload_printer_driver ( tctx , dcerpc_server_name ( p ) , d ) ,
" failed to upload printer driver " ) ;
torture_assert ( tctx ,
test_AddPrinterDriver_args_level_3 ( tctx , b , server_name_slash , & d - > info8 , add_flags , true , NULL ) ,
" failed to add driver " ) ;
torture_assert ( tctx ,
2012-01-17 20:07:01 +04:00
test_DeletePrinterDriverEx ( tctx , b , server_name_slash ,
d - > info8 . driver_name ,
2017-01-10 20:20:18 +03:00
d - > info8 . architecture ,
2012-01-17 20:07:01 +04:00
delete_flags ,
d - > info8 . version ) ,
2012-01-16 19:30:17 +04:00
" failed to delete driver " ) ;
2012-01-17 18:20:51 +04:00
torture_assert ( tctx ,
check_printer_driver_files ( tctx , dcerpc_server_name ( p ) , d , false ) ,
" printer driver file check failed " ) ;
2012-01-16 19:30:17 +04:00
2012-01-17 20:07:01 +04:00
talloc_free ( d ) ;
return true ;
}
static bool test_del_driver_unused_files ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct torture_driver_context * d1 ;
struct torture_driver_context * d2 ;
uint32_t add_flags = APD_COPY_NEW_FILES ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
const char * server_name_slash = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
d1 = talloc_zero ( tctx , struct torture_driver_context ) ;
d1 - > ex = true ;
2017-01-10 20:20:18 +03:00
d1 - > local . environment = talloc_strdup ( d1 , SPOOLSS_ARCHITECTURE_x64 ) ;
d1 - > local . driver_directory = talloc_strdup ( d1 , " /usr/share/cups/drivers/x64 " ) ;
2012-01-17 20:07:01 +04:00
d1 - > info8 . version = SPOOLSS_DRIVER_VERSION_200X ;
d1 - > info8 . driver_name = TORTURE_DRIVER_DELETER ;
d1 - > info8 . architecture = NULL ;
d1 - > info8 . driver_path = talloc_strdup ( d1 , " pscript5.dll " ) ;
d1 - > info8 . data_file = talloc_strdup ( d1 , " cups6.ppd " ) ;
d1 - > info8 . config_file = talloc_strdup ( d1 , " cupsui6.dll " ) ;
d1 - > info8 . help_file = talloc_strdup ( d1 , " pscript.hlp " ) ;
d1 - > info8 . architecture = d1 - > local . environment ;
d2 = talloc_zero ( tctx , struct torture_driver_context ) ;
d2 - > ex = true ;
2017-01-10 20:20:18 +03:00
d2 - > local . environment = talloc_strdup ( d2 , SPOOLSS_ARCHITECTURE_x64 ) ;
d2 - > local . driver_directory = talloc_strdup ( d2 , " /usr/share/cups/drivers/x64 " ) ;
2012-01-17 20:07:01 +04:00
d2 - > info8 . version = SPOOLSS_DRIVER_VERSION_200X ;
d2 - > info8 . driver_name = TORTURE_DRIVER_DELETERIN ;
d2 - > info8 . architecture = NULL ;
d2 - > info8 . driver_path = talloc_strdup ( d2 , " pscript5.dll " ) ; /* overlapping */
d2 - > info8 . data_file = talloc_strdup ( d2 , " cupsps6.dll " ) ;
d2 - > info8 . config_file = talloc_strdup ( d2 , " cups6.ini " ) ;
d2 - > info8 . help_file = talloc_strdup ( d2 , " pscript.hlp " ) ; /* overlapping */
d2 - > info8 . architecture = d2 - > local . environment ;
torture_assert ( tctx ,
fillup_printserver_info ( tctx , p , d1 ) ,
" failed to fillup printserver info " ) ;
torture_assert ( tctx ,
fillup_printserver_info ( tctx , p , d2 ) ,
" failed to fillup printserver info " ) ;
if ( ! directory_exist ( d1 - > local . driver_directory ) ) {
torture_skip ( tctx , " Skipping Printer Driver test as no local driver is available " ) ;
}
torture_assert ( tctx ,
upload_printer_driver ( tctx , dcerpc_server_name ( p ) , d1 ) ,
" failed to upload printer driver " ) ;
torture_assert ( tctx ,
test_AddPrinterDriver_args_level_3 ( tctx , b , server_name_slash , & d1 - > info8 , add_flags , true , NULL ) ,
" failed to add driver " ) ;
torture_assert ( tctx ,
upload_printer_driver ( tctx , dcerpc_server_name ( p ) , d2 ) ,
" failed to upload printer driver " ) ;
torture_assert ( tctx ,
test_AddPrinterDriver_args_level_3 ( tctx , b , server_name_slash , & d2 - > info8 , add_flags , true , NULL ) ,
" failed to add driver " ) ;
/* some files are in use by a separate driver, should fail */
torture_assert ( tctx ,
test_DeletePrinterDriverEx_exp ( tctx , b , server_name_slash ,
d1 - > info8 . driver_name ,
2017-01-10 20:20:18 +03:00
d1 - > info8 . architecture ,
2012-01-17 20:07:01 +04:00
DPD_DELETE_ALL_FILES ,
d1 - > info8 . version ,
WERR_PRINTER_DRIVER_IN_USE ) ,
" invalid delete driver response " ) ;
/* should only delete files not in use by other driver */
torture_assert ( tctx ,
test_DeletePrinterDriverEx_exp ( tctx , b , server_name_slash ,
d1 - > info8 . driver_name ,
2017-01-10 20:20:18 +03:00
d1 - > info8 . architecture ,
2012-01-17 20:07:01 +04:00
DPD_DELETE_UNUSED_FILES ,
d1 - > info8 . version ,
WERR_OK ) ,
" failed to delete driver (unused files) " ) ;
/* check non-overlapping were deleted */
d1 - > info8 . driver_path = NULL ;
d1 - > info8 . help_file = NULL ;
torture_assert ( tctx ,
check_printer_driver_files ( tctx , dcerpc_server_name ( p ) , d1 , false ) ,
" printer driver file check failed " ) ;
/* d2 files should be uneffected */
torture_assert ( tctx ,
check_printer_driver_files ( tctx , dcerpc_server_name ( p ) , d2 , true ) ,
" printer driver file check failed " ) ;
torture_assert ( tctx ,
test_DeletePrinterDriverEx_exp ( tctx , b , server_name_slash ,
d2 - > info8 . driver_name ,
2017-01-10 20:20:18 +03:00
d2 - > info8 . architecture ,
2012-01-17 20:07:01 +04:00
DPD_DELETE_ALL_FILES ,
d2 - > info8 . version ,
WERR_OK ) ,
" failed to delete driver " ) ;
torture_assert ( tctx ,
check_printer_driver_files ( tctx , dcerpc_server_name ( p ) , d2 , false ) ,
" printer driver file check failed " ) ;
talloc_free ( d1 ) ;
talloc_free ( d2 ) ;
2012-01-16 19:30:17 +04:00
return true ;
}
2009-07-02 23:49:15 +04:00
struct torture_suite * torture_rpc_spoolss_driver ( TALLOC_CTX * mem_ctx )
{
2010-12-11 05:26:31 +03:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " spoolss.driver " ) ;
2009-07-02 23:49:15 +04:00
struct torture_rpc_tcase * tcase = torture_suite_add_rpc_iface_tcase ( suite ,
" driver " , & ndr_table_spoolss ) ;
2010-11-29 15:08:02 +03:00
torture_rpc_tcase_add_test ( tcase , " add_driver_64 " , test_add_driver_64 ) ;
torture_rpc_tcase_add_test ( tcase , " add_driver_ex_64 " , test_add_driver_ex_64 ) ;
2010-04-22 20:47:27 +04:00
2010-11-29 15:08:02 +03:00
torture_rpc_tcase_add_test ( tcase , " add_driver_32 " , test_add_driver_32 ) ;
torture_rpc_tcase_add_test ( tcase , " add_driver_ex_32 " , test_add_driver_ex_32 ) ;
2009-07-02 23:49:15 +04:00
2010-11-29 17:09:52 +03:00
torture_rpc_tcase_add_test ( tcase , " add_driver_adobe " , test_add_driver_adobe ) ;
2010-11-29 19:50:05 +03:00
torture_rpc_tcase_add_test ( tcase , " add_driver_adobe_cupsaddsmb " , test_add_driver_adobe_cupsaddsmb ) ;
2010-12-24 01:50:23 +03:00
torture_rpc_tcase_add_test ( tcase , " add_driver_timestamps " , test_add_driver_timestamps ) ;
2011-02-08 19:16:51 +03:00
torture_rpc_tcase_add_test ( tcase , " multiple_drivers " , test_multiple_drivers ) ;
2016-11-15 20:34:22 +03:00
torture_rpc_tcase_add_test ( tcase ,
2017-05-05 12:11:25 +03:00
" test_driver_copy_from_directory_64 " ,
test_driver_copy_from_directory_64 ) ;
2016-11-15 20:34:22 +03:00
2017-05-05 12:12:02 +03:00
torture_rpc_tcase_add_test ( tcase ,
" test_driver_copy_from_directory_32 " ,
test_driver_copy_from_directory_32 ) ;
2012-01-16 19:30:17 +04:00
torture_rpc_tcase_add_test ( tcase , " del_driver_all_files " , test_del_driver_all_files ) ;
2012-01-17 20:07:01 +04:00
torture_rpc_tcase_add_test ( tcase , " del_driver_unused_files " , test_del_driver_unused_files ) ;
2009-07-02 23:49:15 +04:00
return suite ;
}