2009-05-13 05:18:07 +04:00
/*
2007-09-21 02:57:57 +04:00
Unix SMB / CIFS implementation .
test suite for accessmasks on the SAMR pipe
Copyright ( C ) Ronnie Sahlberg 2007
2009-06-26 18:53:51 +04:00
Copyright ( C ) Guenther Deschner 2009
2009-05-13 05:18:07 +04:00
2007-09-21 02:57:57 +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
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
2009-05-13 05:18:07 +04:00
2007-09-21 02:57:57 +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 .
2009-05-13 05:18:07 +04:00
2007-09-21 02:57:57 +04:00
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 "librpc/gen_ndr/ndr_samr_c.h"
2010-04-14 00:06:51 +04:00
# include "torture/rpc/torture_rpc.h"
2007-09-21 02:57:57 +04:00
# include "param/param.h"
# include "libcli/security/security.h"
/* test user created to test the ACLs associated to SAMR objects */
# define TEST_USER_NAME "samr_testuser"
2009-06-26 18:53:51 +04:00
# define TEST_MACHINENAME "samrtestmach"
2007-09-21 02:57:57 +04:00
static NTSTATUS torture_samr_Close ( struct torture_context * tctx ,
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b ,
2009-05-13 05:18:07 +04:00
struct policy_handle * h )
2007-09-21 02:57:57 +04:00
{
NTSTATUS status ;
struct samr_Close cl ;
cl . in . handle = h ;
cl . out . handle = h ;
2010-03-15 11:01:17 +03:00
status = dcerpc_samr_Close_r ( b , tctx , & cl ) ;
2010-03-19 14:23:37 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2007-09-21 02:57:57 +04:00
2010-03-19 14:23:37 +03:00
return cl . out . result ;
2007-09-21 02:57:57 +04:00
}
static NTSTATUS torture_samr_Connect5 ( struct torture_context * tctx ,
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b ,
2009-05-13 05:18:07 +04:00
uint32_t mask , struct policy_handle * h )
2007-09-21 02:57:57 +04:00
{
NTSTATUS status ;
struct samr_Connect5 r5 ;
union samr_ConnectInfo info ;
2008-11-05 03:51:51 +03:00
uint32_t level_out = 0 ;
2007-09-21 02:57:57 +04:00
2008-10-15 19:42:33 +04:00
info . info1 . client_version = 0 ;
2021-08-25 15:11:28 +03:00
info . info1 . supported_features = 0 ;
2007-09-21 02:57:57 +04:00
r5 . in . system_name = " " ;
2008-11-05 03:51:51 +03:00
r5 . in . level_in = 1 ;
r5 . in . info_in = & info ;
r5 . out . info_out = & info ;
r5 . out . level_out = & level_out ;
2007-09-21 02:57:57 +04:00
r5 . out . connect_handle = h ;
r5 . in . access_mask = mask ;
2010-03-15 11:01:17 +03:00
status = dcerpc_samr_Connect5_r ( b , tctx , & r5 ) ;
2010-03-19 14:23:37 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2007-09-21 02:57:57 +04:00
2010-03-19 14:23:37 +03:00
return r5 . out . result ;
2007-09-21 02:57:57 +04:00
}
/* check which bits in accessmask allows us to connect to the server */
2009-05-13 05:18:07 +04:00
static bool test_samr_accessmask_Connect5 ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
2007-09-21 02:57:57 +04:00
{
NTSTATUS status ;
struct policy_handle h ;
int i ;
uint32_t mask ;
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2007-09-21 02:57:57 +04:00
2010-04-11 03:39:06 +04:00
printf ( " Testing which bits in accessmask allows us to connect \n " ) ;
2007-09-21 02:57:57 +04:00
mask = 1 ;
2009-05-13 05:18:07 +04:00
for ( i = 0 ; i < 33 ; i + + ) {
2010-04-11 03:39:06 +04:00
printf ( " Testing Connect5 with access mask 0x%08x " , mask ) ;
2010-03-15 11:01:17 +03:00
status = torture_samr_Connect5 ( tctx , b , mask , & h ) ;
2007-09-21 02:57:57 +04:00
mask < < = 1 ;
switch ( i ) {
case 6 :
case 7 :
case 8 :
case 9 :
case 10 :
case 11 :
case 12 :
case 13 :
case 14 :
case 15 :
case 20 :
case 21 :
case 22 :
case 23 :
case 26 :
case 27 :
printf ( " expecting to fail " ) ;
/* of only one of these bits are set we expect to
fail by default
*/
if ( ! NT_STATUS_EQUAL ( NT_STATUS_ACCESS_DENIED , status ) ) {
printf ( " Connect5 failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
break ;
default :
/* these bits set are expected to succeed by default */
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Connect5 failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
2010-03-15 11:01:17 +03:00
status = torture_samr_Close ( tctx , b , & h ) ;
2007-09-21 02:57:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Close failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
break ;
}
printf ( " OK \n " ) ;
}
2007-10-07 02:28:14 +04:00
return true ;
2007-09-21 02:57:57 +04:00
}
/* check which bits in accessmask allows us to EnumDomains()
by default we must specify at least one of :
SAMR / EnumDomains
Maximum
GenericAll
GenericRead
in the access mask to Connect5 ( ) in order to be allowed to perform
EnumDomains ( ) on the policy handle returned from Connect5 ( )
*/
2009-05-13 05:18:07 +04:00
static bool test_samr_accessmask_EnumDomains ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
2007-09-21 02:57:57 +04:00
{
NTSTATUS status ;
struct samr_EnumDomains ed ;
struct policy_handle ch ;
int i ;
uint32_t mask ;
uint32_t resume_handle = 0 ;
2008-11-07 04:57:58 +03:00
struct samr_SamArray * sam = NULL ;
uint32_t num_entries = 0 ;
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2007-09-21 02:57:57 +04:00
2010-04-11 03:39:06 +04:00
printf ( " Testing which bits in Connect5 accessmask allows us to EnumDomains \n " ) ;
2007-09-21 02:57:57 +04:00
mask = 1 ;
2009-05-13 05:18:07 +04:00
for ( i = 0 ; i < 33 ; i + + ) {
2010-04-11 03:39:06 +04:00
printf ( " Testing Connect5/EnumDomains with access mask 0x%08x " , mask ) ;
2010-03-15 11:01:17 +03:00
status = torture_samr_Connect5 ( tctx , b , mask , & ch ) ;
2007-09-21 02:57:57 +04:00
mask < < = 1 ;
switch ( i ) {
case 4 : /* SAMR/EnumDomains */
case 25 : /* Maximum */
case 28 : /* GenericAll */
case 31 : /* GenericRead */
/* these bits set are expected to succeed by default */
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Connect5 failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
ed . in . connect_handle = & ch ;
ed . in . resume_handle = & resume_handle ;
ed . in . buf_size = ( uint32_t ) - 1 ;
ed . out . resume_handle = & resume_handle ;
2008-11-07 04:57:58 +03:00
ed . out . num_entries = & num_entries ;
ed . out . sam = & sam ;
2007-09-21 02:57:57 +04:00
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_EnumDomains_r ( b , tctx , & ed ) ,
" EnumDomains failed " ) ;
if ( ! NT_STATUS_IS_OK ( ed . out . result ) ) {
printf ( " EnumDomains failed - %s \n " , nt_errstr ( ed . out . result ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
2010-03-15 11:01:17 +03:00
status = torture_samr_Close ( tctx , b , & ch ) ;
2007-09-21 02:57:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Close failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
break ;
default :
printf ( " expecting to fail " ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " OK \n " ) ;
continue ;
}
ed . in . connect_handle = & ch ;
ed . in . resume_handle = & resume_handle ;
ed . in . buf_size = ( uint32_t ) - 1 ;
ed . out . resume_handle = & resume_handle ;
2008-11-07 04:57:58 +03:00
ed . out . num_entries = & num_entries ;
ed . out . sam = & sam ;
2007-09-21 02:57:57 +04:00
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_EnumDomains_r ( b , tctx , & ed ) ,
" EnumDomains failed " ) ;
if ( ! NT_STATUS_EQUAL ( NT_STATUS_ACCESS_DENIED , ed . out . result ) ) {
printf ( " EnumDomains failed - %s \n " , nt_errstr ( ed . out . result ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
2010-03-15 11:01:17 +03:00
status = torture_samr_Close ( tctx , b , & ch ) ;
2007-09-21 02:57:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Close failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
break ;
}
printf ( " OK \n " ) ;
}
2007-10-07 02:28:14 +04:00
return true ;
2007-09-21 02:57:57 +04:00
}
/*
2009-05-13 05:18:07 +04:00
* test how ACLs affect how / if a user can connect to the SAMR service
2007-09-21 02:57:57 +04:00
*
* samr_SetSecurity ( ) returns SUCCESS when changing the ACL for
* a policy handle got from Connect5 ( ) but the ACL is not changed on
* the server
*/
2009-05-13 05:18:07 +04:00
static bool test_samr_connect_user_acl ( struct torture_context * tctx ,
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b ,
2009-05-13 05:18:07 +04:00
struct cli_credentials * test_credentials ,
const struct dom_sid * test_sid )
2007-09-21 02:57:57 +04:00
{
NTSTATUS status ;
struct policy_handle ch ;
struct policy_handle uch ;
struct samr_QuerySecurity qs ;
struct samr_SetSecurity ss ;
struct security_ace ace ;
struct security_descriptor * sd ;
2008-10-28 00:57:51 +03:00
struct sec_desc_buf sdb , * sdbuf = NULL ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2007-09-21 02:57:57 +04:00
int sd_size ;
struct dcerpc_pipe * test_p ;
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * test_b ;
2007-09-21 02:57:57 +04:00
const char * binding = torture_setting_string ( tctx , " binding " , NULL ) ;
2010-04-11 03:39:06 +04:00
printf ( " Testing ACLs to allow/prevent users to connect to SAMR " ) ;
2007-09-21 02:57:57 +04:00
/* connect to SAMR */
2010-03-15 11:01:17 +03:00
status = torture_samr_Connect5 ( tctx , b , SEC_FLAG_MAXIMUM_ALLOWED , & ch ) ;
2007-09-21 02:57:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Connect5 failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
2009-05-13 05:18:07 +04:00
2007-09-21 02:57:57 +04:00
/* get the current ACL for the SAMR policy handle */
qs . in . handle = & ch ;
qs . in . sec_info = SECINFO_DACL ;
2008-10-28 00:57:51 +03:00
qs . out . sdbuf = & sdbuf ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_QuerySecurity_r ( b , tctx , & qs ) ,
" QuerySecurity failed " ) ;
if ( ! NT_STATUS_IS_OK ( qs . out . result ) ) {
printf ( " QuerySecurity failed - %s \n " , nt_errstr ( qs . out . result ) ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2007-09-21 02:57:57 +04:00
}
/* how big is the security descriptor? */
2008-10-28 00:57:51 +03:00
sd_size = sdbuf - > sd_size ;
2007-09-21 02:57:57 +04:00
/* add an ACE to the security descriptor to deny the user the
* ' connect to server ' right
*/
2008-10-28 00:57:51 +03:00
sd = sdbuf - > sd ;
2007-09-21 02:57:57 +04:00
ace . type = SEC_ACE_TYPE_ACCESS_DENIED ;
ace . flags = 0 ;
ace . access_mask = SAMR_ACCESS_CONNECT_TO_SERVER ;
ace . trustee = * test_sid ;
status = security_descriptor_dacl_add ( sd , & ace ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to add ACE to security descriptor \n " ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2007-09-21 02:57:57 +04:00
}
ss . in . handle = & ch ;
ss . in . sec_info = SECINFO_DACL ;
ss . in . sdbuf = & sdb ;
sdb . sd = sd ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_SetSecurity_r ( b , tctx , & ss ) ,
" SetSecurity failed " ) ;
if ( ! NT_STATUS_IS_OK ( ss . out . result ) ) {
printf ( " SetSecurity failed - %s \n " , nt_errstr ( ss . out . result ) ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2007-09-21 02:57:57 +04:00
}
/* Try to connect as the test user */
2009-05-13 05:18:07 +04:00
status = dcerpc_pipe_connect ( tctx ,
2007-09-21 02:57:57 +04:00
& test_p , binding , & ndr_table_samr ,
2009-04-16 00:47:15 +04:00
test_credentials , tctx - > ev , tctx - > lp_ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " dcerpc_pipe_connect failed: %s \n " , nt_errstr ( status ) ) ;
return false ;
}
2010-03-15 11:01:17 +03:00
test_b = test_p - > binding_handle ;
2009-04-16 00:47:15 +04:00
2007-09-21 02:57:57 +04:00
/* connect to SAMR as the user */
2010-03-15 11:01:17 +03:00
status = torture_samr_Connect5 ( tctx , test_b , SEC_FLAG_MAXIMUM_ALLOWED , & uch ) ;
2007-09-21 02:57:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Connect5 failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
2023-08-03 16:45:20 +03:00
/* disconnect the user */
2007-09-21 02:57:57 +04:00
talloc_free ( test_p ) ;
2009-05-13 05:18:07 +04:00
/* read the sequrity descriptor back. it should not have changed
2023-08-03 16:45:20 +03:00
* even though samr_SetSecurity returned SUCCESS
2007-09-21 02:57:57 +04:00
*/
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_QuerySecurity_r ( b , tctx , & qs ) ,
" QuerySecurity failed " ) ;
if ( ! NT_STATUS_IS_OK ( qs . out . result ) ) {
printf ( " QuerySecurity failed - %s \n " , nt_errstr ( qs . out . result ) ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2007-09-21 02:57:57 +04:00
}
2008-10-28 00:57:51 +03:00
if ( sd_size ! = sdbuf - > sd_size ) {
2007-09-21 02:57:57 +04:00
printf ( " security descriptor changed \n " ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2007-09-21 02:57:57 +04:00
}
2010-03-15 11:01:17 +03:00
status = torture_samr_Close ( tctx , b , & ch ) ;
2007-09-21 02:57:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Close failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2007-09-21 02:57:57 +04:00
}
2007-10-07 02:28:14 +04:00
if ( ret = = true ) {
2007-09-21 02:57:57 +04:00
printf ( " OK \n " ) ;
}
return ret ;
}
2007-09-21 03:27:28 +04:00
/*
* test if the ACLs are enforced for users .
2023-08-03 16:45:20 +03:00
* a normal testuser only gets the rights provided in the ACL for
2007-09-21 03:27:28 +04:00
* Everyone which does not include the SAMR_ACCESS_SHUTDOWN_SERVER
2009-05-13 05:18:07 +04:00
* right . If the ACLs are checked when a user connects
2007-09-21 03:27:28 +04:00
* a testuser that requests the accessmask with only this bit set
* the connect should fail .
*/
2009-05-13 05:18:07 +04:00
static bool test_samr_connect_user_acl_enforced ( struct torture_context * tctx ,
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b ,
2009-05-13 05:18:07 +04:00
struct cli_credentials * test_credentials ,
const struct dom_sid * test_sid )
2007-09-21 03:27:28 +04:00
{
NTSTATUS status ;
struct policy_handle uch ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2007-09-21 03:27:28 +04:00
struct dcerpc_pipe * test_p ;
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * test_b ;
2007-09-21 03:27:28 +04:00
const char * binding = torture_setting_string ( tctx , " binding " , NULL ) ;
2010-04-11 03:39:06 +04:00
printf ( " Testing if ACLs are enforced for non domain admin users when connecting to SAMR " ) ;
2007-09-21 03:27:28 +04:00
2009-05-13 05:18:07 +04:00
status = dcerpc_pipe_connect ( tctx ,
2007-09-21 03:27:28 +04:00
& test_p , binding , & ndr_table_samr ,
2009-04-16 00:47:15 +04:00
test_credentials , tctx - > ev , tctx - > lp_ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " dcerpc_pipe_connect failed: %s \n " , nt_errstr ( status ) ) ;
return false ;
}
2010-03-15 11:01:17 +03:00
test_b = test_p - > binding_handle ;
2007-09-21 03:27:28 +04:00
/* connect to SAMR as the user */
2010-03-15 11:01:17 +03:00
status = torture_samr_Connect5 ( tctx , test_b , SAMR_ACCESS_SHUTDOWN_SERVER , & uch ) ;
2007-09-21 03:27:28 +04:00
if ( NT_STATUS_IS_OK ( status ) ) {
printf ( " Connect5 failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 03:27:28 +04:00
}
printf ( " OK \n " ) ;
2023-08-03 16:45:20 +03:00
/* disconnect the user */
2007-09-21 03:27:28 +04:00
talloc_free ( test_p ) ;
return ret ;
}
2007-09-21 02:57:57 +04:00
/* check which bits in accessmask allows us to LookupDomain()
by default we must specify at least one of :
in the access mask to Connect5 ( ) in order to be allowed to perform
case 5 : samr / opendomain
2009-05-13 05:18:07 +04:00
case 25 : Maximum
2007-09-21 02:57:57 +04:00
case 28 : GenericAll
case 29 : GenericExecute
LookupDomain ( ) on the policy handle returned from Connect5 ( )
*/
2009-05-13 05:18:07 +04:00
static bool test_samr_accessmask_LookupDomain ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
2007-09-21 02:57:57 +04:00
{
NTSTATUS status ;
struct samr_LookupDomain ld ;
2008-11-07 04:42:45 +03:00
struct dom_sid2 * sid = NULL ;
2007-09-21 02:57:57 +04:00
struct policy_handle ch ;
struct lsa_String dn ;
int i ;
uint32_t mask ;
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2007-09-21 02:57:57 +04:00
2010-04-11 03:39:06 +04:00
printf ( " Testing which bits in Connect5 accessmask allows us to LookupDomain \n " ) ;
2007-09-21 02:57:57 +04:00
mask = 1 ;
2009-05-13 05:18:07 +04:00
for ( i = 0 ; i < 33 ; i + + ) {
2010-04-11 03:39:06 +04:00
printf ( " Testing Connect5/LookupDomain with access mask 0x%08x " , mask ) ;
2010-03-15 11:01:17 +03:00
status = torture_samr_Connect5 ( tctx , b , mask , & ch ) ;
2007-09-21 02:57:57 +04:00
mask < < = 1 ;
switch ( i ) {
2009-05-13 05:18:07 +04:00
case 5 :
2007-09-21 02:57:57 +04:00
case 25 : /* Maximum */
case 28 : /* GenericAll */
case 29 : /* GenericExecute */
/* these bits set are expected to succeed by default */
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Connect5 failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
ld . in . connect_handle = & ch ;
ld . in . domain_name = & dn ;
2008-11-07 04:42:45 +03:00
ld . out . sid = & sid ;
2010-07-16 08:32:42 +04:00
dn . string = lpcfg_workgroup ( tctx - > lp_ctx ) ;
2007-09-21 02:57:57 +04:00
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_LookupDomain_r ( b , tctx , & ld ) ,
" LookupDomain failed " ) ;
if ( ! NT_STATUS_IS_OK ( ld . out . result ) ) {
printf ( " LookupDomain failed - %s \n " , nt_errstr ( ld . out . result ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
2010-03-15 11:01:17 +03:00
status = torture_samr_Close ( tctx , b , & ch ) ;
2007-09-21 02:57:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Close failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
break ;
default :
printf ( " expecting to fail " ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " OK \n " ) ;
continue ;
}
ld . in . connect_handle = & ch ;
ld . in . domain_name = & dn ;
2009-04-16 00:47:15 +04:00
ld . out . sid = & sid ;
2010-07-16 08:32:42 +04:00
dn . string = lpcfg_workgroup ( tctx - > lp_ctx ) ;
2007-09-21 02:57:57 +04:00
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_LookupDomain_r ( b , tctx , & ld ) ,
" LookupDomain failed " ) ;
if ( ! NT_STATUS_EQUAL ( NT_STATUS_ACCESS_DENIED , ld . out . result ) ) {
printf ( " LookupDomain failed - %s \n " , nt_errstr ( ld . out . result ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
2010-03-15 11:01:17 +03:00
status = torture_samr_Close ( tctx , b , & ch ) ;
2007-09-21 02:57:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Close failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
break ;
}
printf ( " OK \n " ) ;
}
2007-10-07 02:28:14 +04:00
return true ;
2007-09-21 02:57:57 +04:00
}
/* check which bits in accessmask allows us to OpenDomain()
by default we must specify at least one of :
samr / opendomain
2009-05-13 05:18:07 +04:00
Maximum
2007-09-21 02:57:57 +04:00
GenericAll
GenericExecute
in the access mask to Connect5 ( ) in order to be allowed to perform
OpenDomain ( ) on the policy handle returned from Connect5 ( )
*/
2009-05-13 05:18:07 +04:00
static bool test_samr_accessmask_OpenDomain ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
2007-09-21 02:57:57 +04:00
{
NTSTATUS status ;
struct samr_LookupDomain ld ;
2008-11-07 04:42:45 +03:00
struct dom_sid2 * sid = NULL ;
2007-09-21 02:57:57 +04:00
struct samr_OpenDomain od ;
struct policy_handle ch ;
struct policy_handle dh ;
struct lsa_String dn ;
int i ;
uint32_t mask ;
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2007-09-21 02:57:57 +04:00
/* first we must grab the sid of the domain */
2010-03-15 11:01:17 +03:00
status = torture_samr_Connect5 ( tctx , b , SEC_FLAG_MAXIMUM_ALLOWED , & ch ) ;
2007-09-21 02:57:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Connect5 failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
ld . in . connect_handle = & ch ;
ld . in . domain_name = & dn ;
2008-11-07 04:42:45 +03:00
ld . out . sid = & sid ;
2010-07-16 08:32:42 +04:00
dn . string = lpcfg_workgroup ( tctx - > lp_ctx ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_LookupDomain_r ( b , tctx , & ld ) ,
" LookupDomain failed " ) ;
if ( ! NT_STATUS_IS_OK ( ld . out . result ) ) {
printf ( " LookupDomain failed - %s \n " , nt_errstr ( ld . out . result ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
2010-04-11 03:39:06 +04:00
printf ( " Testing which bits in Connect5 accessmask allows us to OpenDomain \n " ) ;
2007-09-21 02:57:57 +04:00
mask = 1 ;
2009-05-13 05:18:07 +04:00
for ( i = 0 ; i < 33 ; i + + ) {
2010-04-11 03:39:06 +04:00
printf ( " Testing Connect5/OpenDomain with access mask 0x%08x " , mask ) ;
2010-03-15 11:01:17 +03:00
status = torture_samr_Connect5 ( tctx , b , mask , & ch ) ;
2007-09-21 02:57:57 +04:00
mask < < = 1 ;
switch ( i ) {
2009-05-13 05:18:07 +04:00
case 5 :
2007-09-21 02:57:57 +04:00
case 25 : /* Maximum */
case 28 : /* GenericAll */
case 29 : /* GenericExecute */
/* these bits set are expected to succeed by default */
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Connect5 failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
od . in . connect_handle = & ch ;
od . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
2009-04-16 00:47:15 +04:00
od . in . sid = sid ;
2007-09-21 02:57:57 +04:00
od . out . domain_handle = & dh ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_OpenDomain_r ( b , tctx , & od ) ,
" OpenDomain failed " ) ;
if ( ! NT_STATUS_IS_OK ( od . out . result ) ) {
printf ( " OpenDomain failed - %s \n " , nt_errstr ( od . out . result ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
2010-03-15 11:01:17 +03:00
status = torture_samr_Close ( tctx , b , & dh ) ;
2007-09-21 02:57:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Close failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
2010-03-15 11:01:17 +03:00
status = torture_samr_Close ( tctx , b , & ch ) ;
2007-09-21 02:57:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Close failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
break ;
default :
printf ( " expecting to fail " ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " OK \n " ) ;
continue ;
}
2010-03-15 11:01:17 +03:00
status = torture_samr_Close ( tctx , b , & ch ) ;
2007-09-21 02:57:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Close failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
break ;
}
printf ( " OK \n " ) ;
}
2007-10-07 02:28:14 +04:00
return true ;
2007-09-21 02:57:57 +04:00
}
2009-05-13 05:18:07 +04:00
static bool test_samr_connect ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
2007-09-21 02:57:57 +04:00
{
void * testuser ;
const char * testuser_passwd ;
struct cli_credentials * test_credentials ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2007-09-21 02:57:57 +04:00
const struct dom_sid * test_sid ;
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2007-09-21 02:57:57 +04:00
2009-05-13 17:14:20 +04:00
if ( torture_setting_bool ( tctx , " samba3 " , false ) ) {
torture_skip ( tctx , " Skipping test against Samba 3 " ) ;
}
2007-09-21 02:57:57 +04:00
/* create a test user */
2010-07-16 08:32:42 +04:00
testuser = torture_create_testuser ( tctx , TEST_USER_NAME , lpcfg_workgroup ( tctx - > lp_ctx ) ,
2007-09-28 05:17:46 +04:00
ACB_NORMAL , & testuser_passwd ) ;
2007-09-21 02:57:57 +04:00
if ( ! testuser ) {
printf ( " Failed to create test user \n " ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-09-21 02:57:57 +04:00
}
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 ) ,
2007-09-28 05:17:46 +04:00
CRED_SPECIFIED ) ;
2007-09-21 02:57:57 +04:00
cli_credentials_set_username ( test_credentials , TEST_USER_NAME , CRED_SPECIFIED ) ;
cli_credentials_set_password ( test_credentials , testuser_passwd , CRED_SPECIFIED ) ;
test_sid = torture_join_user_sid ( testuser ) ;
/* test if ACLs can be changed for the policy handle
* returned by Connect5
*/
2010-03-15 11:01:17 +03:00
if ( ! test_samr_connect_user_acl ( tctx , b , test_credentials , test_sid ) ) {
2007-10-07 02:28:14 +04:00
ret = false ;
2007-09-21 02:57:57 +04:00
}
2009-05-13 05:18:07 +04:00
/* test if the ACLs that are reported from the Connect5
2007-09-21 03:27:28 +04:00
* policy handle is enforced .
* i . e . an ordinary user only has the same rights as Everybody
* ReadControl
* Samr / OpenDomain
* Samr / EnumDomains
* Samr / ConnectToServer
* is granted and should therefore not be able to connect when
* requesting SAMR_ACCESS_SHUTDOWN_SERVER
*/
2010-03-15 11:01:17 +03:00
if ( ! test_samr_connect_user_acl_enforced ( tctx , b , test_credentials , test_sid ) ) {
2007-10-07 02:28:14 +04:00
ret = false ;
2007-09-21 03:27:28 +04:00
}
2007-09-21 02:57:57 +04:00
/* remove the test user */
2008-06-14 19:24:17 +04:00
torture_leave_domain ( tctx , testuser ) ;
2007-09-21 02:57:57 +04:00
return ret ;
}
struct torture_suite * torture_rpc_samr_accessmask ( TALLOC_CTX * mem_ctx )
{
2010-12-11 05:26:31 +03:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " samr.accessmask " ) ;
2007-09-21 02:57:57 +04:00
struct torture_rpc_tcase * tcase ;
2009-05-13 05:18:07 +04:00
tcase = torture_suite_add_rpc_iface_tcase ( suite , " samr " ,
& ndr_table_samr ) ;
2010-12-11 05:26:31 +03:00
torture_rpc_tcase_add_test ( tcase , " connect " , test_samr_connect ) ;
2007-09-21 02:57:57 +04:00
2009-05-13 17:14:20 +04:00
/* test which bits in the accessmask to Connect5 will allow
* us to call OpenDomain ( ) */
torture_rpc_tcase_add_test ( tcase , " OpenDomain " ,
test_samr_accessmask_OpenDomain ) ;
/* test which bits in the accessmask to Connect5 will allow
* us to call LookupDomain ( ) */
torture_rpc_tcase_add_test ( tcase , " LookupDomain " ,
test_samr_accessmask_LookupDomain ) ;
/* test which bits in the accessmask to Connect5 will allow
* us to call EnumDomains ( ) */
torture_rpc_tcase_add_test ( tcase , " EnumDomains " ,
test_samr_accessmask_EnumDomains ) ;
/* test which bits in the accessmask to Connect5
will allow us to connect to the server */
torture_rpc_tcase_add_test ( tcase , " Connect5 " ,
test_samr_accessmask_Connect5 ) ;
2007-09-21 02:57:57 +04:00
return suite ;
}
2009-06-26 18:53:51 +04:00
static bool test_LookupRids ( struct torture_context * tctx ,
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b ,
2009-06-26 18:53:51 +04:00
struct policy_handle * domain_handle ,
uint32_t rid )
{
struct samr_LookupRids r ;
struct lsa_Strings names ;
struct samr_Ids types ;
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing LookupRids %d \n " , rid ) ;
2009-06-26 18:53:51 +04:00
r . in . domain_handle = domain_handle ;
r . in . num_rids = 1 ;
r . in . rids = & rid ;
r . out . names = & names ;
r . out . types = & types ;
2010-03-15 11:01:17 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_LookupRids_r ( b , tctx , & r ) ,
2009-06-26 18:53:51 +04:00
" failed to call samr_LookupRids " ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" failed to call samr_LookupRids " ) ;
2009-06-26 18:53:51 +04:00
return true ;
}
static bool test_user ( struct torture_context * tctx ,
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b ,
2009-06-26 18:53:51 +04:00
struct policy_handle * domain_handle ,
uint32_t access_mask ,
struct samr_DispEntryGeneral * u )
{
struct policy_handle user_handle ;
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing user %s (%d) \n " , u - > account_name . string , u - > rid ) ;
2009-06-26 18:53:51 +04:00
2010-03-15 11:01:17 +03:00
torture_assert ( tctx , test_LookupRids ( tctx , b , domain_handle , u - > rid ) ,
2009-06-26 18:53:51 +04:00
" failed to call lookuprids " ) ;
{
struct samr_OpenUser r ;
r . in . domain_handle = domain_handle ;
r . in . access_mask = access_mask ;
r . in . rid = u - > rid ;
r . out . user_handle = & user_handle ;
2010-03-15 11:01:17 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_OpenUser_r ( b , tctx , & r ) ,
2009-06-26 18:53:51 +04:00
" failed to open user " ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" failed to open user " ) ;
2009-06-26 18:53:51 +04:00
}
{
struct samr_QueryUserInfo r ;
union samr_UserInfo * info ;
uint32_t levels [ ] = { 16 , 21 } ;
int i ;
r . in . user_handle = & user_handle ;
r . out . info = & info ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
r . in . level = levels [ i ] ;
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing QueryUserInfo rid: %d level: %d \n " ,
2009-06-26 18:53:51 +04:00
u - > rid , r . in . level ) ;
2010-03-15 11:01:17 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_QueryUserInfo_r ( b , tctx , & r ) ,
2009-06-26 18:53:51 +04:00
talloc_asprintf ( tctx , " failed to query user info level %d " , r . in . level ) ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result ,
talloc_asprintf ( tctx , " failed to query user info level %d " , r . in . level ) ) ;
2009-06-26 18:53:51 +04:00
}
}
{
struct samr_GetGroupsForUser r ;
struct samr_RidWithAttributeArray * rids ;
r . in . user_handle = & user_handle ;
r . out . rids = & rids ;
2010-03-15 11:01:17 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_GetGroupsForUser_r ( b , tctx , & r ) ,
2009-06-26 18:53:51 +04:00
" failed to query groups for user " ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" failed to query groups for user " ) ;
2009-06-26 18:53:51 +04:00
}
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 11:01:17 +03:00
torture_samr_Close ( tctx , b , & user_handle ) ,
2009-06-26 18:53:51 +04:00
" failed to close user handle " ) ;
return true ;
}
static bool test_samr_group ( struct torture_context * tctx ,
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b ,
2009-06-26 18:53:51 +04:00
struct policy_handle * domain_handle ,
uint32_t access_mask ,
struct samr_SamEntry * g )
{
struct policy_handle group_handle ;
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing group %s (%d) \n " , g - > name . string , g - > idx ) ;
2009-06-26 18:53:51 +04:00
2010-03-15 11:01:17 +03:00
torture_assert ( tctx , test_LookupRids ( tctx , b , domain_handle , g - > idx ) ,
2009-06-26 18:53:51 +04:00
" failed to call lookuprids " ) ;
{
struct samr_OpenGroup r ;
r . in . domain_handle = domain_handle ;
r . in . access_mask = access_mask ;
r . in . rid = g - > idx ;
r . out . group_handle = & group_handle ;
2010-03-15 11:01:17 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_OpenGroup_r ( b , tctx , & r ) ,
2009-06-26 18:53:51 +04:00
" failed to open group " ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" failed to open group " ) ;
2009-06-26 18:53:51 +04:00
}
{
struct samr_QueryGroupMember r ;
2010-10-07 15:01:29 +04:00
struct samr_RidAttrArray * rids ;
2009-06-26 18:53:51 +04:00
r . in . group_handle = & group_handle ;
r . out . rids = & rids ;
2010-03-15 11:01:17 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_QueryGroupMember_r ( b , tctx , & r ) ,
2009-06-26 18:53:51 +04:00
" failed to query group member " ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" failed to query group member " ) ;
2009-06-26 18:53:51 +04:00
}
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 11:01:17 +03:00
torture_samr_Close ( tctx , b , & group_handle ) ,
2009-06-26 18:53:51 +04:00
" failed to close group handle " ) ;
return true ;
}
static bool test_samr_alias ( struct torture_context * tctx ,
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b ,
2009-06-26 18:53:51 +04:00
struct policy_handle * domain_handle ,
struct samr_SamEntry * a )
{
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing alias %s (%d) \n " , a - > name . string , a - > idx ) ;
2009-06-26 18:53:51 +04:00
2010-03-15 11:01:17 +03:00
torture_assert ( tctx , test_LookupRids ( tctx , b , domain_handle , a - > idx ) ,
2009-06-26 18:53:51 +04:00
" failed to call lookuprids " ) ;
{
struct samr_GetAliasMembership r ;
struct lsa_SidArray sids ;
struct samr_Ids rids ;
ZERO_STRUCT ( sids ) ;
r . in . domain_handle = domain_handle ;
r . in . sids = & sids ;
r . out . rids = & rids ;
2010-03-15 11:01:17 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_GetAliasMembership_r ( b , tctx , & r ) ,
2009-06-26 18:53:51 +04:00
" failed to get alias membership " ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" failed to get alias membership " ) ;
2009-06-26 18:53:51 +04:00
}
return true ;
}
static bool test_samr_domain ( struct torture_context * tctx ,
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b ,
2009-06-26 18:53:51 +04:00
uint32_t access_mask ,
const char * domain_name ,
struct policy_handle * connect_handle ,
struct policy_handle * domain_handle_p )
{
struct policy_handle domain_handle ;
struct dom_sid * domain_sid ;
if ( ! domain_name ) {
struct samr_EnumDomains r ;
uint32_t resume_handle ;
struct samr_SamArray * sam ;
uint32_t num_entries ;
int i ;
r . in . connect_handle = connect_handle ;
r . in . buf_size = 0xffff ;
r . in . resume_handle = & resume_handle ;
r . out . sam = & sam ;
r . out . num_entries = & num_entries ;
r . out . resume_handle = & resume_handle ;
2010-03-15 11:01:17 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_EnumDomains_r ( b , tctx , & r ) ,
2009-06-26 18:53:51 +04:00
" failed to enum domains " ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" failed to enum domains " ) ;
2009-06-26 18:53:51 +04:00
torture_assert_int_equal ( tctx , num_entries , 2 ,
" unexpected number of domains " ) ;
torture_assert ( tctx , sam ,
" no domain pointer returned " ) ;
for ( i = 0 ; i < sam - > count ; i + + ) {
if ( ! strequal ( sam - > entries [ i ] . name . string , " builtin " ) ) {
domain_name = sam - > entries [ i ] . name . string ;
break ;
}
}
torture_assert ( tctx , domain_name ,
" no domain found other than builtin found " ) ;
}
{
struct samr_LookupDomain r ;
struct dom_sid2 * sid ;
struct lsa_String name ;
name . string = talloc_strdup ( tctx , domain_name ) ;
r . in . connect_handle = connect_handle ;
r . in . domain_name = & name ;
r . out . sid = & sid ;
2010-03-15 11:01:17 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_LookupDomain_r ( b , tctx , & r ) ,
2009-06-26 18:53:51 +04:00
" failed to lookup domain " ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" failed to lookup domain " ) ;
2009-06-26 18:53:51 +04:00
domain_sid = dom_sid_dup ( tctx , sid ) ;
}
{
struct samr_OpenDomain r ;
r . in . connect_handle = connect_handle ;
r . in . access_mask = access_mask ;
r . in . sid = domain_sid ;
r . out . domain_handle = & domain_handle ;
2010-03-15 11:01:17 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_OpenDomain_r ( b , tctx , & r ) ,
2009-06-26 18:53:51 +04:00
" failed to open domain " ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" failed to open domain " ) ;
2009-06-26 18:53:51 +04:00
}
{
struct samr_QueryDomainInfo r ;
union samr_DomainInfo * info ;
uint32_t levels [ ] = { 1 , 2 , 8 , 12 } ;
int i ;
r . in . domain_handle = & domain_handle ;
r . out . info = & info ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
r . in . level = levels [ i ] ;
2010-03-15 11:01:17 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_QueryDomainInfo_r ( b , tctx , & r ) ,
2009-06-26 18:53:51 +04:00
talloc_asprintf ( tctx , " failed to query domain info level %d " , r . in . level ) ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result ,
talloc_asprintf ( tctx , " failed to query domain info level %d " , r . in . level ) ) ;
2009-06-26 18:53:51 +04:00
}
}
* domain_handle_p = domain_handle ;
return true ;
}
static void get_query_dispinfo_params ( int loop_count ,
uint32_t * max_entries ,
uint32_t * buf_size )
{
switch ( loop_count ) {
case 0 :
* max_entries = 512 ;
* buf_size = 16383 ;
break ;
case 1 :
* max_entries = 1024 ;
* buf_size = 32766 ;
break ;
case 2 :
* max_entries = 2048 ;
* buf_size = 65532 ;
break ;
case 3 :
* max_entries = 4096 ;
* buf_size = 131064 ;
break ;
default : /* loop_count >= 4 */
* max_entries = 4096 ;
* buf_size = 131071 ;
break ;
}
}
static bool test_samr_users ( struct torture_context * tctx ,
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b ,
2009-06-26 18:53:51 +04:00
uint32_t access_mask ,
struct policy_handle * domain_handle )
{
{
struct samr_QueryDisplayInfo r ;
uint32_t total_size ;
uint32_t returned_size ;
union samr_DispInfo info ;
int loop_count = 0 ;
r . in . domain_handle = domain_handle ;
r . in . level = 1 ;
r . in . start_idx = 0 ;
r . out . total_size = & total_size ;
r . out . returned_size = & returned_size ;
r . out . info = & info ;
do {
int i ;
r . in . max_entries = 0xffff ;
r . in . buf_size = 0xffff ;
get_query_dispinfo_params ( loop_count ,
& r . in . max_entries ,
& r . in . buf_size ) ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_QueryDisplayInfo_r ( b , tctx , & r ) ,
" QueryDisplayInfo failed " ) ;
if ( NT_STATUS_IS_ERR ( r . out . result ) ) {
torture_assert_ntstatus_ok ( tctx , r . out . result ,
2009-06-26 18:53:51 +04:00
" failed to call QueryDisplayInfo " ) ;
}
for ( i = 0 ; i < info . info1 . count ; i + + ) {
torture_assert ( tctx ,
2010-03-15 11:01:17 +03:00
test_user ( tctx , b , domain_handle , access_mask , & info . info1 . entries [ i ] ) ,
2009-06-26 18:53:51 +04:00
" failed to test user " ) ;
}
loop_count + + ;
r . in . start_idx + = info . info1 . count ;
2010-03-19 14:23:37 +03:00
} while ( NT_STATUS_EQUAL ( r . out . result , STATUS_MORE_ENTRIES ) ) ;
2009-06-26 18:53:51 +04:00
}
return true ;
}
static bool test_samr_groups ( struct torture_context * tctx ,
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b ,
2009-06-26 18:53:51 +04:00
uint32_t access_mask ,
struct policy_handle * domain_handle )
{
{
struct samr_EnumDomainGroups r ;
uint32_t resume_handle = 0 ;
struct samr_SamArray * sam ;
uint32_t num_entries ;
r . in . domain_handle = domain_handle ;
r . in . resume_handle = & resume_handle ;
r . in . max_size = 0xFFFF ;
r . out . sam = & sam ;
r . out . num_entries = & num_entries ;
r . out . resume_handle = & resume_handle ;
do {
int i ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_EnumDomainGroups_r ( b , tctx , & r ) ,
" EnumDomainGroups failed " ) ;
if ( NT_STATUS_IS_ERR ( r . out . result ) ) {
torture_assert_ntstatus_ok ( tctx , r . out . result ,
2009-06-26 18:53:51 +04:00
" failed to call EnumDomainGroups " ) ;
}
for ( i = 0 ; i < num_entries ; i + + ) {
torture_assert ( tctx ,
2010-03-15 11:01:17 +03:00
test_samr_group ( tctx , b , domain_handle , access_mask , & sam - > entries [ i ] ) ,
2009-06-26 18:53:51 +04:00
" failed to test group " ) ;
}
2010-03-19 14:23:37 +03:00
} while ( NT_STATUS_EQUAL ( r . out . result , STATUS_MORE_ENTRIES ) ) ;
2009-06-26 18:53:51 +04:00
}
return true ;
}
static bool test_samr_aliases ( struct torture_context * tctx ,
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b ,
2009-06-26 18:53:51 +04:00
uint32_t access_mask ,
struct policy_handle * domain_handle )
{
{
struct samr_EnumDomainAliases r ;
uint32_t resume_handle = 0 ;
struct samr_SamArray * sam ;
uint32_t num_entries ;
r . in . domain_handle = domain_handle ;
r . in . resume_handle = & resume_handle ;
r . in . max_size = 0xFFFF ;
r . out . sam = & sam ;
r . out . num_entries = & num_entries ;
r . out . resume_handle = & resume_handle ;
do {
int i ;
2010-03-19 14:23:37 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_EnumDomainAliases_r ( b , tctx , & r ) ,
" EnumDomainAliases failed " ) ;
if ( NT_STATUS_IS_ERR ( r . out . result ) ) {
torture_assert_ntstatus_ok ( tctx , r . out . result ,
2009-06-26 18:53:51 +04:00
" failed to call EnumDomainAliases " ) ;
}
for ( i = 0 ; i < num_entries ; i + + ) {
torture_assert ( tctx ,
2010-03-15 11:01:17 +03:00
test_samr_alias ( tctx , b , domain_handle , & sam - > entries [ i ] ) ,
2009-06-26 18:53:51 +04:00
" failed to test alias " ) ;
}
2010-03-19 14:23:37 +03:00
} while ( NT_STATUS_EQUAL ( r . out . result , STATUS_MORE_ENTRIES ) ) ;
2009-06-26 18:53:51 +04:00
}
return true ;
}
static bool torture_rpc_samr_workstation_query ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct cli_credentials * machine_credentials )
{
struct policy_handle connect_handle ;
struct policy_handle domain_handle ;
2010-03-15 11:01:17 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2009-06-26 18:53:51 +04:00
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 11:01:17 +03:00
torture_samr_Connect5 ( tctx , b , SEC_FLAG_MAXIMUM_ALLOWED ,
2009-06-26 18:53:51 +04:00
& connect_handle ) ,
" failed to connect to samr server " ) ;
torture_assert ( tctx ,
2010-03-15 11:01:17 +03:00
test_samr_domain ( tctx , b , SEC_FLAG_MAXIMUM_ALLOWED ,
2010-07-16 08:32:42 +04:00
lpcfg_workgroup ( tctx - > lp_ctx ) ,
2009-06-26 18:53:51 +04:00
& connect_handle , & domain_handle ) ,
" failed to test domain " ) ;
torture_assert ( tctx ,
2010-03-15 11:01:17 +03:00
test_samr_users ( tctx , b , SEC_FLAG_MAXIMUM_ALLOWED ,
2009-06-26 18:53:51 +04:00
& domain_handle ) ,
" failed to test users " ) ;
torture_assert ( tctx ,
2010-03-15 11:01:17 +03:00
test_samr_groups ( tctx , b , SEC_FLAG_MAXIMUM_ALLOWED ,
2009-06-26 18:53:51 +04:00
& domain_handle ) ,
" failed to test groups " ) ;
torture_assert ( tctx ,
2010-03-15 11:01:17 +03:00
test_samr_aliases ( tctx , b , SEC_FLAG_MAXIMUM_ALLOWED ,
2009-06-26 18:53:51 +04:00
& domain_handle ) ,
" failed to test aliases " ) ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 11:01:17 +03:00
torture_samr_Close ( tctx , b , & domain_handle ) ,
2009-06-26 18:53:51 +04:00
" failed to close domain handle " ) ;
torture_assert_ntstatus_ok ( tctx ,
2010-03-15 11:01:17 +03:00
torture_samr_Close ( tctx , b , & connect_handle ) ,
2009-06-26 18:53:51 +04:00
" failed to close connect handle " ) ;
return true ;
}
/* The purpose of this test is to verify that an account authenticated as a
* domain member workstation can query a DC for various remote read calls all
* opening objects while requesting SEC_FLAG_MAXIMUM_ALLOWED access rights on
* the object open calls . This is the behavior of winbind ( and most of samba ' s
* client code ) - gd */
struct torture_suite * torture_rpc_samr_workstation_auth ( TALLOC_CTX * mem_ctx )
{
2010-12-11 05:26:31 +03:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " samr.machine.auth " ) ;
2009-06-26 18:53:51 +04:00
struct torture_rpc_tcase * tcase ;
tcase = torture_suite_add_machine_workstation_rpc_iface_tcase ( suite , " samr " ,
& ndr_table_samr ,
TEST_MACHINENAME ) ;
torture_rpc_tcase_add_test_creds ( tcase , " workstation_query " ,
torture_rpc_samr_workstation_query ) ;
return suite ;
}