2010-01-19 16:10:47 +03:00
/*
2007-09-03 17:13:25 +04:00
Unix SMB / CIFS implementation .
test suite for spoolss rpc notify operations
Copyright ( C ) Jelmer Vernooij 2007
2010-01-20 00:18:24 +03:00
Copyright ( C ) Guenther Deschner 2010
2010-01-19 16:10:47 +03:00
2007-09-03 17:13:25 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2008-03-28 09:08:49 +03:00
the Free Software Foundation ; either version 3 of the License , or
2007-09-03 17:13:25 +04:00
( at your option ) any later version .
2010-01-19 16:10:47 +03:00
2007-09-03 17:13:25 +04:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2010-01-19 16:10:47 +03:00
2007-09-03 17:13:25 +04:00
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2009-05-01 20:19:34 +04:00
# include "system/filesys.h"
2007-09-03 17:13:25 +04:00
# include "librpc/gen_ndr/ndr_spoolss_c.h"
2010-01-19 02:22:57 +03:00
# include "librpc/gen_ndr/ndr_spoolss.h"
2010-04-14 00:06:51 +04:00
# include "torture/rpc/torture_rpc.h"
2007-09-03 17:13:25 +04:00
# include "rpc_server/dcerpc_server.h"
2019-01-24 22:03:44 +03:00
# include "rpc_server/dcerpc_server_proto.h"
2009-05-01 20:19:34 +04:00
# include "rpc_server/service_rpc.h"
2020-11-20 17:27:17 +03:00
# include "samba/process_model.h"
2007-09-03 17:13:25 +04:00
# include "smb_server/smb_server.h"
# include "lib/socket/netif.h"
# include "ntvfs/ntvfs.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2007-09-03 17:13:25 +04:00
2021-03-13 18:34:23 +03:00
static struct dcesrv_context_callbacks srv_cb = {
2019-01-24 22:03:44 +03:00
. log . successful_authz = log_successful_dcesrv_authz_event ,
2019-01-24 22:34:03 +03:00
. auth . gensec_prepare = dcesrv_gensec_prepare ,
2022-03-31 13:29:14 +03:00
. assoc_group . find = dcesrv_assoc_group_find_s4 ,
2019-01-24 22:03:44 +03:00
} ;
2018-11-21 22:06:21 +03:00
static NTSTATUS spoolss__op_bind ( struct dcesrv_connection_context * context ,
const struct dcesrv_interface * iface )
2007-09-03 17:13:25 +04:00
{
return NT_STATUS_OK ;
}
static void spoolss__op_unbind ( struct dcesrv_connection_context * context , const struct dcesrv_interface * iface )
{
}
static NTSTATUS spoolss__op_ndr_pull ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct ndr_pull * pull , void * * r )
{
2007-11-09 21:24:51 +03:00
enum ndr_err_code ndr_err ;
2007-09-03 17:13:25 +04:00
uint16_t opnum = dce_call - > pkt . u . request . opnum ;
dce_call - > fault_code = 0 ;
if ( opnum > = ndr_table_spoolss . num_calls ) {
dce_call - > fault_code = DCERPC_FAULT_OP_RNG_ERROR ;
return NT_STATUS_NET_WRITE_FAULT ;
}
* r = talloc_size ( mem_ctx , ndr_table_spoolss . calls [ opnum ] . struct_size ) ;
NT_STATUS_HAVE_NO_MEMORY ( * r ) ;
/* unravel the NDR for the packet */
2007-11-09 21:24:51 +03:00
ndr_err = ndr_table_spoolss . calls [ opnum ] . ndr_pull ( pull , NDR_IN , * r ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2007-09-03 17:13:25 +04:00
dce_call - > fault_code = DCERPC_FAULT_NDR ;
return NT_STATUS_NET_WRITE_FAULT ;
}
return NT_STATUS_OK ;
}
2017-04-25 02:40:37 +03:00
/* Note that received_packets are allocated on the NULL context
2008-01-28 04:49:44 +03:00
* because no other context appears to stay around long enough . */
2007-09-03 17:13:25 +04:00
static struct received_packet {
uint16_t opnum ;
void * r ;
struct received_packet * prev , * next ;
} * received_packets = NULL ;
2017-04-25 02:40:37 +03:00
static void free_received_packets ( void )
{
struct received_packet * rp ;
struct received_packet * rp_next ;
for ( rp = received_packets ; rp ; rp = rp_next ) {
rp_next = rp - > next ;
DLIST_REMOVE ( received_packets , rp ) ;
talloc_unlink ( rp , rp - > r ) ;
talloc_free ( rp ) ;
}
received_packets = NULL ;
}
2010-01-19 02:22:57 +03:00
static WERROR _spoolss_ReplyOpenPrinter ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct spoolss_ReplyOpenPrinter * r )
{
DEBUG ( 1 , ( " _spoolss_ReplyOpenPrinter \n " ) ) ;
NDR_PRINT_IN_DEBUG ( spoolss_ReplyOpenPrinter , r ) ;
r - > out . handle = talloc ( r , struct policy_handle ) ;
r - > out . handle - > handle_type = 42 ;
r - > out . handle - > uuid = GUID_random ( ) ;
r - > out . result = WERR_OK ;
NDR_PRINT_OUT_DEBUG ( spoolss_ReplyOpenPrinter , r ) ;
return WERR_OK ;
}
2007-09-03 17:13:25 +04:00
2010-01-19 02:27:50 +03:00
static WERROR _spoolss_ReplyClosePrinter ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct spoolss_ReplyClosePrinter * r )
{
DEBUG ( 1 , ( " _spoolss_ReplyClosePrinter \n " ) ) ;
NDR_PRINT_IN_DEBUG ( spoolss_ReplyClosePrinter , r ) ;
ZERO_STRUCTP ( r - > out . handle ) ;
r - > out . result = WERR_OK ;
NDR_PRINT_OUT_DEBUG ( spoolss_ReplyClosePrinter , r ) ;
return WERR_OK ;
}
2010-01-31 22:39:36 +03:00
static WERROR _spoolss_RouterReplyPrinterEx ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct spoolss_RouterReplyPrinterEx * r )
{
DEBUG ( 1 , ( " _spoolss_RouterReplyPrinterEx \n " ) ) ;
NDR_PRINT_IN_DEBUG ( spoolss_RouterReplyPrinterEx , r ) ;
r - > out . reply_result = talloc ( r , uint32_t ) ;
* r - > out . reply_result = 0 ;
r - > out . result = WERR_OK ;
NDR_PRINT_OUT_DEBUG ( spoolss_RouterReplyPrinterEx , r ) ;
return WERR_OK ;
}
2007-09-03 17:13:25 +04:00
static NTSTATUS spoolss__op_dispatch ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , void * r )
{
uint16_t opnum = dce_call - > pkt . u . request . opnum ;
struct received_packet * rp ;
2017-04-25 02:40:37 +03:00
rp = talloc_zero ( NULL , struct received_packet ) ;
2007-09-03 17:13:25 +04:00
rp - > opnum = opnum ;
2008-01-28 04:49:44 +03:00
rp - > r = talloc_reference ( rp , r ) ;
2007-09-03 17:13:25 +04:00
2016-02-05 13:32:18 +03:00
DLIST_ADD_END ( received_packets , rp ) ;
2007-09-03 17:13:25 +04:00
switch ( opnum ) {
case 58 : {
struct spoolss_ReplyOpenPrinter * r2 = ( struct spoolss_ReplyOpenPrinter * ) r ;
2010-01-19 02:22:57 +03:00
r2 - > out . result = _spoolss_ReplyOpenPrinter ( dce_call , mem_ctx , r2 ) ;
2007-09-03 17:13:25 +04:00
break ;
}
2010-01-19 02:27:50 +03:00
case 60 : {
struct spoolss_ReplyClosePrinter * r2 = ( struct spoolss_ReplyClosePrinter * ) r ;
r2 - > out . result = _spoolss_ReplyClosePrinter ( dce_call , mem_ctx , r2 ) ;
break ;
}
2010-01-31 22:39:36 +03:00
case 66 : {
struct spoolss_RouterReplyPrinterEx * r2 = ( struct spoolss_RouterReplyPrinterEx * ) r ;
r2 - > out . result = _spoolss_RouterReplyPrinterEx ( dce_call , mem_ctx , r2 ) ;
break ;
}
2007-09-03 17:13:25 +04:00
default :
dce_call - > fault_code = DCERPC_FAULT_OP_RNG_ERROR ;
break ;
}
if ( dce_call - > fault_code ! = 0 ) {
return NT_STATUS_NET_WRITE_FAULT ;
}
return NT_STATUS_OK ;
}
static NTSTATUS spoolss__op_reply ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , void * r )
{
return NT_STATUS_OK ;
}
static NTSTATUS spoolss__op_ndr_push ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct ndr_push * push , const void * r )
{
2007-11-09 21:24:51 +03:00
enum ndr_err_code ndr_err ;
2007-09-03 17:13:25 +04:00
uint16_t opnum = dce_call - > pkt . u . request . opnum ;
2007-11-09 21:24:51 +03:00
ndr_err = ndr_table_spoolss . calls [ opnum ] . ndr_push ( push , NDR_OUT , r ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2007-09-03 17:13:25 +04:00
dce_call - > fault_code = DCERPC_FAULT_NDR ;
return NT_STATUS_NET_WRITE_FAULT ;
}
return NT_STATUS_OK ;
}
2021-01-20 23:10:06 +03:00
static const struct dcesrv_interface notify_test_spoolss_interface = {
2007-09-03 17:13:25 +04:00
. name = " spoolss " ,
. syntax_id = { { 0x12345678 , 0x1234 , 0xabcd , { 0xef , 0x00 } , { 0x01 , 0x23 , 0x45 , 0x67 , 0x89 , 0xab } } , 1.0 } ,
. bind = spoolss__op_bind ,
. unbind = spoolss__op_unbind ,
. ndr_pull = spoolss__op_ndr_pull ,
. dispatch = spoolss__op_dispatch ,
. reply = spoolss__op_reply ,
. ndr_push = spoolss__op_ndr_push
} ;
static bool spoolss__op_interface_by_uuid ( struct dcesrv_interface * iface , const struct GUID * uuid , uint32_t if_version )
{
if ( notify_test_spoolss_interface . syntax_id . if_version = = if_version & &
GUID_equal ( & notify_test_spoolss_interface . syntax_id . uuid , uuid ) ) {
memcpy ( iface , & notify_test_spoolss_interface , sizeof ( * iface ) ) ;
return true ;
}
return false ;
}
static bool spoolss__op_interface_by_name ( struct dcesrv_interface * iface , const char * name )
{
if ( strcmp ( notify_test_spoolss_interface . name , name ) = = 0 ) {
memcpy ( iface , & notify_test_spoolss_interface , sizeof ( * iface ) ) ;
return true ;
}
2010-01-19 16:10:47 +03:00
return false ;
2007-09-03 17:13:25 +04:00
}
static NTSTATUS spoolss__op_init_server ( struct dcesrv_context * dce_ctx , const struct dcesrv_endpoint_server * ep_server )
{
2021-01-20 23:10:35 +03:00
uint32_t i ;
2007-09-03 17:13:25 +04:00
for ( i = 0 ; i < ndr_table_spoolss . endpoints - > count ; i + + ) {
NTSTATUS ret ;
const char * name = ndr_table_spoolss . endpoints - > names [ i ] ;
2018-12-13 00:41:56 +03:00
ret = dcesrv_interface_register ( dce_ctx ,
name ,
NULL ,
& notify_test_spoolss_interface ,
NULL ) ;
2007-09-03 17:13:25 +04:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
DEBUG ( 1 , ( " spoolss_op_init_server: failed to register endpoint '%s' \n " , name ) ) ;
return ret ;
}
}
return NT_STATUS_OK ;
}
2019-09-06 16:16:01 +03:00
static NTSTATUS spoolss__op_shutdown_server ( struct dcesrv_context * dce_ctx ,
const struct dcesrv_endpoint_server * ep_server )
{
return NT_STATUS_OK ;
}
2010-01-20 00:18:24 +03:00
static bool test_OpenPrinter ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
2010-01-31 22:39:36 +03:00
struct policy_handle * handle ,
2011-06-21 17:06:27 +04:00
const char * printername )
2010-01-20 00:18:24 +03:00
{
struct spoolss_OpenPrinter r ;
2010-03-12 12:53:54 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-01-20 00:18:24 +03:00
ZERO_STRUCT ( r ) ;
2010-01-31 22:39:36 +03:00
r . in . printername = printername ;
2010-01-20 00:18:24 +03:00
r . in . datatype = NULL ;
r . in . devmode_ctr . devmode = NULL ;
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
r . out . handle = handle ;
torture_comment ( tctx , " Testing OpenPrinter(%s) \n " , r . in . printername ) ;
2010-03-12 12:53:54 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_OpenPrinter_r ( b , tctx , & r ) ,
2010-01-31 22:39:36 +03:00
" OpenPrinter failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" OpenPrinter failed " ) ;
2010-01-20 00:18:24 +03:00
return true ;
}
2010-01-31 22:30:09 +03:00
static struct spoolss_NotifyOption * setup_printserver_NotifyOption ( struct torture_context * tctx )
{
struct spoolss_NotifyOption * o ;
o = talloc_zero ( tctx , struct spoolss_NotifyOption ) ;
o - > version = 2 ;
o - > flags = PRINTER_NOTIFY_OPTIONS_REFRESH ;
o - > count = 2 ;
o - > types = talloc_zero_array ( o , struct spoolss_NotifyOptionType , o - > count ) ;
o - > types [ 0 ] . type = PRINTER_NOTIFY_TYPE ;
o - > types [ 0 ] . count = 1 ;
o - > types [ 0 ] . fields = talloc_array ( o - > types , union spoolss_Field , o - > types [ 0 ] . count ) ;
o - > types [ 0 ] . fields [ 0 ] . field = PRINTER_NOTIFY_FIELD_SERVER_NAME ;
o - > types [ 1 ] . type = JOB_NOTIFY_TYPE ;
o - > types [ 1 ] . count = 1 ;
o - > types [ 1 ] . fields = talloc_array ( o - > types , union spoolss_Field , o - > types [ 1 ] . count ) ;
o - > types [ 1 ] . fields [ 0 ] . field = JOB_NOTIFY_FIELD_MACHINE_NAME ;
return o ;
}
2014-01-14 19:37:36 +04:00
#if 0
2010-01-31 22:39:36 +03:00
static struct spoolss_NotifyOption * setup_printer_NotifyOption ( struct torture_context * tctx )
{
struct spoolss_NotifyOption * o ;
o = talloc_zero ( tctx , struct spoolss_NotifyOption ) ;
o - > version = 2 ;
o - > flags = PRINTER_NOTIFY_OPTIONS_REFRESH ;
o - > count = 1 ;
o - > types = talloc_zero_array ( o , struct spoolss_NotifyOptionType , o - > count ) ;
o - > types [ 0 ] . type = PRINTER_NOTIFY_TYPE ;
o - > types [ 0 ] . count = 1 ;
o - > types [ 0 ] . fields = talloc_array ( o - > types , union spoolss_Field , o - > types [ 0 ] . count ) ;
o - > types [ 0 ] . fields [ 0 ] . field = PRINTER_NOTIFY_FIELD_COMMENT ;
return o ;
}
2014-01-14 19:37:36 +04:00
# endif
2010-01-31 22:39:36 +03:00
2010-01-20 00:18:24 +03:00
static bool test_RemoteFindFirstPrinterChangeNotifyEx ( struct torture_context * tctx ,
2010-03-12 12:53:54 +03:00
struct dcerpc_binding_handle * b ,
2010-01-20 00:18:24 +03:00
struct policy_handle * handle ,
2010-01-31 22:30:09 +03:00
const char * address ,
struct spoolss_NotifyOption * option )
2007-09-03 17:13:25 +04:00
{
struct spoolss_RemoteFindFirstPrinterChangeNotifyEx r ;
2010-05-20 23:57:53 +04:00
const char * local_machine = talloc_asprintf ( tctx , " \\ \\ %s " , address ) ;
2007-09-03 17:13:25 +04:00
2010-05-20 23:57:53 +04:00
torture_comment ( tctx , " Testing RemoteFindFirstPrinterChangeNotifyEx(%s) \n " , local_machine ) ;
2007-09-03 17:13:25 +04:00
2010-01-20 00:18:24 +03:00
r . in . flags = 0 ;
2010-05-20 23:57:53 +04:00
r . in . local_machine = local_machine ;
2010-01-20 00:18:24 +03:00
r . in . options = 0 ;
2010-01-31 22:30:09 +03:00
r . in . printer_local = 0 ;
r . in . notify_options = option ;
2010-01-20 00:18:24 +03:00
r . in . handle = handle ;
2007-12-13 13:41:47 +03:00
2010-03-12 12:53:54 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_RemoteFindFirstPrinterChangeNotifyEx_r ( b , tctx , & r ) ,
2010-01-20 00:18:24 +03:00
" RemoteFindFirstPrinterChangeNotifyEx failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" error return code for RemoteFindFirstPrinterChangeNotifyEx " ) ;
2007-09-03 17:13:25 +04:00
2010-01-20 00:18:24 +03:00
return true ;
}
2007-09-03 17:13:25 +04:00
2010-01-31 22:31:00 +03:00
static bool test_RouterRefreshPrinterChangeNotify ( struct torture_context * tctx ,
2010-03-12 12:53:54 +03:00
struct dcerpc_binding_handle * b ,
2010-01-31 22:31:00 +03:00
struct policy_handle * handle ,
2011-06-21 17:06:27 +04:00
struct spoolss_NotifyOption * options ,
struct spoolss_NotifyInfo * * info )
2010-01-31 22:31:00 +03:00
{
struct spoolss_RouterRefreshPrinterChangeNotify r ;
torture_comment ( tctx , " Testing RouterRefreshPrinterChangeNotify \n " ) ;
r . in . handle = handle ;
r . in . change_low = 0 ;
r . in . options = options ;
2011-06-21 17:06:27 +04:00
r . out . info = info ;
2010-01-31 22:31:00 +03:00
2010-03-12 12:53:54 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_RouterRefreshPrinterChangeNotify_r ( b , tctx , & r ) ,
2010-01-31 22:31:00 +03:00
" RouterRefreshPrinterChangeNotify failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" error return code for RouterRefreshPrinterChangeNotify " ) ;
return true ;
}
2014-01-14 19:37:36 +04:00
#if 0
2010-01-31 22:39:36 +03:00
static bool test_SetPrinter ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct policy_handle * handle )
{
2010-02-10 02:43:51 +03:00
union spoolss_PrinterInfo info ;
2010-01-31 22:39:36 +03:00
struct spoolss_SetPrinter r ;
struct spoolss_SetPrinterInfo2 info2 ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
2010-03-12 12:53:54 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-01-31 22:39:36 +03:00
2010-03-12 12:53:54 +03:00
torture_assert ( tctx , test_GetPrinter_level ( tctx , b , handle , 2 , & info ) , " " ) ;
2010-01-31 22:39:36 +03:00
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
2010-02-10 02:43:51 +03:00
info2 . servername = info . info2 . servername ;
info2 . printername = info . info2 . printername ;
info2 . sharename = info . info2 . sharename ;
info2 . portname = info . info2 . portname ;
info2 . drivername = info . info2 . drivername ;
2010-01-31 22:39:36 +03:00
info2 . comment = talloc_asprintf ( tctx , " torture_comment %d \n " , ( int ) time ( NULL ) ) ;
2010-02-10 02:43:51 +03:00
info2 . location = info . info2 . location ;
2016-11-11 18:29:20 +03:00
info2 . devmode_ptr = 0 ;
2010-02-10 02:43:51 +03:00
info2 . sepfile = info . info2 . sepfile ;
info2 . printprocessor = info . info2 . printprocessor ;
info2 . datatype = info . info2 . datatype ;
info2 . parameters = info . info2 . parameters ;
2016-11-11 18:29:20 +03:00
info2 . secdesc_ptr = 0 ;
2010-02-10 02:43:51 +03:00
info2 . attributes = info . info2 . attributes ;
info2 . priority = info . info2 . priority ;
info2 . defaultpriority = info . info2 . defaultpriority ;
info2 . starttime = info . info2 . starttime ;
info2 . untiltime = info . info2 . untiltime ;
info2 . status = info . info2 . status ;
info2 . cjobs = info . info2 . cjobs ;
info2 . averageppm = info . info2 . averageppm ;
2010-01-31 22:39:36 +03:00
info_ctr . level = 2 ;
info_ctr . info . info2 = & info2 ;
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 ;
2010-03-12 12:53:54 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_SetPrinter_r ( b , tctx , & r ) , " SetPrinter failed " ) ;
2010-01-31 22:39:36 +03:00
torture_assert_werr_ok ( tctx , r . out . result , " SetPrinter failed " ) ;
return true ;
}
2014-01-14 19:37:36 +04:00
# endif
2010-01-31 22:39:36 +03:00
2010-01-20 00:18:24 +03:00
static bool test_start_dcerpc_server ( struct torture_context * tctx ,
struct tevent_context * event_ctx ,
struct dcesrv_context * * dce_ctx_p ,
const char * * address_p )
{
struct dcesrv_endpoint_server ep_server ;
NTSTATUS status ;
struct dcesrv_context * dce_ctx ;
const char * endpoints [ ] = { " spoolss " , NULL } ;
struct dcesrv_endpoint * e ;
const char * address ;
struct interface * ifaces ;
ntvfs_init ( tctx - > lp_ctx ) ;
2007-09-03 17:13:25 +04:00
/* fill in our name */
ep_server . name = " spoolss " ;
2019-09-06 15:38:29 +03:00
ep_server . initialized = false ;
2007-09-03 17:13:25 +04:00
/* fill in all the operations */
ep_server . init_server = spoolss__op_init_server ;
2019-09-06 16:16:01 +03:00
ep_server . shutdown_server = spoolss__op_shutdown_server ;
2007-09-03 17:13:25 +04:00
ep_server . interface_by_uuid = spoolss__op_interface_by_uuid ;
ep_server . interface_by_name = spoolss__op_interface_by_name ;
torture_assert_ntstatus_ok ( tctx , dcerpc_register_ep_server ( & ep_server ) ,
" unable to register spoolss server " ) ;
2010-07-16 08:32:42 +04:00
lpcfg_set_cmdline ( tctx - > lp_ctx , " dcerpc endpoint servers " , " spoolss " ) ;
2007-09-03 17:13:25 +04:00
2011-06-02 09:40:28 +04:00
load_interface_list ( tctx , tctx - > lp_ctx , & ifaces ) ;
2011-06-20 20:01:38 +04:00
address = iface_list_first_v4 ( ifaces ) ;
2010-01-20 00:18:24 +03:00
2007-09-03 17:13:25 +04:00
torture_comment ( tctx , " Listening for callbacks on %s \n " , address ) ;
2010-01-20 00:18:24 +03:00
2010-10-30 16:42:27 +04:00
status = process_model_init ( tctx - > lp_ctx ) ;
torture_assert_ntstatus_ok ( tctx , status ,
" unable to initialize process models " ) ;
2017-09-14 22:09:23 +03:00
status = smbsrv_add_socket ( tctx , event_ctx , tctx - > lp_ctx ,
process_model_startup ( " single " ) ,
address , NULL ) ;
2007-09-03 17:13:25 +04:00
torture_assert_ntstatus_ok ( tctx , status , " starting smb server " ) ;
2019-02-05 20:54:02 +03:00
status = dcesrv_init_context ( tctx , tctx - > lp_ctx , & srv_cb , & dce_ctx ) ;
2010-01-19 16:10:47 +03:00
torture_assert_ntstatus_ok ( tctx , status ,
2007-09-03 17:13:25 +04:00
" unable to initialize DCE/RPC server " ) ;
2019-02-05 20:54:02 +03:00
status = dcesrv_init_ep_servers ( dce_ctx , endpoints ) ;
torture_assert_ntstatus_ok ( tctx ,
status ,
" unable to initialize DCE/RPC ep servers " ) ;
2009-05-01 20:19:34 +04:00
for ( e = dce_ctx - > endpoint_list ; e ; e = e - > next ) {
status = dcesrv_add_ep ( dce_ctx , tctx - > lp_ctx ,
2017-09-14 22:09:23 +03:00
e , tctx - > ev ,
process_model_startup ( " single " ) , NULL ) ;
2009-05-01 20:19:34 +04:00
torture_assert_ntstatus_ok ( tctx , status ,
" unable listen on dcerpc endpoint server " ) ;
}
2010-01-20 00:18:24 +03:00
* dce_ctx_p = dce_ctx ;
* address_p = address ;
2007-09-03 17:13:25 +04:00
2010-01-20 00:18:24 +03:00
return true ;
}
2007-09-03 17:13:25 +04:00
2010-01-27 17:04:00 +03:00
static struct received_packet * last_packet ( struct received_packet * p )
{
struct received_packet * tmp ;
2017-11-19 08:20:57 +03:00
for ( tmp = p ; tmp - > next ; tmp = tmp - > next ) {
}
2010-01-27 17:04:00 +03:00
return tmp ;
}
2010-01-20 00:18:24 +03:00
static bool test_RFFPCNEx ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct dcesrv_context * dce_ctx ;
struct policy_handle handle ;
const char * address ;
2010-01-27 17:04:00 +03:00
struct received_packet * tmp ;
2010-01-31 22:30:09 +03:00
struct spoolss_NotifyOption * server_option = setup_printserver_NotifyOption ( tctx ) ;
2010-03-12 12:53:15 +03:00
#if 0
2010-01-31 22:39:36 +03:00
struct spoolss_NotifyOption * printer_option = setup_printer_NotifyOption ( tctx ) ;
2010-03-12 12:53:15 +03:00
# endif
2010-03-12 12:53:54 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2011-06-21 17:06:27 +04:00
const char * printername = NULL ;
struct spoolss_NotifyInfo * info = NULL ;
2010-01-19 02:27:50 +03:00
2017-04-25 02:40:37 +03:00
free_received_packets ( ) ;
2010-01-19 02:27:50 +03:00
2010-01-20 00:18:24 +03:00
/* Start DCE/RPC server */
2014-01-14 15:30:44 +04:00
torture_assert ( tctx , test_start_dcerpc_server ( tctx , tctx - > ev , & dce_ctx , & address ) , " " ) ;
2010-01-20 00:18:24 +03:00
2011-06-21 17:06:27 +04:00
printername = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
torture_assert ( tctx , test_OpenPrinter ( tctx , p , & handle , printername ) , " " ) ;
2010-03-12 12:53:54 +03:00
torture_assert ( tctx , test_RemoteFindFirstPrinterChangeNotifyEx ( tctx , b , & handle , address , server_option ) , " " ) ;
2010-01-20 00:18:24 +03:00
torture_assert ( tctx , received_packets , " no packets received " ) ;
torture_assert_int_equal ( tctx , received_packets - > opnum , NDR_SPOOLSS_REPLYOPENPRINTER ,
" no ReplyOpenPrinter packet after RemoteFindFirstPrinterChangeNotifyEx " ) ;
2011-06-21 17:06:27 +04:00
torture_assert ( tctx , test_RouterRefreshPrinterChangeNotify ( tctx , b , & handle , NULL , & info ) , " " ) ;
torture_assert ( tctx , test_RouterRefreshPrinterChangeNotify ( tctx , b , & handle , server_option , & info ) , " " ) ;
2010-03-12 12:53:54 +03:00
torture_assert ( tctx , test_ClosePrinter ( tctx , b , & handle ) , " " ) ;
2010-01-27 17:04:00 +03:00
tmp = last_packet ( received_packets ) ;
torture_assert_int_equal ( tctx , tmp - > opnum , NDR_SPOOLSS_REPLYCLOSEPRINTER ,
2010-01-20 00:18:24 +03:00
" no ReplyClosePrinter packet after ClosePrinter " ) ;
2010-01-31 22:39:36 +03:00
#if 0
2011-06-21 17:06:27 +04:00
printername = talloc_asprintf ( tctx , " \\ \\ %s \\ %s " , dcerpc_server_name ( p ) , name ) ;
2010-01-31 22:39:36 +03:00
torture_assert ( tctx , test_OpenPrinter ( tctx , p , & handle , " Epson AL-2600 " ) , " " ) ;
torture_assert ( tctx , test_RemoteFindFirstPrinterChangeNotifyEx ( tctx , p , & handle , address , printer_option ) , " " ) ;
tmp = last_packet ( received_packets ) ;
torture_assert_int_equal ( tctx , tmp - > opnum , NDR_SPOOLSS_REPLYOPENPRINTER ,
" no ReplyOpenPrinter packet after RemoteFindFirstPrinterChangeNotifyEx " ) ;
2011-06-21 17:06:27 +04:00
torture_assert ( tctx , test_RouterRefreshPrinterChangeNotify ( tctx , p , & handle , NULL , & info ) , " " ) ;
torture_assert ( tctx , test_RouterRefreshPrinterChangeNotify ( tctx , p , & handle , printer_option , & info ) , " " ) ;
2010-01-31 22:39:36 +03:00
torture_assert ( tctx , test_SetPrinter ( tctx , p , & handle ) , " " ) ;
tmp = last_packet ( received_packets ) ;
torture_assert_int_equal ( tctx , tmp - > opnum , NDR_SPOOLSS_ROUTERREPLYPRINTEREX ,
" no RouterReplyPrinterEx packet after ClosePrinter " ) ;
torture_assert ( tctx , test_ClosePrinter ( tctx , p , & handle ) , " " ) ;
tmp = last_packet ( received_packets ) ;
torture_assert_int_equal ( tctx , tmp - > opnum , NDR_SPOOLSS_REPLYCLOSEPRINTER ,
" no ReplyClosePrinter packet after ClosePrinter " ) ;
# endif
2007-09-03 17:13:25 +04:00
/* Shut down DCE/RPC server */
talloc_free ( dce_ctx ) ;
2017-04-25 02:40:37 +03:00
free_received_packets ( ) ;
2007-09-03 17:13:25 +04:00
return true ;
}
2009-04-13 19:05:12 +04:00
/** Test that makes sure that calling ReplyOpenPrinter()
* on Samba 4 will cause an irpc broadcast call .
*/
static bool test_ReplyOpenPrinter ( struct torture_context * tctx ,
2009-05-01 20:20:53 +04:00
struct dcerpc_pipe * p )
2009-04-13 19:05:12 +04:00
{
struct spoolss_ReplyOpenPrinter r ;
struct spoolss_ReplyClosePrinter s ;
struct policy_handle h ;
2010-03-12 12:53:54 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-04-13 19:05:12 +04:00
2010-01-19 02:19:47 +03:00
if ( torture_setting_bool ( tctx , " samba3 " , false ) ) {
torture_skip ( tctx , " skipping ReplyOpenPrinter server implementation test against s3 \n " ) ;
}
2009-04-13 19:05:12 +04:00
r . in . server_name = " earth " ;
r . in . printer_local = 2 ;
r . in . type = REG_DWORD ;
r . in . bufsize = 0 ;
r . in . buffer = NULL ;
r . out . handle = & h ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-12 12:53:54 +03:00
dcerpc_spoolss_ReplyOpenPrinter_r ( b , tctx , & r ) ,
2009-04-13 19:05:12 +04:00
" spoolss_ReplyOpenPrinter call failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " error return code " ) ;
s . in . handle = & h ;
s . out . handle = & h ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-12 12:53:54 +03:00
dcerpc_spoolss_ReplyClosePrinter_r ( b , tctx , & s ) ,
2009-04-13 19:05:12 +04:00
" spoolss_ReplyClosePrinter call failed " ) ;
torture_assert_werr_ok ( tctx , r . out . result , " error return code " ) ;
return true ;
}
2007-09-03 17:13:25 +04:00
struct torture_suite * torture_rpc_spoolss_notify ( TALLOC_CTX * mem_ctx )
{
2010-12-11 05:26:31 +03:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " spoolss.notify " ) ;
2010-01-19 16:10:47 +03:00
struct torture_rpc_tcase * tcase = torture_suite_add_rpc_iface_tcase ( suite ,
2007-09-03 17:13:25 +04:00
" notify " , & ndr_table_spoolss ) ;
torture_rpc_tcase_add_test ( tcase , " testRFFPCNEx " , test_RFFPCNEx ) ;
2009-04-13 19:05:12 +04:00
torture_rpc_tcase_add_test ( tcase , " testReplyOpenPrinter " , test_ReplyOpenPrinter ) ;
2010-01-19 16:10:47 +03:00
2007-09-03 17:13:25 +04:00
return suite ;
}