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"
# include "torture/torture.h"
# include "lib/events/events.h"
2006-03-14 18:02:05 +03:00
# include "libnet/libnet_join.h"
# include "torture/rpc/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
2007-10-07 02:28:14 +04:00
static bool open_policy ( TALLOC_CTX * mem_ctx , struct dcerpc_pipe * p ,
2006-01-08 15:29:11 +03:00
struct policy_handle * * handle )
{
struct lsa_ObjectAttribute attr ;
struct lsa_QosInfo qos ;
struct lsa_OpenPolicy2 r ;
NTSTATUS status ;
* handle = talloc ( mem_ctx , struct policy_handle ) ;
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 ;
status = dcerpc_lsa_OpenPolicy2 ( p , mem_ctx , & r ) ;
return NT_STATUS_IS_OK ( status ) ;
}
2007-10-07 02:28:14 +04:00
static bool get_domainsid ( TALLOC_CTX * mem_ctx , struct dcerpc_pipe * p ,
2006-01-08 15:29:11 +03:00
struct policy_handle * handle ,
struct dom_sid * * sid )
{
struct lsa_QueryInfoPolicy r ;
NTSTATUS status ;
r . in . level = LSA_POLICY_INFO_DOMAIN ;
r . in . handle = handle ;
status = dcerpc_lsa_QueryInfoPolicy ( p , mem_ctx , & r ) ;
2007-10-07 02:28:14 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) return false ;
2006-01-08 15:29:11 +03:00
* sid = r . out . info - > domain . sid ;
2007-10-07 02:28:14 +04:00
return true ;
2006-01-08 15:29:11 +03:00
}
static NTSTATUS lookup_sids ( TALLOC_CTX * mem_ctx , uint16_t level ,
struct dcerpc_pipe * p ,
struct policy_handle * handle ,
struct dom_sid * * sids , uint32_t num_sids ,
struct lsa_TransNameArray * names )
{
struct lsa_LookupSids r ;
struct lsa_SidArray sidarray ;
uint32_t count = 0 ;
uint32_t i ;
names - > count = 0 ;
names - > names = NULL ;
sidarray . num_sids = num_sids ;
sidarray . sids = talloc_array ( mem_ctx , struct lsa_SidPtr , num_sids ) ;
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 ;
return dcerpc_lsa_LookupSids ( p , mem_ctx , & r ) ;
}
2006-01-08 15:44:41 +03:00
static const char * sid_type_lookup ( enum lsa_SidType r )
2006-01-08 15:29:11 +03:00
{
switch ( r ) {
case SID_NAME_USE_NONE : return " SID_NAME_USE_NONE " ; break ;
case SID_NAME_USER : return " SID_NAME_USER " ; break ;
case SID_NAME_DOM_GRP : return " SID_NAME_DOM_GRP " ; break ;
case SID_NAME_DOMAIN : return " SID_NAME_DOMAIN " ; break ;
case SID_NAME_ALIAS : return " SID_NAME_ALIAS " ; break ;
case SID_NAME_WKN_GRP : return " SID_NAME_WKN_GRP " ; break ;
case SID_NAME_DELETED : return " SID_NAME_DELETED " ; break ;
case SID_NAME_INVALID : return " SID_NAME_INVALID " ; break ;
case SID_NAME_UNKNOWN : return " SID_NAME_UNKNOWN " ; break ;
2007-08-31 17:30:47 +04:00
case SID_NAME_COMPUTER : return " SID_NAME_COMPUTER " ; break ;
2006-01-08 15:29:11 +03:00
}
return " Invalid sid type \n " ;
}
2007-10-07 02:28:14 +04:00
static bool test_lookupsids ( TALLOC_CTX * mem_ctx , struct dcerpc_pipe * p ,
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
status = lookup_sids ( mem_ctx , level , p , handle , sids , num_sids ,
& 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 ,
dom_sid_string ( mem_ctx , sids [ i ] ) ,
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 ;
}
2007-10-07 02:28:14 +04:00
static bool get_downleveltrust ( struct torture_context * tctx , struct dcerpc_pipe * p ,
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 ;
NTSTATUS status ;
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 ;
2007-08-31 17:30:47 +04:00
status = dcerpc_lsa_EnumTrustDom ( p , tctx , & r ) ;
2006-01-08 16:26:04 +03:00
2007-08-31 17:30:47 +04:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_NO_MORE_ENTRIES ) )
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 ;
if ( domains . domains [ i ] . sid = = NULL )
continue ;
q . in . handle = handle ;
q . in . dom_sid = domains . domains [ i ] . sid ;
q . in . level = 6 ;
2007-08-31 17:30:47 +04:00
status = dcerpc_lsa_QueryTrustedDomainInfoBySid ( p , tctx , & q ) ;
2006-01-08 16:26:04 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) continue ;
if ( ( q . out . info - > info_ex . trust_direction & 2 ) & &
( q . out . info - > info_ex . trust_type = = 1 ) ) {
* 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 ;
struct dom_sid * dom_sid ;
2006-01-08 16:26:04 +03:00
struct dom_sid * trusted_sid ;
2006-01-08 15:29:11 +03:00
struct dom_sid * sids [ NUM_SIDS ] ;
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
}
2007-08-31 17:30:47 +04:00
ret & = open_policy ( torture , p , & handle ) ;
if ( ! ret ) return false ;
2006-01-08 15:29:11 +03:00
2007-08-31 17:30:47 +04:00
ret & = get_domainsid ( torture , p , handle , & dom_sid ) ;
if ( ! ret ) return false ;
2006-01-08 15:29:11 +03:00
2007-08-31 17:30:47 +04:00
ret & = get_downleveltrust ( torture , p , handle , & trusted_sid ) ;
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
2007-08-31 17:30:47 +04:00
ret & = test_lookupsids ( torture , p , 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
2007-08-31 17:30:47 +04:00
ret & = test_lookupsids ( torture , p , 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 } ;
2007-08-31 17:30:47 +04:00
ret & = test_lookupsids ( torture , p , 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 } ;
2007-08-31 17:30:47 +04:00
ret & = test_lookupsids ( torture , p , 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 } ;
2007-08-31 17:30:47 +04:00
ret & = test_lookupsids ( torture , p , handle , sids , NUM_SIDS , 4 ,
2006-01-08 15:29:11 +03:00
STATUS_SOME_UNMAPPED , types ) ;
}
2007-08-31 17:30:47 +04:00
ret & = test_lookupsids ( torture , p , 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 } ;
2007-08-31 17:30:47 +04:00
ret & = test_lookupsids ( torture , p , handle , sids , NUM_SIDS , 6 ,
2006-01-08 15:29:11 +03:00
STATUS_SOME_UNMAPPED , types ) ;
}
2007-08-31 17:30:47 +04:00
ret & = test_lookupsids ( torture , p , handle , sids , NUM_SIDS , 7 ,
2006-01-08 15:29:11 +03:00
NT_STATUS_INVALID_PARAMETER , NULL ) ;
2007-08-31 17:30:47 +04:00
ret & = test_lookupsids ( torture , p , handle , sids , NUM_SIDS , 8 ,
2006-01-08 15:29:11 +03:00
NT_STATUS_INVALID_PARAMETER , NULL ) ;
2007-08-31 17:30:47 +04:00
ret & = test_lookupsids ( torture , p , handle , sids , NUM_SIDS , 9 ,
2006-01-08 15:29:11 +03:00
NT_STATUS_INVALID_PARAMETER , NULL ) ;
2007-08-31 17:30:47 +04:00
ret & = test_lookupsids ( torture , p , handle , sids , NUM_SIDS , 10 ,
2006-01-08 15:29:11 +03:00
NT_STATUS_INVALID_PARAMETER , NULL ) ;
return ret ;
}