2010-06-04 21:03:11 +04:00
/*
Unix SMB / CIFS implementation .
test suite for spoolss rpc operations
Copyright ( C ) Guenther Deschner 2010
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "torture/torture.h"
# include "librpc/gen_ndr/ndr_misc.h"
# include "librpc/gen_ndr/ndr_spoolss.h"
# include "librpc/gen_ndr/ndr_spoolss_c.h"
# include "librpc/gen_ndr/ndr_samr_c.h"
# include "librpc/gen_ndr/ndr_lsa_c.h"
# include "librpc/gen_ndr/ndr_security.h"
# include "libcli/security/security.h"
# include "torture/rpc/torture_rpc.h"
# include "param/param.h"
2020-12-02 19:24:22 +03:00
# include "lib/cmdline/cmdline.h"
2010-06-04 21:03:11 +04:00
# define TORTURE_USER "torture_user"
# define TORTURE_USER_ADMINGROUP "torture_user_544"
# define TORTURE_USER_PRINTOPGROUP "torture_user_550"
# define TORTURE_USER_PRINTOPPRIV "torture_user_priv"
# define TORTURE_USER_SD "torture_user_sd"
2010-06-07 14:41:39 +04:00
# define TORTURE_WORKSTATION "torture_workstation"
2010-06-04 21:03:11 +04:00
struct torture_user {
const char * username ;
void * testuser ;
uint32_t * builtin_memberships ;
uint32_t num_builtin_memberships ;
const char * * privs ;
uint32_t num_privs ;
bool privs_present ;
bool sd ;
2010-06-08 14:26:15 +04:00
bool admin_rights ;
bool system_security ;
2010-06-04 21:03:11 +04:00
} ;
struct torture_access_context {
struct dcerpc_pipe * spoolss_pipe ;
const char * printername ;
struct security_descriptor * sd_orig ;
struct torture_user user ;
} ;
static bool test_openprinter_handle ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
2010-06-08 14:26:15 +04:00
const char * name ,
2010-06-04 21:03:11 +04:00
const char * printername ,
const char * username ,
uint32_t access_mask ,
2010-06-08 14:26:15 +04:00
WERROR expected_result ,
2010-06-04 21:03:11 +04:00
struct policy_handle * handle )
{
struct spoolss_OpenPrinterEx r ;
struct spoolss_UserLevel1 level1 ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
level1 . size = 28 ;
level1 . client = talloc_asprintf ( tctx , " \\ \\ %s " , " smbtorture " ) ;
level1 . user = username ;
2018-08-31 22:28:36 +03:00
/* Windows 7 and Windows Server 2008 R2 */
level1 . build = 7007 ;
level1 . major = 6 ;
level1 . minor = 1 ;
2010-06-04 21:03:11 +04:00
level1 . processor = 0 ;
r . in . printername = printername ;
r . in . datatype = NULL ;
r . in . devmode_ctr . devmode = NULL ;
r . in . access_mask = access_mask ;
2013-01-14 20:26:31 +04:00
r . in . userlevel_ctr . level = 1 ;
r . in . userlevel_ctr . user_info . level1 = & level1 ;
2010-06-04 21:03:11 +04:00
r . out . handle = handle ;
2010-06-08 14:26:15 +04:00
torture_comment ( tctx , " Testing OpenPrinterEx(%s) with access_mask 0x%08x (%s) \n " ,
r . in . printername , r . in . access_mask , name ) ;
2010-06-04 21:03:11 +04:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_OpenPrinterEx_r ( b , tctx , & r ) ,
" OpenPrinterEx failed " ) ;
2010-06-08 14:26:15 +04:00
torture_assert_werr_equal ( tctx , r . out . result , expected_result ,
talloc_asprintf ( tctx , " OpenPrinterEx(%s) as '%s' with access_mask: 0x%08x (%s) failed " ,
r . in . printername , username , r . in . access_mask , name ) ) ;
2010-06-04 21:03:11 +04:00
return true ;
}
static bool test_openprinter_access ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
2010-06-08 14:26:15 +04:00
const char * name ,
2010-06-04 21:03:11 +04:00
const char * printername ,
const char * username ,
2010-06-08 14:26:15 +04:00
uint32_t access_mask ,
WERROR expected_result )
2010-06-04 21:03:11 +04:00
{
struct policy_handle handle ;
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-06-08 14:26:15 +04:00
bool ret = true ;
2010-06-04 21:03:11 +04:00
2010-06-08 14:26:15 +04:00
ZERO_STRUCT ( handle ) ;
if ( printername = = NULL ) {
torture_comment ( tctx , " skipping test %s as there is no printer \n " , name ) ;
2010-06-04 21:03:11 +04:00
return true ;
}
2010-06-08 14:26:15 +04:00
ret = test_openprinter_handle ( tctx , p , name , printername , username , access_mask , expected_result , & handle ) ;
if ( is_valid_policy_hnd ( & handle ) ) {
test_ClosePrinter ( tctx , b , & handle ) ;
}
return ret ;
2010-06-04 21:03:11 +04:00
}
static bool spoolss_access_setup_membership ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
uint32_t num_members ,
uint32_t * members ,
struct dom_sid * user_sid )
{
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct policy_handle connect_handle , domain_handle ;
int i ;
2010-09-22 22:04:38 +04:00
torture_comment ( tctx ,
" Setting up BUILTIN membership for %s \n " ,
dom_sid_string ( tctx , user_sid ) ) ;
for ( i = 0 ; i < num_members ; i + + ) {
torture_comment ( tctx , " adding user to S-1-5-32-%d \n " , members [ i ] ) ;
}
2010-06-04 21:03:11 +04:00
{
struct samr_Connect2 r ;
r . in . system_name = " " ;
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
r . out . connect_handle = & connect_handle ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_samr_Connect2_r ( b , tctx , & r ) ,
" samr_Connect2 failed " ) ;
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" samr_Connect2 failed " ) ;
}
{
struct samr_OpenDomain r ;
r . in . connect_handle = & connect_handle ;
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
r . in . sid = dom_sid_parse_talloc ( tctx , " S-1-5-32 " ) ;
r . out . domain_handle = & domain_handle ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_samr_OpenDomain_r ( b , tctx , & r ) ,
" samr_OpenDomain failed " ) ;
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" samr_OpenDomain failed " ) ;
}
for ( i = 0 ; i < num_members ; i + + ) {
struct policy_handle alias_handle ;
{
struct samr_OpenAlias r ;
r . in . domain_handle = & domain_handle ;
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
r . in . rid = members [ i ] ;
r . out . alias_handle = & alias_handle ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_samr_OpenAlias_r ( b , tctx , & r ) ,
" samr_OpenAlias failed " ) ;
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" samr_OpenAlias failed " ) ;
}
{
struct samr_AddAliasMember r ;
r . in . alias_handle = & alias_handle ;
r . in . sid = user_sid ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_samr_AddAliasMember_r ( b , tctx , & r ) ,
" samr_AddAliasMember failed " ) ;
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" samr_AddAliasMember failed " ) ;
}
test_samr_handle_Close ( b , tctx , & alias_handle ) ;
}
test_samr_handle_Close ( b , tctx , & domain_handle ) ;
test_samr_handle_Close ( b , tctx , & connect_handle ) ;
return true ;
}
static void init_lsa_StringLarge ( struct lsa_StringLarge * name , const char * s )
{
name - > string = s ;
}
static void init_lsa_String ( struct lsa_String * name , const char * s )
{
name - > string = s ;
}
static bool spoolss_access_setup_privs ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
uint32_t num_privs ,
const char * * privs ,
struct dom_sid * user_sid ,
bool * privs_present )
{
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct policy_handle * handle ;
int i ;
torture_assert ( tctx ,
test_lsa_OpenPolicy2 ( b , tctx , & handle ) ,
" failed to open policy " ) ;
for ( i = 0 ; i < num_privs ; i + + ) {
struct lsa_LookupPrivValue r ;
struct lsa_LUID luid ;
struct lsa_String name ;
init_lsa_String ( & name , privs [ i ] ) ;
r . in . handle = handle ;
r . in . name = & name ;
r . out . luid = & luid ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_lsa_LookupPrivValue_r ( b , tctx , & r ) ,
" lsa_LookupPrivValue failed " ) ;
if ( ! NT_STATUS_IS_OK ( r . out . result ) ) {
torture_comment ( tctx , " lsa_LookupPrivValue failed for '%s' with %s \n " ,
privs [ i ] , nt_errstr ( r . out . result ) ) ;
* privs_present = false ;
return true ;
}
}
* privs_present = true ;
{
struct lsa_AddAccountRights r ;
struct lsa_RightSet rights ;
rights . count = num_privs ;
rights . names = talloc_zero_array ( tctx , struct lsa_StringLarge , rights . count ) ;
for ( i = 0 ; i < rights . count ; i + + ) {
init_lsa_StringLarge ( & rights . names [ i ] , privs [ i ] ) ;
}
r . in . handle = handle ;
r . in . sid = user_sid ;
r . in . rights = & rights ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_lsa_AddAccountRights_r ( b , tctx , & r ) ,
" lsa_AddAccountRights failed " ) ;
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" lsa_AddAccountRights failed " ) ;
}
test_lsa_Close ( b , tctx , handle ) ;
return true ;
}
static bool test_SetPrinter ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
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 ;
torture_comment ( tctx , " Testing SetPrinter level %d \n " , r . in . info_ctr - > level ) ;
torture_assert_ntstatus_ok ( tctx , dcerpc_spoolss_SetPrinter_r ( b , tctx , & r ) ,
" failed to call SetPrinter " ) ;
torture_assert_werr_ok ( tctx , r . out . result ,
" failed to call SetPrinter " ) ;
return true ;
}
static bool spoolss_access_setup_sd ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
const char * printername ,
2010-08-27 00:48:27 +04:00
const struct dom_sid * user_sid ,
2010-06-04 21:03:11 +04:00
struct security_descriptor * * sd_orig )
{
struct dcerpc_binding_handle * b = p - > binding_handle ;
struct policy_handle 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_ace * ace ;
struct security_descriptor * sd ;
torture_assert ( tctx ,
2010-06-08 14:26:15 +04:00
test_openprinter_handle ( tctx , p , " " , printername , " " , SEC_FLAG_MAXIMUM_ALLOWED , WERR_OK , & handle ) ,
2010-06-04 21:03:11 +04:00
" failed to open printer " ) ;
torture_assert ( tctx ,
test_GetPrinter_level ( tctx , b , & handle , 3 , & info ) ,
" failed to get sd " ) ;
sd = security_descriptor_copy ( tctx , info . info3 . secdesc ) ;
* sd_orig = security_descriptor_copy ( tctx , info . info3 . secdesc ) ;
ace = talloc_zero ( tctx , struct security_ace ) ;
ace - > type = SEC_ACE_TYPE_ACCESS_ALLOWED ;
ace - > flags = 0 ;
ace - > access_mask = PRINTER_ALL_ACCESS ;
ace - > trustee = * user_sid ;
torture_assert_ntstatus_ok ( tctx ,
security_descriptor_dacl_add ( sd , ace ) ,
" failed to add new ace " ) ;
ace = talloc_zero ( tctx , struct security_ace ) ;
ace - > type = SEC_ACE_TYPE_ACCESS_ALLOWED ;
ace - > flags = SEC_ACE_FLAG_OBJECT_INHERIT |
SEC_ACE_FLAG_CONTAINER_INHERIT |
SEC_ACE_FLAG_INHERIT_ONLY ;
ace - > access_mask = SEC_GENERIC_ALL ;
ace - > trustee = * user_sid ;
torture_assert_ntstatus_ok ( tctx ,
security_descriptor_dacl_add ( sd , ace ) ,
" failed to add new ace " ) ;
ZERO_STRUCT ( info3 ) ;
ZERO_STRUCT ( info_ctr ) ;
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
info_ctr . level = 3 ;
info_ctr . info . info3 = & info3 ;
secdesc_ctr . sd = sd ;
torture_assert ( tctx ,
test_SetPrinter ( tctx , b , & handle , & info_ctr , & devmode_ctr , & secdesc_ctr , 0 ) ,
" failed to set sd " ) ;
return true ;
}
static bool test_EnumPrinters_findone ( struct torture_context * tctx ,
2010-06-05 03:26:49 +04:00
struct dcerpc_pipe * p ,
2010-06-04 21:03:11 +04:00
const char * * printername )
{
struct spoolss_EnumPrinters r ;
uint32_t count ;
union spoolss_PrinterInfo * info ;
uint32_t needed ;
int i ;
2010-06-05 03:26:49 +04:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-06-04 21:03:11 +04:00
* printername = NULL ;
r . in . flags = PRINTER_ENUM_LOCAL ;
2010-11-24 12:57:09 +03:00
r . in . server = NULL ;
2010-06-04 21:03:11 +04:00
r . in . level = 1 ;
r . in . buffer = NULL ;
r . in . offered = 0 ;
r . out . count = & count ;
r . out . info = & info ;
r . out . needed = & needed ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_spoolss_EnumPrinters_r ( b , tctx , & r ) ,
" failed to enum printers " ) ;
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 ) ,
" failed to enum printers " ) ;
}
torture_assert_werr_ok ( tctx , r . out . result ,
" failed to enum printers " ) ;
for ( i = 0 ; i < count ; i + + ) {
2010-11-24 12:57:09 +03:00
if ( count > 1 & & strequal ( info [ i ] . info1 . name , " Microsoft XPS Document Writer " ) ) {
continue ;
}
torture_comment ( tctx , " testing printer: %s \n " ,
info [ i ] . info1 . name ) ;
2010-06-04 21:03:11 +04:00
* printername = talloc_strdup ( tctx , info [ i ] . info1 . name ) ;
break ;
}
return true ;
}
static bool torture_rpc_spoolss_access_setup_common ( struct torture_context * tctx , struct torture_access_context * t )
{
void * testuser ;
const char * testuser_passwd ;
struct cli_credentials * test_credentials ;
struct dom_sid * test_sid ;
struct dcerpc_pipe * p ;
const char * printername ;
const char * binding = torture_setting_string ( tctx , " binding " , NULL ) ;
2010-06-07 14:41:39 +04:00
struct dcerpc_pipe * spoolss_pipe ;
2010-06-04 21:03:11 +04:00
2010-06-05 03:26:49 +04:00
testuser = torture_create_testuser_max_pwlen ( tctx , t - > user . username ,
torture_setting_string ( tctx , " workgroup " , NULL ) ,
ACB_NORMAL ,
& testuser_passwd ,
32 ) ;
2010-06-04 21:03:11 +04:00
if ( ! testuser ) {
torture_fail ( tctx , " Failed to create test user " ) ;
}
test_credentials = cli_credentials_init ( tctx ) ;
cli_credentials_set_workstation ( test_credentials , " localhost " , CRED_SPECIFIED ) ;
2010-07-16 08:32:42 +04:00
cli_credentials_set_domain ( test_credentials , lpcfg_workgroup ( tctx - > lp_ctx ) ,
2010-06-04 21:03:11 +04:00
CRED_SPECIFIED ) ;
cli_credentials_set_username ( test_credentials , t - > user . username , CRED_SPECIFIED ) ;
cli_credentials_set_password ( test_credentials , testuser_passwd , CRED_SPECIFIED ) ;
2010-08-27 00:48:27 +04:00
test_sid = discard_const_p ( struct dom_sid ,
torture_join_user_sid ( testuser ) ) ;
2010-06-04 21:03:11 +04:00
if ( t - > user . num_builtin_memberships ) {
struct dcerpc_pipe * samr_pipe = torture_join_samr_pipe ( testuser ) ;
torture_assert ( tctx ,
spoolss_access_setup_membership ( tctx , samr_pipe ,
t - > user . num_builtin_memberships ,
t - > user . builtin_memberships ,
test_sid ) ,
" failed to setup membership " ) ;
}
if ( t - > user . num_privs ) {
struct dcerpc_pipe * lsa_pipe ;
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection ( tctx , & lsa_pipe , & ndr_table_lsarpc ) ,
" Error connecting to server " ) ;
torture_assert ( tctx ,
spoolss_access_setup_privs ( tctx , lsa_pipe ,
t - > user . num_privs ,
t - > user . privs ,
test_sid ,
& t - > user . privs_present ) ,
" failed to setup privs " ) ;
talloc_free ( lsa_pipe ) ;
}
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection ( tctx , & spoolss_pipe , & ndr_table_spoolss ) ,
" Error connecting to server " ) ;
torture_assert ( tctx ,
2010-06-05 03:26:49 +04:00
test_EnumPrinters_findone ( tctx , spoolss_pipe , & printername ) ,
2010-06-04 21:03:11 +04:00
" failed to enumerate printers " ) ;
2010-06-07 13:21:26 +04:00
if ( t - > user . sd & & printername ) {
2010-06-04 21:03:11 +04:00
torture_assert ( tctx ,
spoolss_access_setup_sd ( tctx , spoolss_pipe ,
printername ,
test_sid ,
& t - > sd_orig ) ,
" failed to setup sd " ) ;
}
talloc_free ( spoolss_pipe ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_pipe_connect ( tctx , & p , binding , & ndr_table_spoolss ,
test_credentials , tctx - > ev , tctx - > lp_ctx ) ,
" Error connecting to server " ) ;
t - > spoolss_pipe = p ;
t - > printername = printername ;
t - > user . testuser = testuser ;
return true ;
}
static bool torture_rpc_spoolss_access_setup ( struct torture_context * tctx , void * * data )
{
struct torture_access_context * t ;
* data = t = talloc_zero ( tctx , struct torture_access_context ) ;
t - > user . username = talloc_strdup ( t , TORTURE_USER ) ;
return torture_rpc_spoolss_access_setup_common ( tctx , t ) ;
}
static bool torture_rpc_spoolss_access_admin_setup ( struct torture_context * tctx , void * * data )
{
struct torture_access_context * t ;
* data = t = talloc_zero ( tctx , struct torture_access_context ) ;
t - > user . num_builtin_memberships = 1 ;
t - > user . builtin_memberships = talloc_zero_array ( t , uint32_t , t - > user . num_builtin_memberships ) ;
t - > user . builtin_memberships [ 0 ] = BUILTIN_RID_ADMINISTRATORS ;
t - > user . username = talloc_strdup ( t , TORTURE_USER_ADMINGROUP ) ;
2010-06-08 14:26:15 +04:00
t - > user . admin_rights = true ;
t - > user . system_security = true ;
2010-06-04 21:03:11 +04:00
return torture_rpc_spoolss_access_setup_common ( tctx , t ) ;
}
static bool torture_rpc_spoolss_access_printop_setup ( struct torture_context * tctx , void * * data )
{
struct torture_access_context * t ;
* data = t = talloc_zero ( tctx , struct torture_access_context ) ;
t - > user . num_builtin_memberships = 1 ;
t - > user . builtin_memberships = talloc_zero_array ( t , uint32_t , t - > user . num_builtin_memberships ) ;
t - > user . builtin_memberships [ 0 ] = BUILTIN_RID_PRINT_OPERATORS ;
t - > user . username = talloc_strdup ( t , TORTURE_USER_PRINTOPGROUP ) ;
2010-06-08 14:26:15 +04:00
t - > user . admin_rights = true ;
2010-06-04 21:03:11 +04:00
return torture_rpc_spoolss_access_setup_common ( tctx , t ) ;
}
static bool torture_rpc_spoolss_access_priv_setup ( struct torture_context * tctx , void * * data )
{
struct torture_access_context * t ;
* data = t = talloc_zero ( tctx , struct torture_access_context ) ;
t - > user . username = talloc_strdup ( t , TORTURE_USER_PRINTOPPRIV ) ;
t - > user . num_privs = 1 ;
t - > user . privs = talloc_zero_array ( t , const char * , t - > user . num_privs ) ;
t - > user . privs [ 0 ] = talloc_strdup ( t , " SePrintOperatorPrivilege " ) ;
2010-06-08 14:26:15 +04:00
t - > user . admin_rights = true ;
2010-06-04 21:03:11 +04:00
return torture_rpc_spoolss_access_setup_common ( tctx , t ) ;
}
static bool torture_rpc_spoolss_access_sd_setup ( struct torture_context * tctx , void * * data )
{
struct torture_access_context * t ;
* data = t = talloc_zero ( tctx , struct torture_access_context ) ;
t - > user . username = talloc_strdup ( t , TORTURE_USER_SD ) ;
t - > user . sd = true ;
2010-06-08 14:26:15 +04:00
t - > user . admin_rights = true ;
2010-06-04 21:03:11 +04:00
return torture_rpc_spoolss_access_setup_common ( tctx , t ) ;
}
static bool torture_rpc_spoolss_access_teardown_common ( struct torture_context * tctx , struct torture_access_context * t )
{
if ( t - > user . testuser ) {
torture_leave_domain ( tctx , t - > user . testuser ) ;
}
/* remove membership ? */
if ( t - > user . num_builtin_memberships ) {
}
/* remove privs ? */
if ( t - > user . num_privs ) {
}
/* restore sd */
2010-06-07 13:21:26 +04:00
if ( t - > user . sd & & t - > printername ) {
2010-06-04 21:03:11 +04:00
struct policy_handle handle ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_SetPrinterInfo3 info3 ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
struct dcerpc_pipe * spoolss_pipe ;
struct dcerpc_binding_handle * b ;
torture_assert_ntstatus_ok ( tctx ,
torture_rpc_connection ( tctx , & spoolss_pipe , & ndr_table_spoolss ) ,
" Error connecting to server " ) ;
b = spoolss_pipe - > binding_handle ;
ZERO_STRUCT ( info_ctr ) ;
ZERO_STRUCT ( info3 ) ;
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
info_ctr . level = 3 ;
info_ctr . info . info3 = & info3 ;
secdesc_ctr . sd = t - > sd_orig ;
torture_assert ( tctx ,
2010-06-08 14:26:15 +04:00
test_openprinter_handle ( tctx , spoolss_pipe , " " , t - > printername , " " , SEC_FLAG_MAXIMUM_ALLOWED , WERR_OK , & handle ) ,
2010-06-04 21:03:11 +04:00
" failed to open printer " ) ;
torture_assert ( tctx ,
test_SetPrinter ( tctx , b , & handle , & info_ctr , & devmode_ctr , & secdesc_ctr , 0 ) ,
" failed to set sd " ) ;
talloc_free ( spoolss_pipe ) ;
}
return true ;
}
static bool torture_rpc_spoolss_access_teardown ( struct torture_context * tctx , void * data )
{
struct torture_access_context * t = talloc_get_type ( data , struct torture_access_context ) ;
bool ret ;
ret = torture_rpc_spoolss_access_teardown_common ( tctx , t ) ;
talloc_free ( t ) ;
return ret ;
}
static bool test_openprinter ( struct torture_context * tctx ,
void * private_data )
{
struct torture_access_context * t =
( struct torture_access_context * ) talloc_get_type_abort ( private_data , struct torture_access_context ) ;
struct dcerpc_pipe * p = t - > spoolss_pipe ;
bool ret = true ;
const char * username = t - > user . username ;
2010-06-08 14:26:15 +04:00
const char * servername_slash = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
int i ;
2010-06-04 21:03:11 +04:00
2010-06-08 14:26:15 +04:00
struct {
const char * name ;
uint32_t access_mask ;
const char * printername ;
WERROR expected_result ;
} checks [ ] = {
2010-06-04 21:03:11 +04:00
2010-06-08 14:26:15 +04:00
/* printserver handle tests */
2010-06-04 21:03:11 +04:00
2010-06-08 14:26:15 +04:00
{
. name = " 0 " ,
. access_mask = 0 ,
. printername = servername_slash ,
. expected_result = WERR_OK
} ,
{
. name = " SEC_FLAG_MAXIMUM_ALLOWED " ,
. access_mask = SEC_FLAG_MAXIMUM_ALLOWED ,
. printername = servername_slash ,
. expected_result = WERR_OK
} ,
{
. name = " SERVER_ACCESS_ENUMERATE " ,
. access_mask = SERVER_ACCESS_ENUMERATE ,
. printername = servername_slash ,
. expected_result = WERR_OK
} ,
{
. name = " SERVER_ACCESS_ADMINISTER " ,
. access_mask = SERVER_ACCESS_ADMINISTER ,
. printername = servername_slash ,
. expected_result = t - > user . admin_rights ? WERR_OK : WERR_ACCESS_DENIED
} ,
{
. name = " SERVER_READ " ,
. access_mask = SERVER_READ ,
. printername = servername_slash ,
. expected_result = WERR_OK
} ,
{
. name = " SERVER_WRITE " ,
. access_mask = SERVER_WRITE ,
. printername = servername_slash ,
. expected_result = t - > user . admin_rights ? WERR_OK : WERR_ACCESS_DENIED
} ,
{
. name = " SERVER_EXECUTE " ,
. access_mask = SERVER_EXECUTE ,
. printername = servername_slash ,
. expected_result = WERR_OK
} ,
{
. name = " SERVER_ALL_ACCESS " ,
. access_mask = SERVER_ALL_ACCESS ,
. printername = servername_slash ,
. expected_result = t - > user . admin_rights ? WERR_OK : WERR_ACCESS_DENIED
} ,
2010-06-04 21:03:11 +04:00
2010-06-08 14:26:15 +04:00
/* printer handle tests */
2010-06-04 21:03:11 +04:00
2010-06-08 14:26:15 +04:00
{
. name = " 0 " ,
. access_mask = 0 ,
. printername = t - > printername ,
. expected_result = WERR_OK
} ,
{
. name = " SEC_FLAG_MAXIMUM_ALLOWED " ,
. access_mask = SEC_FLAG_MAXIMUM_ALLOWED ,
. printername = t - > printername ,
. expected_result = WERR_OK
} ,
{
. name = " SEC_FLAG_SYSTEM_SECURITY " ,
. access_mask = SEC_FLAG_SYSTEM_SECURITY ,
. printername = t - > printername ,
. expected_result = t - > user . system_security ? WERR_OK : WERR_ACCESS_DENIED
} ,
{
. name = " 0x010e0000 " ,
. access_mask = 0x010e0000 ,
. printername = t - > printername ,
. expected_result = t - > user . system_security ? WERR_OK : WERR_ACCESS_DENIED
} ,
{
. name = " PRINTER_ACCESS_USE " ,
. access_mask = PRINTER_ACCESS_USE ,
. printername = t - > printername ,
. expected_result = WERR_OK
} ,
{
. name = " SEC_STD_READ_CONTROL " ,
. access_mask = SEC_STD_READ_CONTROL ,
. printername = t - > printername ,
. expected_result = WERR_OK
} ,
{
. name = " PRINTER_ACCESS_ADMINISTER " ,
. access_mask = PRINTER_ACCESS_ADMINISTER ,
. printername = t - > printername ,
. expected_result = t - > user . admin_rights ? WERR_OK : WERR_ACCESS_DENIED
} ,
{
. name = " SEC_STD_WRITE_DAC " ,
. access_mask = SEC_STD_WRITE_DAC ,
. printername = t - > printername ,
. expected_result = t - > user . admin_rights ? WERR_OK : WERR_ACCESS_DENIED
} ,
{
. name = " SEC_STD_WRITE_OWNER " ,
. access_mask = SEC_STD_WRITE_OWNER ,
. printername = t - > printername ,
. expected_result = t - > user . admin_rights ? WERR_OK : WERR_ACCESS_DENIED
} ,
{
. name = " PRINTER_READ " ,
. access_mask = PRINTER_READ ,
. printername = t - > printername ,
. expected_result = WERR_OK
} ,
{
. name = " PRINTER_WRITE " ,
. access_mask = PRINTER_WRITE ,
. printername = t - > printername ,
. expected_result = t - > user . admin_rights ? WERR_OK : WERR_ACCESS_DENIED
} ,
{
. name = " PRINTER_EXECUTE " ,
. access_mask = PRINTER_EXECUTE ,
. printername = t - > printername ,
. expected_result = WERR_OK
} ,
{
. name = " PRINTER_ALL_ACCESS " ,
. access_mask = PRINTER_ALL_ACCESS ,
. printername = t - > printername ,
. expected_result = t - > user . admin_rights ? WERR_OK : WERR_ACCESS_DENIED
}
} ;
2010-06-04 21:03:11 +04:00
if ( t - > user . num_privs & & ! t - > user . privs_present ) {
torture_skip ( tctx , " skipping test as not all required privileges are present on the server \n " ) ;
}
2010-06-08 14:26:15 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( checks ) ; i + + ) {
ret & = test_openprinter_access ( tctx , p ,
checks [ i ] . name ,
checks [ i ] . printername ,
username ,
checks [ i ] . access_mask ,
checks [ i ] . expected_result ) ;
2010-06-04 21:03:11 +04:00
}
return ret ;
}
2010-06-07 14:41:39 +04:00
static bool test_openprinter_wrap ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
struct torture_access_context * t ;
const char * printername ;
bool ret = true ;
t = talloc_zero ( tctx , struct torture_access_context ) ;
t - > user . username = talloc_strdup ( tctx , " dummy " ) ;
t - > spoolss_pipe = p ;
torture_assert ( tctx ,
test_EnumPrinters_findone ( tctx , p , & printername ) ,
" failed to enumerate printers " ) ;
t - > printername = printername ;
ret = test_openprinter ( tctx , ( void * ) t ) ;
talloc_free ( t ) ;
2014-05-13 01:06:49 +04:00
return ret ;
2010-06-07 14:41:39 +04:00
}
2010-06-04 21:03:11 +04:00
struct torture_suite * torture_rpc_spoolss_access ( TALLOC_CTX * mem_ctx )
{
2010-12-11 05:26:31 +03:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " spoolss.access " ) ;
2010-06-04 21:03:11 +04:00
struct torture_tcase * tcase ;
2010-06-07 14:41:39 +04:00
struct torture_rpc_tcase * rpc_tcase ;
2010-06-04 21:03:11 +04:00
tcase = torture_suite_add_tcase ( suite , " normaluser " ) ;
torture_tcase_set_fixture ( tcase ,
torture_rpc_spoolss_access_setup ,
torture_rpc_spoolss_access_teardown ) ;
torture_tcase_add_simple_test ( tcase , " openprinter " , test_openprinter ) ;
tcase = torture_suite_add_tcase ( suite , " adminuser " ) ;
torture_tcase_set_fixture ( tcase ,
torture_rpc_spoolss_access_admin_setup ,
torture_rpc_spoolss_access_teardown ) ;
torture_tcase_add_simple_test ( tcase , " openprinter " , test_openprinter ) ;
tcase = torture_suite_add_tcase ( suite , " printopuser " ) ;
torture_tcase_set_fixture ( tcase ,
torture_rpc_spoolss_access_printop_setup ,
torture_rpc_spoolss_access_teardown ) ;
torture_tcase_add_simple_test ( tcase , " openprinter " , test_openprinter ) ;
tcase = torture_suite_add_tcase ( suite , " printopuserpriv " ) ;
torture_tcase_set_fixture ( tcase ,
torture_rpc_spoolss_access_priv_setup ,
torture_rpc_spoolss_access_teardown ) ;
torture_tcase_add_simple_test ( tcase , " openprinter " , test_openprinter ) ;
tcase = torture_suite_add_tcase ( suite , " normaluser_sd " ) ;
torture_tcase_set_fixture ( tcase ,
torture_rpc_spoolss_access_sd_setup ,
torture_rpc_spoolss_access_teardown ) ;
torture_tcase_add_simple_test ( tcase , " openprinter " , test_openprinter ) ;
2010-06-07 14:41:39 +04:00
rpc_tcase = torture_suite_add_machine_workstation_rpc_iface_tcase ( suite , " workstation " ,
& ndr_table_spoolss ,
TORTURE_WORKSTATION ) ;
torture_rpc_tcase_add_test ( rpc_tcase , " openprinter " , test_openprinter_wrap ) ;
2010-06-04 21:03:11 +04:00
return suite ;
}