2006-08-28 00:41:29 +04:00
/*
Unix SMB / CIFS implementation .
Test suite for libnet calls .
Copyright ( C ) Rafal Szczesniak 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-08-28 00:41:29 +04: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-08-28 00:41:29 +04:00
*/
# include "includes.h"
# include "lib/cmdline/popt_common.h"
# include "lib/events/events.h"
# include "auth/credentials/credentials.h"
# include "libnet/libnet.h"
# include "librpc/gen_ndr/ndr_samr_c.h"
# include "librpc/gen_ndr/ndr_lsa_c.h"
# include "libcli/security/security.h"
# include "librpc/rpc/dcerpc.h"
# include "torture/torture.h"
# include "torture/rpc/rpc.h"
static BOOL test_opendomain_samr ( struct dcerpc_pipe * p , TALLOC_CTX * mem_ctx ,
2006-09-05 22:46:07 +04:00
struct policy_handle * handle , struct lsa_String * domname ,
2007-08-02 17:08:39 +04:00
uint32_t * access_mask , struct dom_sid * * sid )
2006-08-28 00:41:29 +04:00
{
NTSTATUS status ;
struct policy_handle h , domain_handle ;
struct samr_Connect r1 ;
struct samr_LookupDomain r2 ;
struct samr_OpenDomain r3 ;
printf ( " connecting \n " ) ;
2006-09-05 22:46:07 +04:00
* access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
2006-08-28 00:41:29 +04:00
r1 . in . system_name = 0 ;
2006-09-05 22:46:07 +04:00
r1 . in . access_mask = * access_mask ;
2006-08-28 00:41:29 +04:00
r1 . out . connect_handle = & h ;
status = dcerpc_samr_Connect ( p , mem_ctx , & r1 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Connect failed - %s \n " , nt_errstr ( status ) ) ;
return False ;
}
r2 . in . connect_handle = & h ;
r2 . in . domain_name = domname ;
printf ( " domain lookup on %s \n " , domname - > string ) ;
status = dcerpc_samr_LookupDomain ( p , mem_ctx , & r2 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " LookupDomain failed - %s \n " , nt_errstr ( status ) ) ;
return False ;
}
r3 . in . connect_handle = & h ;
2006-09-05 22:46:07 +04:00
r3 . in . access_mask = * access_mask ;
2007-08-02 17:08:39 +04:00
r3 . in . sid = * sid = r2 . out . sid ;
2006-08-28 00:41:29 +04:00
r3 . out . domain_handle = & domain_handle ;
printf ( " opening domain \n " ) ;
status = dcerpc_samr_OpenDomain ( p , mem_ctx , & r3 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " OpenDomain failed - %s \n " , nt_errstr ( status ) ) ;
return False ;
} else {
* handle = domain_handle ;
}
return True ;
}
static BOOL test_opendomain_lsa ( struct dcerpc_pipe * p , TALLOC_CTX * mem_ctx ,
2006-09-05 21:59:37 +04:00
struct policy_handle * handle , struct lsa_String * domname ,
uint32_t * access_mask )
2006-08-28 00:41:29 +04:00
{
NTSTATUS status ;
struct lsa_OpenPolicy2 open ;
struct lsa_ObjectAttribute attr ;
struct lsa_QosInfo qos ;
2006-09-05 21:59:37 +04:00
* access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
2006-08-28 00:41:29 +04:00
ZERO_STRUCT ( attr ) ;
ZERO_STRUCT ( qos ) ;
qos . len = 0 ;
qos . impersonation_level = 2 ;
qos . context_mode = 1 ;
qos . effective_only = 0 ;
attr . sec_qos = & qos ;
open . in . system_name = domname - > string ;
open . in . attr = & attr ;
2006-09-05 21:59:37 +04:00
open . in . access_mask = * access_mask ;
open . out . handle = handle ;
2006-08-28 00:41:29 +04:00
status = dcerpc_lsa_OpenPolicy2 ( p , mem_ctx , & open ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return False ;
}
return True ;
}
BOOL torture_domain_open_lsa ( struct torture_context * torture )
{
NTSTATUS status ;
2006-09-05 21:59:37 +04:00
BOOL ret = True ;
2006-08-28 00:41:29 +04:00
struct libnet_context * ctx ;
struct libnet_DomainOpen r ;
2007-01-02 04:39:53 +03:00
struct lsa_Close lsa_close ;
2006-09-05 21:59:37 +04:00
struct policy_handle h ;
2007-05-12 01:48:29 +04:00
const char * domain_name ;
/* we're accessing domain controller so the domain name should be
passed ( it ' s going to be resolved to dc name and address ) instead
of specific server name . */
domain_name = lp_workgroup ( ) ;
2006-08-28 00:41:29 +04:00
ctx = libnet_context_init ( NULL ) ;
if ( ctx = = NULL ) {
d_printf ( " failed to create libnet context \n " ) ;
return False ;
}
ctx - > cred = cmdline_credentials ;
2006-09-05 21:59:37 +04:00
ZERO_STRUCT ( r ) ;
2006-08-28 00:41:29 +04:00
r . in . type = DOMAIN_LSA ;
2007-05-12 01:48:29 +04:00
r . in . domain_name = domain_name ;
2006-08-28 00:41:29 +04:00
r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
status = libnet_DomainOpen ( ctx , torture , & r ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " failed to open domain on lsa service: %s \n " , nt_errstr ( status ) ) ;
2006-09-05 21:59:37 +04:00
ret = False ;
goto done ;
2006-08-28 00:41:29 +04:00
}
2007-01-02 04:39:53 +03:00
ZERO_STRUCT ( lsa_close ) ;
lsa_close . in . handle = & ctx - > lsa . handle ;
lsa_close . out . handle = & h ;
2006-09-05 21:59:37 +04:00
2007-01-02 04:39:53 +03:00
status = dcerpc_lsa_Close ( ctx - > lsa . pipe , ctx , & lsa_close ) ;
2006-09-05 21:59:37 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " failed to close domain on lsa service: %s \n " , nt_errstr ( status ) ) ;
ret = False ;
}
2006-08-28 00:41:29 +04:00
2006-09-05 21:59:37 +04:00
done :
talloc_free ( ctx ) ;
return ret ;
2006-08-28 00:41:29 +04:00
}
BOOL torture_domain_close_lsa ( struct torture_context * torture )
{
2006-09-05 21:59:37 +04:00
BOOL ret = True ;
2006-08-28 00:41:29 +04:00
NTSTATUS status ;
2006-09-10 14:43:31 +04:00
TALLOC_CTX * mem_ctx = NULL ;
2006-08-28 00:41:29 +04:00
struct libnet_context * ctx ;
struct lsa_String domain_name ;
struct dcerpc_binding * binding ;
const char * bindstr ;
2006-09-05 21:59:37 +04:00
uint32_t access_mask ;
struct policy_handle h ;
2006-08-28 00:41:29 +04:00
struct dcerpc_pipe * p ;
struct libnet_DomainClose r ;
2006-10-18 18:23:19 +04:00
bindstr = torture_setting_string ( torture , " binding " , NULL ) ;
2006-08-28 00:41:29 +04:00
status = dcerpc_parse_binding ( torture , bindstr , & binding ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " failed to parse binding string \n " ) ;
return False ;
}
ctx = libnet_context_init ( NULL ) ;
if ( ctx = = NULL ) {
d_printf ( " failed to create libnet context \n " ) ;
ret = False ;
goto done ;
}
ctx - > cred = cmdline_credentials ;
2006-09-05 21:59:37 +04:00
mem_ctx = talloc_init ( " torture_domain_close_lsa " ) ;
2007-08-20 01:23:03 +04:00
status = dcerpc_pipe_connect ( mem_ctx , & p , bindstr , & ndr_table_lsarpc ,
2006-09-05 21:59:37 +04:00
cmdline_credentials , NULL ) ;
2006-08-28 00:41:29 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-09-05 21:59:37 +04:00
d_printf ( " failed to connect to server %s: %s \n " , bindstr ,
nt_errstr ( status ) ) ;
2006-08-28 00:41:29 +04:00
ret = False ;
goto done ;
}
domain_name . string = lp_workgroup ( ) ;
2006-09-05 21:59:37 +04:00
if ( ! test_opendomain_lsa ( p , torture , & h , & domain_name , & access_mask ) ) {
d_printf ( " failed to open domain on lsa service \n " ) ;
2006-08-28 00:41:29 +04:00
ret = False ;
goto done ;
}
2006-09-05 21:59:37 +04:00
ctx - > lsa . pipe = p ;
ctx - > lsa . name = domain_name . string ;
ctx - > lsa . access_mask = access_mask ;
ctx - > lsa . handle = h ;
/* we have to use pipe's event context, otherwise the call will
2007-05-12 01:48:29 +04:00
hang indefinitely */
2006-09-05 21:59:37 +04:00
ctx - > event_ctx = p - > conn - > event_ctx ;
ZERO_STRUCT ( r ) ;
2006-08-28 00:41:29 +04:00
r . in . type = DOMAIN_LSA ;
r . in . domain_name = domain_name . string ;
status = libnet_DomainClose ( ctx , mem_ctx , & r ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
ret = False ;
2006-08-31 02:30:47 +04:00
goto done ;
2006-08-28 00:41:29 +04:00
}
done :
talloc_free ( mem_ctx ) ;
talloc_free ( ctx ) ;
return ret ;
}
BOOL torture_domain_open_samr ( struct torture_context * torture )
{
NTSTATUS status ;
const char * binding ;
struct libnet_context * ctx ;
2006-09-10 14:43:31 +04:00
struct event_context * evt_ctx = NULL ;
2006-08-28 00:41:29 +04:00
TALLOC_CTX * mem_ctx ;
struct policy_handle domain_handle , handle ;
struct libnet_DomainOpen io ;
struct samr_Close r ;
2007-05-12 01:48:29 +04:00
const char * domain_name ;
2006-08-28 00:41:29 +04:00
BOOL ret = True ;
mem_ctx = talloc_init ( " test_domainopen_lsa " ) ;
2006-10-18 18:23:19 +04:00
binding = torture_setting_string ( torture , " binding " , NULL ) ;
2006-08-28 00:41:29 +04:00
ctx = libnet_context_init ( evt_ctx ) ;
2006-09-05 22:46:07 +04:00
ctx - > cred = cmdline_credentials ;
2006-08-28 00:41:29 +04:00
2007-05-12 01:48:29 +04:00
/* we're accessing domain controller so the domain name should be
passed ( it ' s going to be resolved to dc name and address ) instead
of specific server name . */
domain_name = lp_workgroup ( ) ;
2006-08-28 00:41:29 +04:00
/*
* Testing synchronous version
*/
printf ( " opening domain \n " ) ;
io . in . type = DOMAIN_SAMR ;
2007-05-12 01:48:29 +04:00
io . in . domain_name = domain_name ;
2006-08-28 00:41:29 +04:00
io . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
status = libnet_DomainOpen ( ctx , mem_ctx , & io ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Composite domain open failed - %s \n " , nt_errstr ( status ) ) ;
ret = False ;
goto done ;
}
2006-09-05 22:46:07 +04:00
domain_handle = ctx - > samr . handle ;
2006-08-28 00:41:29 +04:00
r . in . handle = & domain_handle ;
r . out . handle = & handle ;
printf ( " closing domain handle \n " ) ;
status = dcerpc_samr_Close ( ctx - > samr . pipe , mem_ctx , & r ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Close failed - %s \n " , nt_errstr ( status ) ) ;
ret = False ;
goto done ;
}
done :
talloc_free ( mem_ctx ) ;
2006-09-05 22:46:07 +04:00
talloc_free ( ctx ) ;
return ret ;
}
BOOL torture_domain_close_samr ( struct torture_context * torture )
{
BOOL ret = True ;
NTSTATUS status ;
2007-04-29 16:32:17 +04:00
TALLOC_CTX * mem_ctx = NULL ;
2006-09-05 22:46:07 +04:00
struct libnet_context * ctx ;
struct lsa_String domain_name ;
struct dcerpc_binding * binding ;
const char * bindstr ;
uint32_t access_mask ;
struct policy_handle h ;
struct dcerpc_pipe * p ;
struct libnet_DomainClose r ;
2007-08-02 17:08:39 +04:00
struct dom_sid * sid ;
2006-08-28 00:41:29 +04:00
2006-10-18 18:23:19 +04:00
bindstr = torture_setting_string ( torture , " binding " , NULL ) ;
2006-09-05 22:46:07 +04:00
status = dcerpc_parse_binding ( torture , bindstr , & binding ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " failed to parse binding string \n " ) ;
return False ;
}
ctx = libnet_context_init ( NULL ) ;
if ( ctx = = NULL ) {
d_printf ( " failed to create libnet context \n " ) ;
ret = False ;
goto done ;
}
ctx - > cred = cmdline_credentials ;
mem_ctx = talloc_init ( " torture_domain_close_samr " ) ;
2007-08-20 01:23:03 +04:00
status = dcerpc_pipe_connect ( mem_ctx , & p , bindstr , & ndr_table_samr ,
2007-04-29 16:32:17 +04:00
ctx - > cred , NULL ) ;
2006-09-05 22:46:07 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " failed to connect to server %s: %s \n " , bindstr ,
nt_errstr ( status ) ) ;
ret = False ;
goto done ;
}
2007-08-02 17:08:39 +04:00
domain_name . string = talloc_strdup ( mem_ctx , lp_workgroup ( ) ) ;
2006-09-05 22:46:07 +04:00
2007-08-02 17:08:39 +04:00
if ( ! test_opendomain_samr ( p , torture , & h , & domain_name , & access_mask , & sid ) ) {
2006-09-05 22:46:07 +04:00
d_printf ( " failed to open domain on samr service \n " ) ;
ret = False ;
goto done ;
}
ctx - > samr . pipe = p ;
2007-08-02 17:08:39 +04:00
ctx - > samr . name = talloc_steal ( ctx , domain_name . string ) ;
2006-09-05 22:46:07 +04:00
ctx - > samr . access_mask = access_mask ;
ctx - > samr . handle = h ;
2007-08-02 17:08:39 +04:00
ctx - > samr . sid = talloc_steal ( ctx , sid ) ;
2006-09-05 22:46:07 +04:00
/* we have to use pipe's event context, otherwise the call will
2007-04-29 16:32:17 +04:00
hang indefinitely - this wouldn ' t be the case if pipe was opened
by means of libnet call */
2006-09-05 22:46:07 +04:00
ctx - > event_ctx = p - > conn - > event_ctx ;
ZERO_STRUCT ( r ) ;
r . in . type = DOMAIN_SAMR ;
r . in . domain_name = domain_name . string ;
status = libnet_DomainClose ( ctx , mem_ctx , & r ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
ret = False ;
goto done ;
}
done :
talloc_free ( mem_ctx ) ;
talloc_free ( ctx ) ;
2006-08-28 00:41:29 +04:00
return ret ;
}
2007-04-29 16:32:17 +04:00
BOOL torture_domain_list ( struct torture_context * torture )
{
BOOL ret = True ;
NTSTATUS status ;
TALLOC_CTX * mem_ctx = NULL ;
const char * bindstr ;
struct dcerpc_binding * binding ;
struct libnet_context * ctx ;
struct libnet_DomainList r ;
int i ;
bindstr = torture_setting_string ( torture , " binding " , NULL ) ;
status = dcerpc_parse_binding ( torture , bindstr , & binding ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " failed to parse binding string \n " ) ;
return False ;
}
ctx = libnet_context_init ( NULL ) ;
if ( ctx = = NULL ) {
d_printf ( " failed to create libnet context \n " ) ;
ret = False ;
goto done ;
}
ctx - > cred = cmdline_credentials ;
mem_ctx = talloc_init ( " torture_domain_close_samr " ) ;
2007-05-12 01:48:29 +04:00
/*
* querying the domain list using default buffer size
*/
ZERO_STRUCT ( r ) ;
r . in . hostname = binding - > host ;
status = libnet_DomainList ( ctx , mem_ctx , & r ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
ret = False ;
goto done ;
}
d_printf ( " Received list or domains (everything in one piece): \n " ) ;
for ( i = 0 ; i < r . out . count ; i + + ) {
d_printf ( " Name[%d]: %s \n " , i , r . out . domains [ i ] . name ) ;
}
/*
* querying the domain list using specified ( much smaller ) buffer size
*/
ctx - > samr . buf_size = 32 ;
2007-04-29 16:32:17 +04:00
ZERO_STRUCT ( r ) ;
r . in . hostname = binding - > host ;
status = libnet_DomainList ( ctx , mem_ctx , & r ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
ret = False ;
goto done ;
}
2007-05-12 01:48:29 +04:00
d_printf ( " Received list or domains (collected in more than one round): \n " ) ;
2007-04-29 16:32:17 +04:00
for ( i = 0 ; i < r . out . count ; i + + ) {
d_printf ( " Name[%d]: %s \n " , i , r . out . domains [ i ] . name ) ;
}
done :
d_printf ( " \n Status: %s \n " , nt_errstr ( status ) ) ;
talloc_free ( mem_ctx ) ;
talloc_free ( ctx ) ;
return ret ;
}