2006-01-08 15:29:11 +03:00
/*
Unix SMB / CIFS implementation .
test suite for lsa rpc lookup operations
Copyright ( C ) Volker Lendecke 2006
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-01-08 15:29:11 +03:00
( 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
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-01-08 15:29:11 +03:00
*/
# include "includes.h"
2010-04-14 00:06:51 +04:00
# include "torture/rpc/torture_rpc.h"
2006-03-15 02:35:30 +03:00
# include "librpc/gen_ndr/ndr_lsa_c.h"
2006-04-02 16:02:01 +04:00
# include "libcli/security/security.h"
2006-01-08 15:29:11 +03:00
2010-03-19 01:54:14 +03:00
static bool open_policy ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
2006-01-08 15:29:11 +03:00
struct policy_handle * * handle )
{
struct lsa_ObjectAttribute attr ;
struct lsa_QosInfo qos ;
struct lsa_OpenPolicy2 r ;
2010-03-19 01:54:14 +03:00
* handle = talloc ( tctx , struct policy_handle ) ;
2006-01-08 15:29:11 +03:00
if ( ! * handle ) {
2007-10-07 02:28:14 +04:00
return false ;
2006-01-08 15:29:11 +03:00
}
qos . len = 0 ;
qos . impersonation_level = 2 ;
qos . context_mode = 1 ;
qos . effective_only = 0 ;
attr . len = 0 ;
attr . root_dir = NULL ;
attr . object_name = NULL ;
attr . attributes = 0 ;
attr . sec_desc = NULL ;
attr . sec_qos = & qos ;
r . in . system_name = " \\ " ;
r . in . attr = & attr ;
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
r . out . handle = * handle ;
2010-03-19 02:09:46 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_lsa_OpenPolicy2_r ( b , tctx , & r ) ,
" OpenPolicy2 failed " ) ;
2006-01-08 15:29:11 +03:00
2010-03-19 01:54:14 +03:00
return NT_STATUS_IS_OK ( r . out . result ) ;
2006-01-08 15:29:11 +03:00
}
2010-03-19 01:54:14 +03:00
static bool get_domainsid ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
2006-01-08 15:29:11 +03:00
struct policy_handle * handle ,
struct dom_sid * * sid )
{
struct lsa_QueryInfoPolicy r ;
2008-10-24 17:05:57 +04:00
union lsa_PolicyInformation * info = NULL ;
2006-01-08 15:29:11 +03:00
r . in . level = LSA_POLICY_INFO_DOMAIN ;
r . in . handle = handle ;
2008-10-24 17:05:57 +04:00
r . out . info = & info ;
2006-01-08 15:29:11 +03:00
2010-03-19 01:54:14 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_lsa_QueryInfoPolicy_r ( b , tctx , & r ) ,
" QueryInfoPolicy failed " ) ;
2010-03-19 02:09:46 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result , " QueryInfoPolicy failed " ) ;
2006-01-08 15:29:11 +03:00
2008-10-24 17:05:57 +04:00
* sid = info - > domain . sid ;
2007-10-07 02:28:14 +04:00
return true ;
2006-01-08 15:29:11 +03:00
}
2010-03-19 01:54:14 +03:00
static NTSTATUS lookup_sids ( struct torture_context * tctx ,
uint16_t level ,
2010-03-11 14:00:34 +03:00
struct dcerpc_binding_handle * b ,
2006-01-08 15:29:11 +03:00
struct policy_handle * handle ,
struct dom_sid * * sids , uint32_t num_sids ,
struct lsa_TransNameArray * names )
{
struct lsa_LookupSids r ;
struct lsa_SidArray sidarray ;
2009-04-17 03:26:40 +04:00
struct lsa_RefDomainList * domains ;
2006-01-08 15:29:11 +03:00
uint32_t count = 0 ;
uint32_t i ;
2010-03-19 02:09:46 +03:00
NTSTATUS status ;
2006-01-08 15:29:11 +03:00
names - > count = 0 ;
names - > names = NULL ;
sidarray . num_sids = num_sids ;
2010-03-19 01:54:14 +03:00
sidarray . sids = talloc_array ( tctx , struct lsa_SidPtr , num_sids ) ;
2006-01-08 15:29:11 +03:00
for ( i = 0 ; i < num_sids ; i + + ) {
sidarray . sids [ i ] . sid = sids [ i ] ;
}
r . in . handle = handle ;
r . in . sids = & sidarray ;
r . in . names = names ;
r . in . level = level ;
r . in . count = & count ;
r . out . names = names ;
r . out . count = & count ;
2009-04-17 03:26:40 +04:00
r . out . domains = & domains ;
2006-01-08 15:29:11 +03:00
2010-03-19 02:09:46 +03:00
status = dcerpc_lsa_LookupSids_r ( b , tctx , & r ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return r . out . result ;
2006-01-08 15:29:11 +03:00
}
2010-03-19 01:54:14 +03:00
static bool test_lookupsids ( struct torture_context * tctx ,
struct dcerpc_binding_handle * b ,
2006-01-08 15:29:11 +03:00
struct policy_handle * handle ,
struct dom_sid * * sids , uint32_t num_sids ,
int level , NTSTATUS expected_result ,
enum lsa_SidType * types )
{
struct lsa_TransNameArray names ;
NTSTATUS status ;
uint32_t i ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2006-01-08 15:29:11 +03:00
2010-03-19 01:54:14 +03:00
status = lookup_sids ( tctx , level , b , handle , sids , num_sids ,
2006-01-08 15:29:11 +03:00
& names ) ;
if ( ! NT_STATUS_EQUAL ( status , expected_result ) ) {
printf ( " For level %d expected %s, got %s \n " ,
level , nt_errstr ( expected_result ) ,
nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2006-01-08 15:29:11 +03:00
}
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_OK ) & &
! NT_STATUS_EQUAL ( status , STATUS_SOME_UNMAPPED ) ) {
2007-10-07 02:28:14 +04:00
return true ;
2006-01-08 15:29:11 +03:00
}
for ( i = 0 ; i < num_sids ; i + + ) {
if ( names . names [ i ] . sid_type ! = types [ i ] ) {
printf ( " In level %d, for sid %s expected %s, "
" got %s \n " , level ,
2010-03-19 01:54:14 +03:00
dom_sid_string ( tctx , sids [ i ] ) ,
2006-01-08 15:29:11 +03:00
sid_type_lookup ( types [ i ] ) ,
sid_type_lookup ( names . names [ i ] . sid_type ) ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2006-01-08 15:29:11 +03:00
}
}
return ret ;
}
2010-03-11 14:00:34 +03:00
static bool get_downleveltrust ( struct torture_context * tctx , struct dcerpc_binding_handle * b ,
2006-01-08 16:26:04 +03:00
struct policy_handle * handle ,
struct dom_sid * * sid )
{
struct lsa_EnumTrustDom r ;
uint32_t resume_handle = 0 ;
struct lsa_DomainList domains ;
int i ;
r . in . handle = handle ;
r . in . resume_handle = & resume_handle ;
r . in . max_size = 1000 ;
r . out . domains = & domains ;
r . out . resume_handle = & resume_handle ;
2010-03-19 02:09:46 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_lsa_EnumTrustDom_r ( b , tctx , & r ) ,
" EnumTrustDom failed " ) ;
2006-01-08 16:26:04 +03:00
2010-03-19 02:09:46 +03:00
if ( NT_STATUS_EQUAL ( r . out . result , NT_STATUS_NO_MORE_ENTRIES ) )
2007-08-31 17:30:47 +04:00
torture_fail ( tctx , " no trusts " ) ;
2006-01-08 16:26:04 +03:00
if ( domains . count = = 0 ) {
2007-08-31 17:30:47 +04:00
torture_fail ( tctx , " no trusts " ) ;
2006-01-08 16:26:04 +03:00
}
for ( i = 0 ; i < domains . count ; i + + ) {
struct lsa_QueryTrustedDomainInfoBySid q ;
2008-10-21 04:34:45 +04:00
union lsa_TrustedDomainInfo * info = NULL ;
2006-01-08 16:26:04 +03:00
if ( domains . domains [ i ] . sid = = NULL )
continue ;
q . in . handle = handle ;
q . in . dom_sid = domains . domains [ i ] . sid ;
q . in . level = 6 ;
2008-10-21 04:34:45 +04:00
q . out . info = & info ;
2010-03-19 02:09:46 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_lsa_QueryTrustedDomainInfoBySid_r ( b , tctx , & q ) ,
" QueryTrustedDomainInfoBySid failed " ) ;
if ( ! NT_STATUS_IS_OK ( q . out . result ) ) continue ;
2006-01-08 16:26:04 +03:00
2008-10-21 04:34:45 +04:00
if ( ( info - > info_ex . trust_direction & 2 ) & &
( info - > info_ex . trust_type = = 1 ) ) {
2006-01-08 16:26:04 +03:00
* sid = domains . domains [ i ] . sid ;
2007-10-07 02:28:14 +04:00
return true ;
2006-01-08 16:26:04 +03:00
}
}
2007-08-31 17:30:47 +04:00
torture_fail ( tctx , " I need a AD DC with an outgoing trust to NT4 " ) ;
2006-01-08 16:26:04 +03:00
}
# define NUM_SIDS 8
2006-01-08 15:29:11 +03:00
2007-08-31 17:30:47 +04:00
bool torture_rpc_lsa_lookup ( struct torture_context * torture )
2006-01-08 15:29:11 +03:00
{
NTSTATUS status ;
struct dcerpc_pipe * p ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2006-01-08 15:29:11 +03:00
struct policy_handle * handle ;
2009-09-29 13:49:50 +04:00
struct dom_sid * dom_sid = NULL ;
struct dom_sid * trusted_sid = NULL ;
2006-01-08 15:29:11 +03:00
struct dom_sid * sids [ NUM_SIDS ] ;
2010-03-11 14:00:34 +03:00
struct dcerpc_binding_handle * b ;
2014-01-30 22:05:06 +04:00
enum dcerpc_transport_t transport ;
2006-01-08 15:29:11 +03:00
2007-08-28 16:54:27 +04:00
status = torture_rpc_connection ( torture , & p , & ndr_table_lsarpc ) ;
2006-01-08 15:29:11 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-08-31 17:30:47 +04:00
torture_fail ( torture , " unable to connect to table " ) ;
2006-01-08 15:29:11 +03:00
}
2010-03-11 14:00:34 +03:00
b = p - > binding_handle ;
2024-09-17 23:41:16 +03:00
transport = dcerpc_binding_handle_get_transport ( b ) ;
2006-01-08 15:29:11 +03:00
2014-01-30 22:05:06 +04:00
if ( transport ! = NCACN_NP & & transport ! = NCALRPC ) {
2012-06-25 21:06:34 +04:00
torture_comment ( torture ,
" torture_rpc_lsa_lookup is only available "
" over NCACN_NP or NCALRPC " ) ;
return true ;
}
2010-03-11 14:00:34 +03:00
ret & = open_policy ( torture , b , & handle ) ;
2007-08-31 17:30:47 +04:00
if ( ! ret ) return false ;
2006-01-08 15:29:11 +03:00
2010-03-11 14:00:34 +03:00
ret & = get_domainsid ( torture , b , handle , & dom_sid ) ;
2007-08-31 17:30:47 +04:00
if ( ! ret ) return false ;
2006-01-08 15:29:11 +03:00
2010-03-11 14:00:34 +03:00
ret & = get_downleveltrust ( torture , b , handle , & trusted_sid ) ;
2007-08-31 17:30:47 +04:00
if ( ! ret ) return false ;
2006-01-08 16:26:04 +03:00
2007-08-31 17:30:47 +04:00
torture_comment ( torture , " domain sid: %s \n " ,
dom_sid_string ( torture , dom_sid ) ) ;
2006-01-08 15:29:11 +03:00
2007-08-31 17:30:47 +04:00
sids [ 0 ] = dom_sid_parse_talloc ( torture , " S-1-1-0 " ) ;
sids [ 1 ] = dom_sid_parse_talloc ( torture , " S-1-5-4 " ) ;
sids [ 2 ] = dom_sid_parse_talloc ( torture , " S-1-5-32 " ) ;
sids [ 3 ] = dom_sid_parse_talloc ( torture , " S-1-5-32-545 " ) ;
sids [ 4 ] = dom_sid_dup ( torture , dom_sid ) ;
sids [ 5 ] = dom_sid_add_rid ( torture , dom_sid , 512 ) ;
sids [ 6 ] = dom_sid_dup ( torture , trusted_sid ) ;
sids [ 7 ] = dom_sid_add_rid ( torture , trusted_sid , 512 ) ;
2006-01-08 15:29:11 +03:00
2010-03-11 14:00:34 +03:00
ret & = test_lookupsids ( torture , b , handle , sids , NUM_SIDS , 0 ,
2006-01-08 15:29:11 +03:00
NT_STATUS_INVALID_PARAMETER , NULL ) ;
{
enum lsa_SidType types [ NUM_SIDS ] =
{ SID_NAME_WKN_GRP , SID_NAME_WKN_GRP , SID_NAME_DOMAIN ,
2006-01-08 16:26:04 +03:00
SID_NAME_ALIAS , SID_NAME_DOMAIN , SID_NAME_DOM_GRP ,
SID_NAME_DOMAIN , SID_NAME_DOM_GRP } ;
2006-01-08 15:29:11 +03:00
2010-03-11 14:00:34 +03:00
ret & = test_lookupsids ( torture , b , handle , sids , NUM_SIDS , 1 ,
2006-01-08 15:29:11 +03:00
NT_STATUS_OK , types ) ;
}
{
enum lsa_SidType types [ NUM_SIDS ] =
{ SID_NAME_UNKNOWN , SID_NAME_UNKNOWN ,
SID_NAME_UNKNOWN , SID_NAME_UNKNOWN ,
2006-01-08 16:26:04 +03:00
SID_NAME_DOMAIN , SID_NAME_DOM_GRP ,
2006-01-08 15:29:11 +03:00
SID_NAME_DOMAIN , SID_NAME_DOM_GRP } ;
2010-03-11 14:00:34 +03:00
ret & = test_lookupsids ( torture , b , handle , sids , NUM_SIDS , 2 ,
2006-01-08 15:29:11 +03:00
STATUS_SOME_UNMAPPED , types ) ;
}
{
enum lsa_SidType types [ NUM_SIDS ] =
{ SID_NAME_UNKNOWN , SID_NAME_UNKNOWN ,
SID_NAME_UNKNOWN , SID_NAME_UNKNOWN ,
2006-01-08 16:26:04 +03:00
SID_NAME_DOMAIN , SID_NAME_DOM_GRP ,
SID_NAME_UNKNOWN , SID_NAME_UNKNOWN } ;
2010-03-11 14:00:34 +03:00
ret & = test_lookupsids ( torture , b , handle , sids , NUM_SIDS , 3 ,
2006-01-08 15:29:11 +03:00
STATUS_SOME_UNMAPPED , types ) ;
}
{
enum lsa_SidType types [ NUM_SIDS ] =
{ SID_NAME_UNKNOWN , SID_NAME_UNKNOWN ,
SID_NAME_UNKNOWN , SID_NAME_UNKNOWN ,
2006-01-08 16:26:04 +03:00
SID_NAME_DOMAIN , SID_NAME_DOM_GRP ,
SID_NAME_UNKNOWN , SID_NAME_UNKNOWN } ;
2010-03-11 14:00:34 +03:00
ret & = test_lookupsids ( torture , b , handle , sids , NUM_SIDS , 4 ,
2006-01-08 15:29:11 +03:00
STATUS_SOME_UNMAPPED , types ) ;
}
2010-03-11 14:00:34 +03:00
ret & = test_lookupsids ( torture , b , handle , sids , NUM_SIDS , 5 ,
2006-01-08 15:29:11 +03:00
NT_STATUS_NONE_MAPPED , NULL ) ;
{
enum lsa_SidType types [ NUM_SIDS ] =
{ SID_NAME_UNKNOWN , SID_NAME_UNKNOWN ,
SID_NAME_UNKNOWN , SID_NAME_UNKNOWN ,
2006-01-08 16:26:04 +03:00
SID_NAME_DOMAIN , SID_NAME_DOM_GRP ,
SID_NAME_UNKNOWN , SID_NAME_UNKNOWN } ;
2010-03-11 14:00:34 +03:00
ret & = test_lookupsids ( torture , b , handle , sids , NUM_SIDS , 6 ,
2006-01-08 15:29:11 +03:00
STATUS_SOME_UNMAPPED , types ) ;
}
2010-03-11 14:00:34 +03:00
ret & = test_lookupsids ( torture , b , handle , sids , NUM_SIDS , 7 ,
2006-01-08 15:29:11 +03:00
NT_STATUS_INVALID_PARAMETER , NULL ) ;
2010-03-11 14:00:34 +03:00
ret & = test_lookupsids ( torture , b , handle , sids , NUM_SIDS , 8 ,
2006-01-08 15:29:11 +03:00
NT_STATUS_INVALID_PARAMETER , NULL ) ;
2010-03-11 14:00:34 +03:00
ret & = test_lookupsids ( torture , b , handle , sids , NUM_SIDS , 9 ,
2006-01-08 15:29:11 +03:00
NT_STATUS_INVALID_PARAMETER , NULL ) ;
2010-03-11 14:00:34 +03:00
ret & = test_lookupsids ( torture , b , handle , sids , NUM_SIDS , 10 ,
2006-01-08 15:29:11 +03:00
NT_STATUS_INVALID_PARAMETER , NULL ) ;
return ret ;
}
2009-04-17 03:28:41 +04:00
static bool test_LookupSidsReply ( struct torture_context * tctx ,
struct dcerpc_pipe * p )
{
2018-01-26 02:38:32 +03:00
struct policy_handle * handle = NULL ;
2009-04-17 03:28:41 +04:00
2018-01-26 02:38:32 +03:00
struct dom_sid * * sids = NULL ;
2009-04-17 03:28:41 +04:00
uint32_t num_sids = 1 ;
struct lsa_LookupSids r ;
struct lsa_SidArray sidarray ;
struct lsa_RefDomainList * domains = NULL ;
struct lsa_TransNameArray names ;
uint32_t count = 0 ;
uint32_t i ;
const char * dom_sid = " S-1-5-21-1111111111-2222222222-3333333333 " ;
const char * dom_admin_sid ;
2010-03-11 14:00:34 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2024-09-17 23:41:16 +03:00
enum dcerpc_transport_t transport =
dcerpc_binding_handle_get_transport ( b ) ;
2009-04-17 03:28:41 +04:00
2018-01-26 02:38:32 +03:00
ZERO_STRUCT ( r ) ;
ZERO_STRUCT ( sidarray ) ;
ZERO_STRUCT ( names ) ;
2014-01-30 22:05:06 +04:00
if ( transport ! = NCACN_NP & & transport ! = NCALRPC ) {
2012-06-25 21:06:34 +04:00
torture_comment ( tctx ,
" test_LookupSidsReply is only available "
" over NCACN_NP or NCALRPC " ) ;
return true ;
}
2010-03-11 14:00:34 +03:00
if ( ! open_policy ( tctx , b , & handle ) ) {
2009-04-17 03:28:41 +04:00
return false ;
}
dom_admin_sid = talloc_asprintf ( tctx , " %s-%d " , dom_sid , 512 ) ;
2018-01-26 02:38:32 +03:00
sids = talloc_zero_array ( tctx , struct dom_sid * , num_sids ) ;
2009-04-17 03:28:41 +04:00
sids [ 0 ] = dom_sid_parse_talloc ( tctx , dom_admin_sid ) ;
names . count = 0 ;
names . names = NULL ;
sidarray . num_sids = num_sids ;
2018-01-26 02:38:32 +03:00
sidarray . sids = talloc_zero_array ( tctx , struct lsa_SidPtr , num_sids ) ;
2009-04-17 03:28:41 +04:00
for ( i = 0 ; i < num_sids ; i + + ) {
sidarray . sids [ i ] . sid = sids [ i ] ;
}
r . in . handle = handle ;
r . in . sids = & sidarray ;
r . in . names = & names ;
r . in . level = LSA_LOOKUP_NAMES_ALL ;
r . in . count = & count ;
r . out . names = & names ;
r . out . count = & count ;
r . out . domains = & domains ;
2010-03-19 02:09:46 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_lsa_LookupSids_r ( b , tctx , & r ) ,
" LookupSids failed " ) ;
2009-04-17 03:28:41 +04:00
2010-03-19 02:09:46 +03:00
torture_assert_ntstatus_equal ( tctx , r . out . result , NT_STATUS_NONE_MAPPED ,
2009-04-17 03:28:41 +04:00
" unexpected error code " ) ;
torture_assert_int_equal ( tctx , names . count , num_sids ,
" unexpected names count " ) ;
torture_assert ( tctx , names . names ,
" unexpected names pointer " ) ;
torture_assert_str_equal ( tctx , names . names [ 0 ] . name . string , dom_admin_sid ,
" unexpected names[0].string " ) ;
#if 0
/* vista sp1 passes, w2k3 sp2 fails */
torture_assert_int_equal ( tctx , domains - > count , num_sids ,
" unexpected domains count " ) ;
torture_assert ( tctx , domains - > domains ,
" unexpected domains pointer " ) ;
torture_assert_str_equal ( tctx , dom_sid_string ( tctx , domains - > domains [ 0 ] . sid ) , dom_sid ,
" unexpected domain sid " ) ;
# endif
return true ;
}
/* check for lookup sids results */
struct torture_suite * torture_rpc_lsa_lookup_sids ( TALLOC_CTX * mem_ctx )
{
struct torture_suite * suite ;
struct torture_rpc_tcase * tcase ;
2010-12-11 05:26:31 +03:00
suite = torture_suite_create ( mem_ctx , " lsa.lookupsids " ) ;
2009-04-17 03:28:41 +04:00
tcase = torture_suite_add_rpc_iface_tcase ( suite , " lsa " ,
& ndr_table_lsarpc ) ;
torture_rpc_tcase_add_test ( tcase , " LookupSidsReply " , test_LookupSidsReply ) ;
return suite ;
}