2011-12-14 02:30:21 +04:00
/*
2004-06-06 11:14:10 +04:00
Unix SMB / CIFS implementation .
test suite for schannel operations
Copyright ( C ) Andrew Tridgell 2004
2011-12-14 02:30:21 +04:00
2004-06-06 11:14:10 +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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2004-06-06 11:14:10 +04:00
( at your option ) any later version .
2011-12-14 02:30:21 +04:00
2004-06-06 11:14:10 +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 .
2011-12-14 02:30:21 +04:00
2004-06-06 11:14:10 +04:00
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/>.
2004-06-06 11:14:10 +04:00
*/
# include "includes.h"
2006-03-15 02:35:30 +03:00
# include "librpc/gen_ndr/ndr_netlogon_c.h"
# include "librpc/gen_ndr/ndr_lsa_c.h"
# include "librpc/gen_ndr/ndr_samr_c.h"
2006-03-14 04:29:56 +03:00
# include "auth/credentials/credentials.h"
2010-04-14 00:06:51 +04:00
# include "torture/rpc/torture_rpc.h"
2006-02-08 02:49:35 +03:00
# include "lib/cmdline/popt_common.h"
2011-07-21 07:20:26 +04:00
# include "auth/gensec/schannel.h"
2009-09-29 13:49:50 +04:00
# include "../libcli/auth/schannel.h"
2006-03-14 18:02:05 +03:00
# include "libcli/auth/libcli_auth.h"
2006-04-02 16:02:01 +04:00
# include "libcli/security/security.h"
2007-05-23 11:44:51 +04:00
# include "system/filesys.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2008-04-02 06:53:27 +04:00
# include "librpc/rpc/dcerpc_proto.h"
# include "auth/gensec/gensec.h"
2008-05-13 11:10:25 +04:00
# include "libcli/composite/composite.h"
# include "lib/events/events.h"
2004-06-06 11:14:10 +04:00
2005-10-25 16:14:08 +04:00
# define TEST_MACHINE_NAME "schannel"
2004-06-06 11:14:10 +04:00
2006-02-08 02:49:35 +03:00
/*
try a netlogon SamLogon
*/
2011-12-14 02:30:21 +04:00
bool test_netlogon_ex_ops ( struct dcerpc_pipe * p , struct torture_context * tctx ,
struct cli_credentials * credentials ,
2009-04-06 16:54:44 +04:00
struct netlogon_creds_CredentialState * creds )
2006-02-08 02:49:35 +03:00
{
NTSTATUS status ;
struct netr_LogonSamLogonEx r ;
struct netr_NetworkInfo ninfo ;
2008-10-28 21:03:50 +03:00
union netr_LogonLevel logon ;
union netr_Validation validation ;
uint8_t authoritative = 0 ;
uint32_t _flags = 0 ;
2006-02-08 02:49:35 +03:00
DATA_BLOB names_blob , chal , lm_resp , nt_resp ;
int i ;
int flags = CLI_CRED_NTLM_AUTH ;
2010-03-16 13:10:16 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2010-07-16 08:32:42 +04:00
if ( lpcfg_client_lanman_auth ( tctx - > lp_ctx ) ) {
2006-02-08 02:49:35 +03:00
flags | = CLI_CRED_LANMAN_AUTH ;
}
2010-07-16 08:32:42 +04:00
if ( lpcfg_client_ntlmv2_auth ( tctx - > lp_ctx ) ) {
2006-02-08 02:49:35 +03:00
flags | = CLI_CRED_NTLMv2_AUTH ;
}
2011-12-14 02:30:21 +04:00
cli_credentials_get_ntlm_username_domain ( cmdline_credentials , tctx ,
2006-02-08 02:49:35 +03:00
& ninfo . identity_info . account_name . string ,
& ninfo . identity_info . domain_name . string ) ;
2011-12-14 02:30:21 +04:00
generate_random_buffer ( ninfo . challenge ,
2006-02-08 02:49:35 +03:00
sizeof ( ninfo . challenge ) ) ;
2011-12-14 02:30:21 +04:00
chal = data_blob_const ( ninfo . challenge ,
2006-02-08 02:49:35 +03:00
sizeof ( ninfo . challenge ) ) ;
2011-12-14 02:30:21 +04:00
names_blob = NTLMv2_generate_names_blob ( tctx , cli_credentials_get_workstation ( credentials ) ,
2006-02-08 02:49:35 +03:00
cli_credentials_get_domain ( credentials ) ) ;
2011-12-14 02:30:21 +04:00
status = cli_credentials_get_ntlm_response ( cmdline_credentials , tctx ,
& flags ,
2006-02-08 02:49:35 +03:00
chal ,
names_blob ,
& lm_resp , & nt_resp ,
NULL , NULL ) ;
2011-12-14 02:30:21 +04:00
torture_assert_ntstatus_ok ( tctx , status ,
2007-09-01 02:34:52 +04:00
" cli_credentials_get_ntlm_response failed " ) ;
2006-02-08 02:49:35 +03:00
ninfo . lm . data = lm_resp . data ;
ninfo . lm . length = lm_resp . length ;
ninfo . nt . data = nt_resp . data ;
ninfo . nt . length = nt_resp . length ;
ninfo . identity_info . parameter_control = 0 ;
ninfo . identity_info . logon_id_low = 0 ;
ninfo . identity_info . logon_id_high = 0 ;
ninfo . identity_info . workstation . string = cli_credentials_get_workstation ( credentials ) ;
2008-10-28 21:03:50 +03:00
logon . network = & ninfo ;
2007-09-01 02:34:52 +04:00
r . in . server_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2006-02-21 03:07:59 +03:00
r . in . computer_name = cli_credentials_get_workstation ( credentials ) ;
2006-02-08 02:49:35 +03:00
r . in . logon_level = 2 ;
2008-10-28 21:03:50 +03:00
r . in . logon = & logon ;
r . in . flags = & _flags ;
r . out . validation = & validation ;
r . out . authoritative = & authoritative ;
r . out . flags = & _flags ;
2006-02-08 02:49:35 +03:00
2011-12-14 02:30:21 +04:00
torture_comment ( tctx ,
" Testing LogonSamLogonEx with name %s \n " ,
2007-09-01 02:34:52 +04:00
ninfo . identity_info . account_name . string ) ;
2011-12-14 02:30:21 +04:00
2006-02-08 02:49:35 +03:00
for ( i = 2 ; i < 3 ; i + + ) {
r . in . validation_level = i ;
2011-12-14 02:30:21 +04:00
2010-03-19 16:17:18 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_netr_LogonSamLogonEx_r ( b , tctx , & r ) ,
" LogonSamLogon failed " ) ;
torture_assert_ntstatus_ok ( tctx , r . out . result , " LogonSamLogon failed " ) ;
2006-02-08 02:49:35 +03:00
}
2007-09-01 02:34:52 +04:00
return true ;
2006-02-08 02:49:35 +03:00
}
2004-06-06 11:58:16 +04:00
/*
do some samr ops using the schannel connection
*/
2007-09-01 02:34:52 +04:00
static bool test_samr_ops ( struct torture_context * tctx ,
2010-03-16 13:10:16 +03:00
struct dcerpc_binding_handle * b )
2004-06-06 11:14:10 +04:00
{
struct samr_GetDomPwInfo r ;
2008-11-05 03:34:55 +03:00
struct samr_PwInfo info ;
2008-12-24 01:22:57 +03:00
struct samr_Connect connect_r ;
2005-08-03 00:08:23 +04:00
struct samr_OpenDomain opendom ;
2004-06-06 11:14:10 +04:00
int i ;
2005-07-08 12:09:02 +04:00
struct lsa_String name ;
2005-08-03 00:08:23 +04:00
struct policy_handle handle ;
struct policy_handle domain_handle ;
2004-06-06 11:14:10 +04:00
2010-07-16 08:32:42 +04:00
name . string = lpcfg_workgroup ( tctx - > lp_ctx ) ;
2005-02-13 03:26:43 +03:00
r . in . domain_name = & name ;
2008-11-05 03:34:55 +03:00
r . out . info = & info ;
2004-06-06 11:14:10 +04:00
2008-12-24 01:22:57 +03:00
connect_r . in . system_name = 0 ;
connect_r . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
connect_r . out . connect_handle = & handle ;
2011-12-14 02:30:21 +04:00
2011-12-14 02:38:46 +04:00
torture_comment ( tctx , " Testing Connect and OpenDomain on BUILTIN \n " ) ;
2005-08-03 00:08:23 +04:00
2010-03-19 16:17:18 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_Connect_r ( b , tctx , & connect_r ) ,
" Connect failed " ) ;
if ( ! NT_STATUS_IS_OK ( connect_r . out . result ) ) {
if ( NT_STATUS_EQUAL ( connect_r . out . result , NT_STATUS_ACCESS_DENIED ) ) {
2011-12-14 02:38:46 +04:00
torture_comment ( tctx , " Connect failed (expected, schannel mapped to anonymous): %s \n " ,
2010-03-19 16:17:18 +03:00
nt_errstr ( connect_r . out . result ) ) ;
2005-10-25 16:14:08 +04:00
} else {
2011-12-14 02:38:46 +04:00
torture_comment ( tctx , " Connect failed - %s \n " , nt_errstr ( connect_r . out . result ) ) ;
2007-09-01 02:34:52 +04:00
return false ;
2005-10-25 16:14:08 +04:00
}
} else {
opendom . in . connect_handle = & handle ;
opendom . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
2007-09-01 02:34:52 +04:00
opendom . in . sid = dom_sid_parse_talloc ( tctx , " S-1-5-32 " ) ;
2005-10-25 16:14:08 +04:00
opendom . out . domain_handle = & domain_handle ;
2011-12-14 02:30:21 +04:00
2010-03-19 16:17:18 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_OpenDomain_r ( b , tctx , & opendom ) ,
" OpenDomain failed " ) ;
if ( ! NT_STATUS_IS_OK ( opendom . out . result ) ) {
2011-12-14 02:38:46 +04:00
torture_comment ( tctx , " OpenDomain failed - %s \n " , nt_errstr ( opendom . out . result ) ) ;
2007-09-01 02:34:52 +04:00
return false ;
2005-10-25 16:14:08 +04:00
}
2005-08-03 00:08:23 +04:00
}
2011-12-14 02:38:46 +04:00
torture_comment ( tctx , " Testing GetDomPwInfo with name %s \n " , r . in . domain_name - > string ) ;
2011-12-14 02:30:21 +04:00
2004-06-06 11:14:10 +04:00
/* do several ops to test credential chaining */
for ( i = 0 ; i < 5 ; i + + ) {
2010-03-19 16:17:18 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_GetDomPwInfo_r ( b , tctx , & r ) ,
" GetDomPwInfo failed " ) ;
if ( ! NT_STATUS_IS_OK ( r . out . result ) ) {
if ( ! NT_STATUS_EQUAL ( r . out . result , NT_STATUS_ACCESS_DENIED ) ) {
2011-12-14 02:38:46 +04:00
torture_comment ( tctx , " GetDomPwInfo op %d failed - %s \n " , i , nt_errstr ( r . out . result ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2005-10-25 16:14:08 +04:00
}
2004-06-06 11:14:10 +04:00
}
}
2007-10-07 02:28:14 +04:00
return true ;
2004-06-06 11:14:10 +04:00
}
2004-11-12 02:24:30 +03:00
2005-10-06 14:29:28 +04:00
/*
do some lsa ops using the schannel connection
*/
2007-09-01 02:34:52 +04:00
static bool test_lsa_ops ( struct torture_context * tctx , struct dcerpc_pipe * p )
2005-10-06 14:29:28 +04:00
{
struct lsa_GetUserName r ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2008-10-21 03:20:53 +04:00
struct lsa_String * account_name_p = NULL ;
struct lsa_String * authority_name_p = NULL ;
2010-03-16 13:10:16 +03:00
struct dcerpc_binding_handle * b = p - > binding_handle ;
2005-10-06 14:29:28 +04:00
2011-12-14 02:38:46 +04:00
torture_comment ( tctx , " \n Testing GetUserName \n " ) ;
2005-10-06 14:29:28 +04:00
2011-12-14 02:30:21 +04:00
r . in . system_name = " \\ " ;
2008-10-21 03:20:53 +04:00
r . in . account_name = & account_name_p ;
2005-10-06 14:29:28 +04:00
r . in . authority_name = & authority_name_p ;
2008-10-21 03:20:53 +04:00
r . out . account_name = & account_name_p ;
2005-10-06 14:29:28 +04:00
2005-10-25 16:14:08 +04:00
/* do several ops to test credential chaining and various operations */
2010-03-19 16:17:18 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_lsa_GetUserName_r ( b , tctx , & r ) ,
" lsa_GetUserName failed " ) ;
2008-10-21 03:20:53 +04:00
authority_name_p = * r . out . authority_name ;
2010-03-19 16:17:18 +03:00
if ( ! NT_STATUS_IS_OK ( r . out . result ) ) {
2011-12-14 02:38:46 +04:00
torture_comment ( tctx , " GetUserName failed - %s \n " , nt_errstr ( r . out . result ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2005-10-25 16:14:08 +04:00
} else {
if ( ! r . out . account_name ) {
2007-10-07 02:28:14 +04:00
return false ;
2005-10-25 16:14:08 +04:00
}
2011-12-14 02:30:21 +04:00
2008-10-21 03:20:53 +04:00
if ( strcmp ( account_name_p - > string , " ANONYMOUS LOGON " ) ! = 0 ) {
2011-12-14 02:38:46 +04:00
torture_comment ( tctx , " GetUserName returned wrong user: %s, expected %s \n " ,
2008-10-21 03:20:53 +04:00
account_name_p - > string , " ANONYMOUS LOGON " ) ;
2009-05-07 15:05:13 +04:00
/* FIXME: gd */
if ( ! torture_setting_bool ( tctx , " samba3 " , false ) ) {
return false ;
}
2005-10-25 16:14:08 +04:00
}
2008-10-21 03:20:53 +04:00
if ( ! authority_name_p | | ! authority_name_p - > string ) {
2007-10-07 02:28:14 +04:00
return false ;
2005-10-25 16:14:08 +04:00
}
2011-12-14 02:30:21 +04:00
2008-10-21 03:20:53 +04:00
if ( strcmp ( authority_name_p - > string , " NT AUTHORITY " ) ! = 0 ) {
2011-12-14 02:38:46 +04:00
torture_comment ( tctx , " GetUserName returned wrong user: %s, expected %s \n " ,
2008-10-21 03:20:53 +04:00
authority_name_p - > string , " NT AUTHORITY " ) ;
2009-05-07 15:05:13 +04:00
/* FIXME: gd */
if ( ! torture_setting_bool ( tctx , " samba3 " , false ) ) {
return false ;
}
2005-10-06 14:29:28 +04:00
}
}
return ret ;
}
2004-06-06 11:58:16 +04:00
/*
test a schannel connection with the given flags
*/
2007-09-01 02:34:52 +04:00
static bool test_schannel ( struct torture_context * tctx ,
2005-02-10 08:09:35 +03:00
uint16_t acct_flags , uint32_t dcerpc_flags ,
2005-10-25 16:14:08 +04:00
int i )
2004-06-06 11:14:10 +04:00
{
2005-12-30 09:49:36 +03:00
struct test_join * join_ctx ;
2004-06-06 11:14:10 +04:00
NTSTATUS status ;
2007-12-03 02:28:22 +03:00
const char * binding = torture_setting_string ( tctx , " binding " , NULL ) ;
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
struct dcerpc_binding * b ;
2005-01-06 12:26:14 +03:00
struct dcerpc_pipe * p = NULL ;
struct dcerpc_pipe * p_netlogon = NULL ;
2006-02-08 02:49:35 +03:00
struct dcerpc_pipe * p_netlogon2 = NULL ;
2006-02-21 03:07:59 +03:00
struct dcerpc_pipe * p_netlogon3 = NULL ;
2006-02-08 02:30:50 +03:00
struct dcerpc_pipe * p_samr2 = NULL ;
2005-10-06 14:29:28 +04:00
struct dcerpc_pipe * p_lsa = NULL ;
2009-04-06 16:54:44 +04:00
struct netlogon_creds_CredentialState * creds ;
2005-03-22 11:00:45 +03:00
struct cli_credentials * credentials ;
2011-12-14 14:07:11 +04:00
enum dcerpc_transport_t transport ;
2005-03-22 11:00:45 +03:00
2011-12-14 02:30:21 +04:00
join_ctx = torture_join_domain ( tctx ,
talloc_asprintf ( tctx , " %s%d " , TEST_MACHINE_NAME , i ) ,
2005-10-04 03:46:21 +04:00
acct_flags , & credentials ) ;
2007-09-01 02:34:52 +04:00
torture_assert ( tctx , join_ctx ! = NULL , " Failed to join domain " ) ;
2004-06-06 11:14:10 +04:00
2007-09-01 02:34:52 +04:00
status = dcerpc_parse_binding ( tctx , binding , & b ) ;
torture_assert_ntstatus_ok ( tctx , status , " Bad binding string " ) ;
2004-06-06 11:14:10 +04:00
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
b - > flags & = ~ DCERPC_AUTH_OPTIONS ;
b - > flags | = dcerpc_flags ;
2004-06-06 11:14:10 +04:00
2007-09-01 02:34:52 +04:00
status = dcerpc_pipe_connect_b ( tctx , & p , b , & ndr_table_samr ,
2008-04-22 01:58:23 +04:00
credentials , tctx - > ev , tctx - > lp_ctx ) ;
2011-12-14 02:30:21 +04:00
torture_assert_ntstatus_ok ( tctx , status ,
2011-12-14 14:07:11 +04:00
" Failed to connect to samr with schannel " ) ;
2004-06-06 11:14:10 +04:00
2010-03-16 13:10:16 +03:00
torture_assert ( tctx , test_samr_ops ( tctx , p - > binding_handle ) ,
2007-09-01 02:34:52 +04:00
" Failed to process schannel secured SAMR ops " ) ;
2004-06-06 11:14:10 +04:00
2004-11-12 02:24:30 +03:00
/* Also test that when we connect to the netlogon pipe, that
* the credentials we setup on the first pipe are valid for
* the second */
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
/* Swap the binding details from SAMR to NETLOGON */
2008-04-17 15:04:04 +04:00
status = dcerpc_epm_map_binding ( tctx , b , & ndr_table_netlogon , tctx - > ev , tctx - > lp_ctx ) ;
2007-09-01 02:34:52 +04:00
torture_assert_ntstatus_ok ( tctx , status , " epm map " ) ;
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
2011-12-14 02:30:21 +04:00
status = dcerpc_secondary_connection ( p , & p_netlogon ,
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
b ) ;
2011-12-14 03:06:53 +04:00
torture_assert_ntstatus_ok ( tctx , status , " secondary connection " ) ;
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
2011-12-14 02:30:21 +04:00
status = dcerpc_bind_auth ( p_netlogon , & ndr_table_netlogon ,
2010-07-16 08:32:42 +04:00
credentials , lpcfg_gensec_settings ( tctx , tctx - > lp_ctx ) ,
2007-12-07 04:37:04 +03:00
DCERPC_AUTH_TYPE_SCHANNEL ,
2006-01-12 12:33:49 +03:00
dcerpc_auth_level ( p - > conn ) ,
2005-11-20 19:28:39 +03:00
NULL ) ;
2004-11-12 02:24:30 +03:00
2007-09-01 02:34:52 +04:00
torture_assert_ntstatus_ok ( tctx , status , " bind auth " ) ;
2004-11-12 02:24:30 +03:00
2007-09-01 02:34:52 +04:00
status = dcerpc_schannel_creds ( p_netlogon - > conn - > security_state . generic_state , tctx , & creds ) ;
torture_assert_ntstatus_ok ( tctx , status , " schannel creds " ) ;
2004-11-12 02:24:30 +03:00
2009-09-19 23:14:17 +04:00
/* checks the capabilities */
torture_assert ( tctx , test_netlogon_capabilities ( p_netlogon , tctx , credentials , creds ) ,
" Failed to process schannel secured capability ops (on fresh connection) " ) ;
2004-11-12 02:24:30 +03:00
/* do a couple of logins */
2007-09-01 02:34:52 +04:00
torture_assert ( tctx , test_netlogon_ops ( p_netlogon , tctx , credentials , creds ) ,
" Failed to process schannel secured NETLOGON ops " ) ;
2005-10-06 14:29:28 +04:00
2007-09-01 02:34:52 +04:00
torture_assert ( tctx , test_netlogon_ex_ops ( p_netlogon , tctx , credentials , creds ) ,
" Failed to process schannel secured NETLOGON EX ops " ) ;
2006-02-08 02:49:35 +03:00
2012-07-06 02:00:04 +04:00
/* we *MUST* use ncacn_np for openpolicy etc. */
transport = b - > transport ;
b - > transport = NCACN_NP ;
2005-10-06 14:29:28 +04:00
/* Swap the binding details from SAMR to LSARPC */
2008-04-17 15:04:04 +04:00
status = dcerpc_epm_map_binding ( tctx , b , & ndr_table_lsarpc , tctx - > ev , tctx - > lp_ctx ) ;
2007-09-01 02:34:52 +04:00
torture_assert_ntstatus_ok ( tctx , status , " epm map " ) ;
2005-10-06 14:29:28 +04:00
2011-12-14 14:07:11 +04:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_pipe_connect_b ( tctx , & p_lsa , b , & ndr_table_lsarpc ,
credentials , tctx - > ev , tctx - > lp_ctx ) ,
" failed to connect lsarpc with schannel " ) ;
2005-10-06 14:29:28 +04:00
2011-12-14 14:07:11 +04:00
torture_assert ( tctx , test_lsa_ops ( tctx , p_lsa ) ,
" Failed to process schannel secured LSA ops " ) ;
2004-11-12 02:24:30 +03:00
2011-12-14 14:07:11 +04:00
talloc_free ( p_lsa ) ;
p_lsa = NULL ;
2005-10-06 14:29:28 +04:00
2012-07-06 02:00:04 +04:00
b - > transport = transport ;
2011-12-14 14:07:11 +04:00
/* we *MUST* use ncacn_ip_tcp for lookupsids3/lookupnames4 */
transport = b - > transport ;
b - > transport = NCACN_IP_TCP ;
2005-10-06 14:29:28 +04:00
2011-12-14 14:07:11 +04:00
torture_assert_ntstatus_ok ( tctx ,
dcerpc_epm_map_binding ( tctx , b , & ndr_table_lsarpc , tctx - > ev , tctx - > lp_ctx ) ,
" failed to call epm map " ) ;
torture_assert_ntstatus_ok ( tctx ,
dcerpc_pipe_connect_b ( tctx , & p_lsa , b , & ndr_table_lsarpc ,
credentials , tctx - > ev , tctx - > lp_ctx ) ,
" failed to connect lsarpc with schannel " ) ;
torture_assert ( tctx ,
test_many_LookupSids ( p_lsa , tctx , NULL ) ,
" LsaLookupSids3 failed! \n " ) ;
b - > transport = transport ;
2005-10-06 14:29:28 +04:00
2006-02-08 02:30:50 +03:00
/* Drop the socket, we want to start from scratch */
talloc_free ( p ) ;
p = NULL ;
/* Now see what we are still allowed to do */
2011-12-14 02:30:21 +04:00
2007-09-01 02:34:52 +04:00
status = dcerpc_parse_binding ( tctx , binding , & b ) ;
torture_assert_ntstatus_ok ( tctx , status , " Bad binding string " ) ;
2006-02-08 02:30:50 +03:00
b - > flags & = ~ DCERPC_AUTH_OPTIONS ;
b - > flags | = dcerpc_flags ;
2007-09-01 02:34:52 +04:00
status = dcerpc_pipe_connect_b ( tctx , & p_samr2 , b , & ndr_table_samr ,
2008-04-22 01:58:23 +04:00
credentials , tctx - > ev , tctx - > lp_ctx ) ;
2011-12-14 02:30:21 +04:00
torture_assert_ntstatus_ok ( tctx , status ,
2007-09-01 02:34:52 +04:00
" Failed to connect with schannel " ) ;
2006-02-08 02:30:50 +03:00
2006-02-09 06:05:22 +03:00
/* do a some SAMR operations. We have *not* done a new serverauthenticate */
2010-03-16 13:10:16 +03:00
torture_assert ( tctx , test_samr_ops ( tctx , p_samr2 - > binding_handle ) ,
2007-09-01 02:34:52 +04:00
" Failed to process schannel secured SAMR ops (on fresh connection) " ) ;
2006-02-08 02:49:35 +03:00
/* Swap the binding details from SAMR to NETLOGON */
2008-04-17 15:04:04 +04:00
status = dcerpc_epm_map_binding ( tctx , b , & ndr_table_netlogon , tctx - > ev , tctx - > lp_ctx ) ;
2007-09-01 02:34:52 +04:00
torture_assert_ntstatus_ok ( tctx , status , " epm " ) ;
2006-02-08 02:49:35 +03:00
2011-12-14 02:30:21 +04:00
status = dcerpc_secondary_connection ( p_samr2 , & p_netlogon2 ,
2006-02-08 02:49:35 +03:00
b ) ;
2011-12-14 03:06:53 +04:00
torture_assert_ntstatus_ok ( tctx , status , " secondary connection " ) ;
2006-02-08 02:49:35 +03:00
2006-02-09 06:05:22 +03:00
/* and now setup an SCHANNEL bind on netlogon */
2007-08-20 01:23:03 +04:00
status = dcerpc_bind_auth ( p_netlogon2 , & ndr_table_netlogon ,
2010-07-16 08:32:42 +04:00
credentials , lpcfg_gensec_settings ( tctx , tctx - > lp_ctx ) ,
2007-12-07 04:37:04 +03:00
DCERPC_AUTH_TYPE_SCHANNEL ,
2006-02-08 02:49:35 +03:00
dcerpc_auth_level ( p_samr2 - > conn ) ,
NULL ) ;
2007-09-01 02:34:52 +04:00
torture_assert_ntstatus_ok ( tctx , status , " auth failed " ) ;
2011-12-14 02:30:21 +04:00
2009-09-19 23:14:17 +04:00
/* checks the capabilities */
torture_assert ( tctx , test_netlogon_capabilities ( p_netlogon2 , tctx , credentials , creds ) ,
" Failed to process schannel secured capability ops (on fresh connection) " ) ;
2006-02-09 05:30:43 +03:00
/* Try the schannel-only SamLogonEx operation */
2011-12-14 02:30:21 +04:00
torture_assert ( tctx , test_netlogon_ex_ops ( p_netlogon2 , tctx , credentials , creds ) ,
2007-09-01 02:34:52 +04:00
" Failed to process schannel secured NETLOGON EX ops (on fresh connection) " ) ;
2011-12-14 02:30:21 +04:00
2006-02-08 02:30:50 +03:00
2006-02-09 06:05:22 +03:00
/* And the more traditional style, proving that the
* credentials chaining state is fully present */
2007-09-01 02:34:52 +04:00
torture_assert ( tctx , test_netlogon_ops ( p_netlogon2 , tctx , credentials , creds ) ,
" Failed to process schannel secured NETLOGON ops (on fresh connection) " ) ;
2006-02-21 03:07:59 +03:00
/* Drop the socket, we want to start from scratch (again) */
talloc_free ( p_samr2 ) ;
/* We don't want schannel for this test */
b - > flags & = ~ DCERPC_AUTH_OPTIONS ;
2007-09-01 02:34:52 +04:00
status = dcerpc_pipe_connect_b ( tctx , & p_netlogon3 , b , & ndr_table_netlogon ,
2008-04-22 01:58:23 +04:00
credentials , tctx - > ev , tctx - > lp_ctx ) ;
2007-09-01 02:34:52 +04:00
torture_assert_ntstatus_ok ( tctx , status , " Failed to connect without schannel " ) ;
2006-02-21 03:07:59 +03:00
2007-09-01 02:34:52 +04:00
torture_assert ( tctx , ! test_netlogon_ex_ops ( p_netlogon3 , tctx , credentials , creds ) ,
" Processed NOT schannel secured NETLOGON EX ops without SCHANNEL (unsafe) " ) ;
2006-02-21 03:07:59 +03:00
2007-09-01 02:34:52 +04:00
/* Required because the previous call will mark the current context as having failed */
tctx - > last_result = TORTURE_OK ;
tctx - > last_reason = NULL ;
2006-02-09 05:30:43 +03:00
2007-09-01 02:34:52 +04:00
torture_assert ( tctx , test_netlogon_ops ( p_netlogon3 , tctx , credentials , creds ) ,
" Failed to processed NOT schannel secured NETLOGON ops without new ServerAuth " ) ;
2004-06-06 11:14:10 +04:00
2008-06-14 19:24:17 +04:00
torture_leave_domain ( tctx , join_ctx ) ;
2007-09-01 02:34:52 +04:00
return true ;
2004-06-06 11:14:10 +04:00
}
2007-05-23 11:44:51 +04:00
2004-06-06 11:58:16 +04:00
/*
a schannel test suite
*/
2007-09-01 02:34:52 +04:00
bool torture_rpc_schannel ( struct torture_context * torture )
2004-06-06 11:14:10 +04:00
{
2007-10-07 02:28:14 +04:00
bool ret = true ;
2004-06-06 11:14:10 +04:00
struct {
2005-02-10 08:09:35 +03:00
uint16_t acct_flags ;
uint32_t dcerpc_flags ;
2004-06-06 11:14:10 +04:00
} tests [ ] = {
2011-12-13 18:20:53 +04:00
{ ACB_WSTRUST , DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AUTO } ,
{ ACB_WSTRUST , DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_AUTO } ,
2005-10-25 16:14:08 +04:00
{ ACB_WSTRUST , DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128 } ,
{ ACB_WSTRUST , DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128 } ,
2012-01-02 19:27:45 +04:00
{ ACB_WSTRUST , DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AES } ,
{ ACB_WSTRUST , DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_AES } ,
2011-12-13 18:20:53 +04:00
{ ACB_SVRTRUST , DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AUTO } ,
{ ACB_SVRTRUST , DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_AUTO } ,
2005-10-25 16:14:08 +04:00
{ ACB_SVRTRUST , DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128 } ,
2012-01-02 19:27:45 +04:00
{ ACB_SVRTRUST , DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128 } ,
{ ACB_SVRTRUST , DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AES } ,
{ ACB_SVRTRUST , DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_AES }
2004-06-06 11:14:10 +04:00
} ;
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( tests ) ; i + + ) {
2011-12-14 14:07:11 +04:00
torture_comment ( torture , " Testing with acct_flags=0x%x dcerpc_flags=0x%x \n " ,
tests [ i ] . acct_flags , tests [ i ] . dcerpc_flags ) ;
2011-12-14 02:30:21 +04:00
if ( ! test_schannel ( torture ,
2005-10-25 16:14:08 +04:00
tests [ i ] . acct_flags , tests [ i ] . dcerpc_flags ,
i ) ) {
2007-09-01 02:34:52 +04:00
torture_comment ( torture , " Failed with acct_flags=0x%x dcerpc_flags=0x%x \n " ,
2005-10-25 16:14:08 +04:00
tests [ i ] . acct_flags , tests [ i ] . dcerpc_flags ) ;
2007-09-01 02:34:52 +04:00
ret = false ;
2004-06-06 11:14:10 +04:00
}
}
return ret ;
}
2007-05-23 11:44:51 +04:00
/*
test two schannel connections
*/
2007-09-01 02:34:52 +04:00
bool torture_rpc_schannel2 ( struct torture_context * torture )
2007-05-23 11:44:51 +04:00
{
struct test_join * join_ctx ;
NTSTATUS status ;
2007-08-28 04:16:58 +04:00
const char * binding = torture_setting_string ( torture , " binding " , NULL ) ;
2007-05-23 11:44:51 +04:00
struct dcerpc_binding * b ;
struct dcerpc_pipe * p1 = NULL , * p2 = NULL ;
struct cli_credentials * credentials1 , * credentials2 ;
uint32_t dcerpc_flags = DCERPC_SCHANNEL | DCERPC_SIGN ;
2011-12-14 02:30:21 +04:00
join_ctx = torture_join_domain ( torture , talloc_asprintf ( torture , " %s2 " , TEST_MACHINE_NAME ) ,
2007-09-01 02:34:52 +04:00
ACB_WSTRUST , & credentials1 ) ;
2011-12-14 02:30:21 +04:00
torture_assert ( torture , join_ctx ! = NULL ,
2007-09-01 02:34:52 +04:00
" Failed to join domain with acct_flags=ACB_WSTRUST " ) ;
2007-05-23 11:44:51 +04:00
2007-09-08 20:46:30 +04:00
credentials2 = ( struct cli_credentials * ) talloc_memdup ( torture , credentials1 , sizeof ( * credentials1 ) ) ;
2007-05-23 11:44:51 +04:00
credentials1 - > netlogon_creds = NULL ;
credentials2 - > netlogon_creds = NULL ;
2007-09-01 02:34:52 +04:00
status = dcerpc_parse_binding ( torture , binding , & b ) ;
torture_assert_ntstatus_ok ( torture , status , " Bad binding string " ) ;
2007-05-23 11:44:51 +04:00
b - > flags & = ~ DCERPC_AUTH_OPTIONS ;
b - > flags | = dcerpc_flags ;
2011-12-14 02:38:46 +04:00
torture_comment ( torture , " Opening first connection \n " ) ;
2007-09-01 02:34:52 +04:00
status = dcerpc_pipe_connect_b ( torture , & p1 , b , & ndr_table_netlogon ,
2008-04-22 01:58:23 +04:00
credentials1 , torture - > ev , torture - > lp_ctx ) ;
2007-09-01 02:34:52 +04:00
torture_assert_ntstatus_ok ( torture , status , " Failed to connect with schannel " ) ;
2007-05-23 11:44:51 +04:00
2007-09-01 02:34:52 +04:00
torture_comment ( torture , " Opening second connection \n " ) ;
status = dcerpc_pipe_connect_b ( torture , & p2 , b , & ndr_table_netlogon ,
2008-04-22 01:58:23 +04:00
credentials2 , torture - > ev , torture - > lp_ctx ) ;
2007-09-01 02:34:52 +04:00
torture_assert_ntstatus_ok ( torture , status , " Failed to connect with schannel " ) ;
2007-05-23 11:44:51 +04:00
credentials1 - > netlogon_creds = NULL ;
credentials2 - > netlogon_creds = NULL ;
2007-09-01 02:34:52 +04:00
torture_comment ( torture , " Testing logon on pipe1 \n " ) ;
if ( ! test_netlogon_ex_ops ( p1 , torture , credentials1 , NULL ) )
return false ;
2007-05-23 11:44:51 +04:00
2007-09-01 02:34:52 +04:00
torture_comment ( torture , " Testing logon on pipe2 \n " ) ;
if ( ! test_netlogon_ex_ops ( p2 , torture , credentials2 , NULL ) )
return false ;
2007-05-23 11:44:51 +04:00
2007-09-01 02:34:52 +04:00
torture_comment ( torture , " Again on pipe1 \n " ) ;
if ( ! test_netlogon_ex_ops ( p1 , torture , credentials1 , NULL ) )
return false ;
2007-05-23 11:44:51 +04:00
2007-09-01 02:34:52 +04:00
torture_comment ( torture , " Again on pipe2 \n " ) ;
if ( ! test_netlogon_ex_ops ( p2 , torture , credentials2 , NULL ) )
return false ;
2007-05-23 11:44:51 +04:00
2008-06-14 19:24:17 +04:00
torture_leave_domain ( torture , join_ctx ) ;
2007-09-01 02:34:52 +04:00
return true ;
2007-05-23 11:44:51 +04:00
}
2008-05-13 11:10:25 +04:00
struct torture_schannel_bench ;
struct torture_schannel_bench_conn {
struct torture_schannel_bench * s ;
int index ;
struct cli_credentials * wks_creds ;
struct dcerpc_pipe * pipe ;
struct netr_LogonSamLogonEx r ;
struct netr_NetworkInfo ninfo ;
TALLOC_CTX * tmp ;
uint64_t total ;
uint32_t count ;
} ;
struct torture_schannel_bench {
struct torture_context * tctx ;
bool progress ;
int timelimit ;
int nprocs ;
int nconns ;
struct torture_schannel_bench_conn * conns ;
2008-05-16 17:51:27 +04:00
struct test_join * join_ctx1 ;
struct cli_credentials * wks_creds1 ;
struct test_join * join_ctx2 ;
struct cli_credentials * wks_creds2 ;
2008-05-13 11:10:25 +04:00
struct cli_credentials * user1_creds ;
struct cli_credentials * user2_creds ;
struct dcerpc_binding * b ;
NTSTATUS error ;
uint64_t total ;
uint32_t count ;
bool stopped ;
} ;
static void torture_schannel_bench_connected ( struct composite_context * c )
{
2008-05-16 17:44:14 +04:00
struct torture_schannel_bench_conn * conn =
( struct torture_schannel_bench_conn * ) c - > async . private_data ;
2008-05-13 11:10:25 +04:00
struct torture_schannel_bench * s = talloc_get_type ( conn - > s ,
struct torture_schannel_bench ) ;
s - > error = dcerpc_pipe_connect_b_recv ( c , s - > conns , & conn - > pipe ) ;
torture_comment ( s - > tctx , " conn[%u]: %s \n " , conn - > index , nt_errstr ( s - > error ) ) ;
if ( NT_STATUS_IS_OK ( s - > error ) ) {
s - > nconns + + ;
}
}
2010-03-09 17:46:55 +03:00
static void torture_schannel_bench_recv ( struct tevent_req * subreq ) ;
2008-05-13 11:10:25 +04:00
static bool torture_schannel_bench_start ( struct torture_schannel_bench_conn * conn )
{
struct torture_schannel_bench * s = conn - > s ;
NTSTATUS status ;
DATA_BLOB names_blob , chal , lm_resp , nt_resp ;
int flags = CLI_CRED_NTLM_AUTH ;
2010-03-09 17:46:55 +03:00
struct tevent_req * subreq ;
2008-05-13 11:10:25 +04:00
struct cli_credentials * user_creds ;
if ( conn - > total % 2 ) {
user_creds = s - > user1_creds ;
} else {
user_creds = s - > user2_creds ;
}
2010-07-16 08:32:42 +04:00
if ( lpcfg_client_lanman_auth ( s - > tctx - > lp_ctx ) ) {
2008-05-13 11:10:25 +04:00
flags | = CLI_CRED_LANMAN_AUTH ;
}
2010-07-16 08:32:42 +04:00
if ( lpcfg_client_ntlmv2_auth ( s - > tctx - > lp_ctx ) ) {
2008-05-13 11:10:25 +04:00
flags | = CLI_CRED_NTLMv2_AUTH ;
}
talloc_free ( conn - > tmp ) ;
conn - > tmp = talloc_new ( s ) ;
ZERO_STRUCT ( conn - > ninfo ) ;
ZERO_STRUCT ( conn - > r ) ;
cli_credentials_get_ntlm_username_domain ( user_creds , conn - > tmp ,
& conn - > ninfo . identity_info . account_name . string ,
& conn - > ninfo . identity_info . domain_name . string ) ;
generate_random_buffer ( conn - > ninfo . challenge ,
sizeof ( conn - > ninfo . challenge ) ) ;
chal = data_blob_const ( conn - > ninfo . challenge ,
sizeof ( conn - > ninfo . challenge ) ) ;
2011-12-14 02:30:21 +04:00
names_blob = NTLMv2_generate_names_blob ( conn - > tmp ,
2008-05-13 11:10:25 +04:00
cli_credentials_get_workstation ( conn - > wks_creds ) ,
cli_credentials_get_domain ( conn - > wks_creds ) ) ;
status = cli_credentials_get_ntlm_response ( user_creds , conn - > tmp ,
& flags ,
chal ,
names_blob ,
& lm_resp , & nt_resp ,
NULL , NULL ) ;
torture_assert_ntstatus_ok ( s - > tctx , status ,
" cli_credentials_get_ntlm_response failed " ) ;
conn - > ninfo . lm . data = lm_resp . data ;
conn - > ninfo . lm . length = lm_resp . length ;
conn - > ninfo . nt . data = nt_resp . data ;
conn - > ninfo . nt . length = nt_resp . length ;
conn - > ninfo . identity_info . parameter_control = 0 ;
conn - > ninfo . identity_info . logon_id_low = 0 ;
conn - > ninfo . identity_info . logon_id_high = 0 ;
conn - > ninfo . identity_info . workstation . string = cli_credentials_get_workstation ( conn - > wks_creds ) ;
conn - > r . in . server_name = talloc_asprintf ( conn - > tmp , " \\ \\ %s " , dcerpc_server_name ( conn - > pipe ) ) ;
conn - > r . in . computer_name = cli_credentials_get_workstation ( conn - > wks_creds ) ;
conn - > r . in . logon_level = 2 ;
2008-10-28 21:03:50 +03:00
conn - > r . in . logon = talloc ( conn - > tmp , union netr_LogonLevel ) ;
conn - > r . in . logon - > network = & conn - > ninfo ;
conn - > r . in . flags = talloc ( conn - > tmp , uint32_t ) ;
2008-05-13 11:10:25 +04:00
conn - > r . in . validation_level = 2 ;
2008-10-28 21:03:50 +03:00
conn - > r . out . validation = talloc ( conn - > tmp , union netr_Validation ) ;
conn - > r . out . authoritative = talloc ( conn - > tmp , uint8_t ) ;
conn - > r . out . flags = conn - > r . in . flags ;
2008-05-13 11:10:25 +04:00
2010-03-09 17:46:55 +03:00
subreq = dcerpc_netr_LogonSamLogonEx_r_send ( s , s - > tctx - > ev ,
conn - > pipe - > binding_handle ,
& conn - > r ) ;
torture_assert ( s - > tctx , subreq , " Failed to setup LogonSamLogonEx request " ) ;
2008-05-13 11:10:25 +04:00
2010-03-09 17:46:55 +03:00
tevent_req_set_callback ( subreq , torture_schannel_bench_recv , conn ) ;
2008-05-13 11:10:25 +04:00
return true ;
}
2010-03-09 17:46:55 +03:00
static void torture_schannel_bench_recv ( struct tevent_req * subreq )
2008-05-13 11:10:25 +04:00
{
bool ret ;
2008-05-16 17:44:14 +04:00
struct torture_schannel_bench_conn * conn =
2010-03-09 17:46:55 +03:00
( struct torture_schannel_bench_conn * ) tevent_req_callback_data_void ( subreq ) ;
2008-05-13 11:10:25 +04:00
struct torture_schannel_bench * s = talloc_get_type ( conn - > s ,
struct torture_schannel_bench ) ;
2010-03-09 17:46:55 +03:00
s - > error = dcerpc_netr_LogonSamLogonEx_r_recv ( subreq , subreq ) ;
TALLOC_FREE ( subreq ) ;
2008-05-13 11:10:25 +04:00
if ( ! NT_STATUS_IS_OK ( s - > error ) ) {
return ;
}
conn - > total + + ;
conn - > count + + ;
if ( s - > stopped ) {
return ;
}
ret = torture_schannel_bench_start ( conn ) ;
if ( ! ret ) {
s - > error = NT_STATUS_INTERNAL_ERROR ;
}
}
/*
test multiple schannel connection in parallel
*/
bool torture_rpc_schannel_bench1 ( struct torture_context * torture )
{
bool ret = true ;
NTSTATUS status ;
const char * binding = torture_setting_string ( torture , " binding " , NULL ) ;
struct torture_schannel_bench * s ;
struct timeval start ;
struct timeval end ;
int i ;
const char * tmp ;
s = talloc_zero ( torture , struct torture_schannel_bench ) ;
s - > tctx = torture ;
s - > progress = torture_setting_bool ( torture , " progress " , true ) ;
s - > timelimit = torture_setting_int ( torture , " timelimit " , 10 ) ;
s - > nprocs = torture_setting_int ( torture , " nprocs " , 4 ) ;
s - > conns = talloc_zero_array ( s , struct torture_schannel_bench_conn , s - > nprocs ) ;
s - > user1_creds = ( struct cli_credentials * ) talloc_memdup ( s ,
cmdline_credentials ,
sizeof ( * s - > user1_creds ) ) ;
tmp = torture_setting_string ( s - > tctx , " extra_user1 " , NULL ) ;
if ( tmp ) {
cli_credentials_parse_string ( s - > user1_creds , tmp , CRED_SPECIFIED ) ;
}
s - > user2_creds = ( struct cli_credentials * ) talloc_memdup ( s ,
cmdline_credentials ,
sizeof ( * s - > user1_creds ) ) ;
tmp = torture_setting_string ( s - > tctx , " extra_user2 " , NULL ) ;
if ( tmp ) {
cli_credentials_parse_string ( s - > user1_creds , tmp , CRED_SPECIFIED ) ;
}
2008-05-16 17:51:27 +04:00
s - > join_ctx1 = torture_join_domain ( s - > tctx , talloc_asprintf ( s , " %sb " , TEST_MACHINE_NAME ) ,
ACB_WSTRUST , & s - > wks_creds1 ) ;
torture_assert ( torture , s - > join_ctx1 ! = NULL ,
" Failed to join domain with acct_flags=ACB_WSTRUST " ) ;
s - > join_ctx2 = torture_join_domain ( s - > tctx , talloc_asprintf ( s , " %sc " , TEST_MACHINE_NAME ) ,
ACB_WSTRUST , & s - > wks_creds2 ) ;
torture_assert ( torture , s - > join_ctx2 ! = NULL ,
2008-05-13 11:10:25 +04:00
" Failed to join domain with acct_flags=ACB_WSTRUST " ) ;
2008-05-16 17:51:27 +04:00
cli_credentials_set_kerberos_state ( s - > wks_creds1 , CRED_DONT_USE_KERBEROS ) ;
cli_credentials_set_kerberos_state ( s - > wks_creds2 , CRED_DONT_USE_KERBEROS ) ;
2008-05-13 11:10:25 +04:00
for ( i = 0 ; i < s - > nprocs ; i + + ) {
s - > conns [ i ] . s = s ;
s - > conns [ i ] . index = i ;
2008-05-16 17:51:27 +04:00
s - > conns [ i ] . wks_creds = ( struct cli_credentials * ) talloc_memdup (
s - > conns , s - > wks_creds1 , sizeof ( * s - > wks_creds1 ) ) ;
if ( ( i % 2 ) & & ( torture_setting_bool ( torture , " multijoin " , false ) ) ) {
memcpy ( s - > conns [ i ] . wks_creds , s - > wks_creds2 ,
talloc_get_size ( s - > conns [ i ] . wks_creds ) ) ;
}
2008-05-13 11:10:25 +04:00
s - > conns [ i ] . wks_creds - > netlogon_creds = NULL ;
}
status = dcerpc_parse_binding ( s , binding , & s - > b ) ;
torture_assert_ntstatus_ok ( torture , status , " Bad binding string " ) ;
s - > b - > flags & = ~ DCERPC_AUTH_OPTIONS ;
s - > b - > flags | = DCERPC_SCHANNEL | DCERPC_SIGN ;
torture_comment ( torture , " Opening %d connections in parallel \n " , s - > nprocs ) ;
for ( i = 0 ; i < s - > nprocs ; i + + ) {
# if 1
s - > error = dcerpc_pipe_connect_b ( s - > conns , & s - > conns [ i ] . pipe , s - > b ,
& ndr_table_netlogon ,
s - > conns [ i ] . wks_creds ,
torture - > ev , torture - > lp_ctx ) ;
torture_assert_ntstatus_ok ( torture , s - > error , " Failed to connect with schannel " ) ;
# else
/*
* This path doesn ' t work against windows ,
* because of windows drops the connections
* which haven ' t reached a session setup yet
*
* The same as the reset on zero vc stuff .
*/
struct composite_context * c ;
c = dcerpc_pipe_connect_b_send ( s - > conns , s - > b ,
& ndr_table_netlogon ,
s - > conns [ i ] . wks_creds ,
torture - > ev ,
torture - > lp_ctx ) ;
torture_assert ( torture , c ! = NULL , " Failed to setup connect " ) ;
c - > async . fn = torture_schannel_bench_connected ;
c - > async . private_data = & s - > conns [ i ] ;
}
while ( NT_STATUS_IS_OK ( s - > error ) & & s - > nprocs ! = s - > nconns ) {
2010-05-25 23:23:55 +04:00
int ev_ret = tevent_loop_once ( torture - > ev ) ;
torture_assert ( torture , ev_ret = = 0 , " tevent_loop_once failed " ) ;
2008-05-13 11:10:25 +04:00
# endif
}
torture_assert_ntstatus_ok ( torture , s - > error , " Failed establish a connect " ) ;
2008-05-20 14:59:04 +04:00
/*
* Change the workstation password after establishing the netlogon
* schannel connections to prove that existing connections are not
* affected by a wks pwchange .
*/
{
struct netr_ServerPasswordSet pwset ;
2010-02-24 17:12:17 +03:00
char * password = generate_random_password ( s - > join_ctx1 , 8 , 255 ) ;
2009-04-06 16:54:44 +04:00
struct netlogon_creds_CredentialState * creds_state ;
2008-05-20 14:59:04 +04:00
struct dcerpc_pipe * net_pipe ;
2008-10-29 03:34:49 +03:00
struct netr_Authenticator credential , return_authenticator ;
struct samr_Password new_password ;
2008-05-20 14:59:04 +04:00
status = dcerpc_pipe_connect_b ( s , & net_pipe , s - > b ,
& ndr_table_netlogon ,
s - > wks_creds1 ,
torture - > ev , torture - > lp_ctx ) ;
torture_assert_ntstatus_ok ( torture , status ,
" dcerpc_pipe_connect_b failed " ) ;
pwset . in . server_name = talloc_asprintf (
net_pipe , " \\ \\ %s " , dcerpc_server_name ( net_pipe ) ) ;
pwset . in . computer_name =
cli_credentials_get_workstation ( s - > wks_creds1 ) ;
pwset . in . account_name = talloc_asprintf (
net_pipe , " %s$ " , pwset . in . computer_name ) ;
pwset . in . secure_channel_type = SEC_CHAN_WKSTA ;
2008-10-29 03:34:49 +03:00
pwset . in . credential = & credential ;
pwset . in . new_password = & new_password ;
pwset . out . return_authenticator = & return_authenticator ;
E_md4hash ( password , new_password . hash ) ;
2008-05-20 14:59:04 +04:00
creds_state = cli_credentials_get_netlogon_creds (
s - > wks_creds1 ) ;
2009-04-06 16:54:44 +04:00
netlogon_creds_des_encrypt ( creds_state , & new_password ) ;
netlogon_creds_client_authenticator ( creds_state , & credential ) ;
2008-05-20 14:59:04 +04:00
2010-03-19 16:17:18 +03:00
torture_assert_ntstatus_ok ( torture , dcerpc_netr_ServerPasswordSet_r ( net_pipe - > binding_handle , torture , & pwset ) ,
" ServerPasswordSet failed " ) ;
torture_assert_ntstatus_ok ( torture , pwset . out . result ,
2008-05-20 14:59:04 +04:00
" ServerPasswordSet failed " ) ;
2009-04-06 16:54:44 +04:00
if ( ! netlogon_creds_client_check ( creds_state ,
2008-10-29 03:34:49 +03:00
& pwset . out . return_authenticator - > cred ) ) {
2011-12-14 02:38:46 +04:00
torture_comment ( torture , " Credential chaining failed \n " ) ;
2008-05-20 14:59:04 +04:00
}
cli_credentials_set_password ( s - > wks_creds1 , password ,
CRED_SPECIFIED ) ;
talloc_free ( net_pipe ) ;
/* Just as a test, connect with the new creds */
talloc_free ( s - > wks_creds1 - > netlogon_creds ) ;
s - > wks_creds1 - > netlogon_creds = NULL ;
status = dcerpc_pipe_connect_b ( s , & net_pipe , s - > b ,
& ndr_table_netlogon ,
s - > wks_creds1 ,
torture - > ev , torture - > lp_ctx ) ;
torture_assert_ntstatus_ok ( torture , status ,
" dcerpc_pipe_connect_b failed " ) ;
talloc_free ( net_pipe ) ;
}
2008-05-13 11:10:25 +04:00
torture_comment ( torture , " Start looping LogonSamLogonEx on %d connections for %d secs \n " ,
s - > nprocs , s - > timelimit ) ;
for ( i = 0 ; i < s - > nprocs ; i + + ) {
ret = torture_schannel_bench_start ( & s - > conns [ i ] ) ;
torture_assert ( torture , ret , " Failed to setup LogonSamLogonEx " ) ;
}
start = timeval_current ( ) ;
end = timeval_add ( & start , s - > timelimit , 0 ) ;
while ( NT_STATUS_IS_OK ( s - > error ) & & ! timeval_expired ( & end ) ) {
2010-05-25 23:23:55 +04:00
int ev_ret = tevent_loop_once ( torture - > ev ) ;
torture_assert ( torture , ev_ret = = 0 , " tevent_loop_once failed " ) ;
2008-05-13 11:10:25 +04:00
}
torture_assert_ntstatus_ok ( torture , s - > error , " Failed some request " ) ;
s - > stopped = true ;
talloc_free ( s - > conns ) ;
for ( i = 0 ; i < s - > nprocs ; i + + ) {
s - > total + = s - > conns [ i ] . total ;
}
torture_comment ( torture ,
" Total ops[%llu] (%u ops/s) \n " ,
( unsigned long long ) s - > total ,
( unsigned ) s - > total / s - > timelimit ) ;
2008-06-14 19:24:17 +04:00
torture_leave_domain ( torture , s - > join_ctx1 ) ;
torture_leave_domain ( torture , s - > join_ctx2 ) ;
2008-05-13 11:10:25 +04:00
return true ;
}