2012-12-05 02:11:10 +04:00
/*
2008-08-27 15:36:27 +04:00
Unix SMB / CIFS implementation .
test suite for netlogon PAC operations
2012-08-24 04:01:42 +04:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2012
2012-12-05 02:11:10 +04:00
2008-08-27 15:36:27 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
2012-12-05 02:11:10 +04:00
2008-08-27 15:36:27 +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 .
2012-12-05 02:11:10 +04:00
2008-08-27 15:36:27 +04:00
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "auth/auth.h"
2010-03-04 12:07:12 +03:00
# include "auth/auth_sam_reply.h"
2008-08-27 15:36:27 +04:00
# include "auth/gensec/gensec.h"
2010-11-02 09:14:55 +03:00
# include "system/kerberos.h"
# include "auth/kerberos/kerberos.h"
# include "auth/credentials/credentials.h"
# include "auth/credentials/credentials_krb5.h"
2008-08-27 15:36:27 +04:00
# include "lib/cmdline/popt_common.h"
2010-04-14 00:06:51 +04:00
# include "torture/rpc/torture_rpc.h"
2008-08-27 15:36:27 +04:00
# include "libcli/auth/libcli_auth.h"
2010-09-20 11:42:13 +04:00
# include "libcli/security/security.h"
2008-08-27 15:36:27 +04:00
# include "librpc/gen_ndr/ndr_netlogon_c.h"
2011-02-08 08:53:13 +03:00
# include "librpc/gen_ndr/ndr_krb5pac.h"
2010-11-02 09:14:55 +03:00
# include "librpc/gen_ndr/ndr_samr_c.h"
2008-08-27 15:36:27 +04:00
# include "param/param.h"
2010-03-04 12:07:12 +03:00
# define TEST_MACHINE_NAME_BDC "torturepacbdc"
# define TEST_MACHINE_NAME_WKSTA "torturepacwksta"
2010-11-02 09:14:55 +03:00
# define TEST_MACHINE_NAME_WKSTA_DES "torturepacwkdes"
2010-03-04 12:07:12 +03:00
# define TEST_MACHINE_NAME_S2U4SELF_BDC "tests2u4selfbdc"
# define TEST_MACHINE_NAME_S2U4SELF_WKSTA "tests2u4selfwk"
2008-08-27 15:36:27 +04:00
2012-01-30 01:00:28 +04:00
struct pac_data {
2016-07-20 11:12:45 +03:00
DATA_BLOB pac_blob ;
2012-01-30 01:00:28 +04:00
struct PAC_SIGNATURE_DATA * pac_srv_sig ;
struct PAC_SIGNATURE_DATA * pac_kdc_sig ;
} ;
2011-12-29 04:46:41 +04:00
/* A helper function which avoids touching the local databases to
* generate the session info , as we just want to verify the PAC
* details , not the full local token */
static NTSTATUS test_generate_session_info_pac ( struct auth4_context * auth_ctx ,
2011-12-29 15:36:14 +04:00
TALLOC_CTX * mem_ctx ,
2011-12-29 04:46:41 +04:00
struct smb_krb5_context * smb_krb5_context ,
DATA_BLOB * pac_blob ,
const char * principal_name ,
const struct tsocket_address * remote_address ,
uint32_t session_info_flags ,
struct auth_session_info * * session_info )
{
NTSTATUS nt_status ;
struct auth_user_info_dc * user_info_dc ;
2011-12-29 15:36:14 +04:00
TALLOC_CTX * tmp_ctx ;
2012-01-30 01:00:28 +04:00
struct pac_data * pac_data ;
2011-12-29 15:36:14 +04:00
tmp_ctx = talloc_named ( mem_ctx , 0 , " gensec_gssapi_session_info context " ) ;
NT_STATUS_HAVE_NO_MEMORY ( tmp_ctx ) ;
2011-12-29 04:46:41 +04:00
2012-12-05 02:11:10 +04:00
auth_ctx - > private_data = pac_data = talloc_zero ( auth_ctx , struct pac_data ) ;
2012-01-30 01:00:28 +04:00
2016-07-20 11:12:45 +03:00
pac_data - > pac_blob = data_blob_dup_talloc ( pac_data , * pac_blob ) ;
if ( pac_data - > pac_blob . length ! = pac_blob - > length ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2012-01-30 01:00:28 +04:00
pac_data - > pac_srv_sig = talloc ( tmp_ctx , struct PAC_SIGNATURE_DATA ) ;
if ( ! pac_data - > pac_srv_sig ) {
2011-12-29 15:36:14 +04:00
talloc_free ( tmp_ctx ) ;
2011-12-29 04:46:41 +04:00
return NT_STATUS_NO_MEMORY ;
}
2012-01-30 01:00:28 +04:00
pac_data - > pac_kdc_sig = talloc ( tmp_ctx , struct PAC_SIGNATURE_DATA ) ;
if ( ! pac_data - > pac_kdc_sig ) {
2011-12-29 15:36:14 +04:00
talloc_free ( tmp_ctx ) ;
2011-12-29 04:46:41 +04:00
return NT_STATUS_NO_MEMORY ;
}
2011-12-29 15:36:14 +04:00
nt_status = kerberos_pac_blob_to_user_info_dc ( tmp_ctx ,
2011-12-29 04:46:41 +04:00
* pac_blob ,
smb_krb5_context - > krb5_context ,
& user_info_dc ,
2012-01-30 01:00:28 +04:00
pac_data - > pac_srv_sig ,
pac_data - > pac_kdc_sig ) ;
2011-12-29 04:46:41 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2011-12-29 15:36:14 +04:00
talloc_free ( tmp_ctx ) ;
2011-12-29 04:46:41 +04:00
return nt_status ;
}
2012-01-30 01:00:28 +04:00
talloc_steal ( pac_data , pac_data - > pac_srv_sig ) ;
talloc_steal ( pac_data , pac_data - > pac_kdc_sig ) ;
2012-01-25 03:01:10 +04:00
if ( user_info_dc - > info - > authenticated ) {
session_info_flags | = AUTH_SESSION_INFO_AUTHENTICATED ;
}
2011-12-29 04:46:41 +04:00
session_info_flags | = AUTH_SESSION_INFO_SIMPLE_PRIVILEGES ;
2011-12-29 15:36:14 +04:00
nt_status = auth_generate_session_info ( mem_ctx ,
2011-12-29 04:46:41 +04:00
NULL ,
NULL ,
user_info_dc , session_info_flags ,
session_info ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2011-12-29 15:36:14 +04:00
talloc_free ( tmp_ctx ) ;
2011-12-29 04:46:41 +04:00
return nt_status ;
}
2011-12-29 15:36:14 +04:00
talloc_free ( tmp_ctx ) ;
2011-12-29 04:46:41 +04:00
return nt_status ;
}
2008-08-27 15:36:27 +04:00
/* Check to see if we can pass the PAC across to the NETLOGON server for validation */
2016-12-21 21:08:58 +03:00
static const struct PAC_BUFFER * get_pac_buffer ( const struct PAC_DATA * pac_data ,
enum PAC_TYPE type )
{
const struct PAC_BUFFER * pac_buf = NULL ;
uint32_t i ;
for ( i = 0 ; i < pac_data - > num_buffers ; + + i ) {
pac_buf = & pac_data - > buffers [ i ] ;
if ( pac_buf - > type = = type ) {
break ;
}
}
return pac_buf ;
}
2008-08-27 15:36:27 +04:00
/* Also happens to be a really good one-step verfication of our Kerberos stack */
2012-12-05 02:11:10 +04:00
static bool test_PACVerify ( struct torture_context * tctx ,
2015-12-22 14:10:12 +03:00
struct dcerpc_pipe * p1 ,
2010-03-04 12:07:12 +03:00
struct cli_credentials * credentials ,
enum netr_SchannelType secure_channel_type ,
2012-12-05 19:23:34 +04:00
const char * test_machine_name ,
uint32_t negotiate_flags )
2008-08-27 15:36:27 +04:00
{
NTSTATUS status ;
2016-07-20 11:12:45 +03:00
bool pkinit_in_use = torture_setting_bool ( tctx , " pkinit_in_use " , false ) ;
2016-05-13 01:13:33 +03:00
bool expect_pac_upn_dns_info = torture_setting_bool ( tctx , " expect_pac_upn_dns_info " , true ) ;
2016-07-20 11:12:45 +03:00
size_t num_pac_buffers ;
2008-08-27 15:36:27 +04:00
struct netr_LogonSamLogon r ;
2008-10-28 21:03:50 +03:00
union netr_LogonLevel logon ;
union netr_Validation validation ;
uint8_t authoritative ;
struct netr_Authenticator return_authenticator ;
2008-08-27 15:36:27 +04:00
struct netr_GenericInfo generic ;
struct netr_Authenticator auth , auth2 ;
2012-12-05 02:11:10 +04:00
2009-04-06 16:54:44 +04:00
struct netlogon_creds_CredentialState * creds ;
2008-08-27 15:36:27 +04:00
struct gensec_security * gensec_client_context ;
struct gensec_security * gensec_server_context ;
2015-02-26 19:03:44 +03:00
struct cli_credentials * client_creds ;
struct cli_credentials * server_creds ;
2008-08-27 15:36:27 +04:00
2008-08-28 10:30:17 +04:00
DATA_BLOB client_to_server , server_to_client , pac_wrapped , payload ;
2008-08-27 15:36:27 +04:00
struct PAC_Validate pac_wrapped_struct ;
2016-07-20 11:12:45 +03:00
struct PAC_DATA pac_data_struct ;
2012-12-05 02:11:10 +04:00
2008-08-27 15:36:27 +04:00
enum ndr_err_code ndr_err ;
2011-12-29 04:46:41 +04:00
struct auth4_context * auth_context ;
2008-08-27 15:36:27 +04:00
struct auth_session_info * session_info ;
2012-01-30 01:00:28 +04:00
struct pac_data * pac_data ;
2016-07-20 11:12:45 +03:00
const struct PAC_BUFFER * pac_buf = NULL ;
2008-08-27 15:36:27 +04:00
2015-12-22 14:10:12 +03:00
struct dcerpc_pipe * p = NULL ;
struct dcerpc_binding_handle * b = NULL ;
2008-08-27 15:36:27 +04:00
TALLOC_CTX * tmp_ctx = talloc_new ( tctx ) ;
torture_assert ( tctx , tmp_ctx ! = NULL , " talloc_new() failed " ) ;
2012-12-05 19:23:34 +04:00
torture_comment ( tctx ,
" Testing PAC Verify (secure_channel_type: %d, machine: %s, negotiate_flags: 0x%08x \n " ,
secure_channel_type , test_machine_name , negotiate_flags ) ;
2015-02-26 19:03:44 +03:00
/*
* Copy the credentials in order to use a different MEMORY krb5 ccache
* for each client / server setup . The MEMORY cache identifier is a
* pointer to the creds container . If we copy it the pointer changes and
* we will get a new clean memory cache .
*/
client_creds = cli_credentials_shallow_copy ( tmp_ctx ,
2017-05-10 02:10:03 +03:00
popt_get_cmdline_credentials ( ) ) ;
2015-02-26 19:03:44 +03:00
torture_assert ( tctx , client_creds , " Failed to copy of credentials " ) ;
2016-07-20 11:12:45 +03:00
if ( ! pkinit_in_use ) {
/* Invalidate the gss creds container to allocate a new MEMORY ccache */
cli_credentials_invalidate_ccache ( client_creds , CRED_SPECIFIED ) ;
}
2015-02-26 19:03:44 +03:00
server_creds = cli_credentials_shallow_copy ( tmp_ctx ,
credentials ) ;
torture_assert ( tctx , server_creds , " Failed to copy of credentials " ) ;
2015-12-22 14:10:12 +03:00
if ( ! test_SetupCredentials2 ( p1 , tctx , negotiate_flags ,
2015-02-26 19:03:44 +03:00
server_creds , secure_channel_type ,
2008-08-27 15:36:27 +04:00
& creds ) ) {
return false ;
}
2015-12-22 14:10:12 +03:00
if ( ! test_SetupCredentialsPipe ( p1 , tctx , server_creds , creds ,
DCERPC_SIGN | DCERPC_SEAL , & p ) ) {
return false ;
}
b = p - > binding_handle ;
2008-08-27 15:36:27 +04:00
2011-12-29 04:46:41 +04:00
auth_context = talloc_zero ( tmp_ctx , struct auth4_context ) ;
torture_assert ( tctx , auth_context ! = NULL , " talloc_new() failed " ) ;
auth_context - > generate_session_info_pac = test_generate_session_info_pac ;
2011-10-17 11:22:33 +04:00
status = gensec_client_start ( tctx , & gensec_client_context ,
2010-07-16 08:32:42 +04:00
lpcfg_gensec_settings ( tctx , tctx - > lp_ctx ) ) ;
2008-08-27 15:36:27 +04:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_client_start (client) failed " ) ;
2010-03-04 12:07:12 +03:00
status = gensec_set_target_hostname ( gensec_client_context , test_machine_name ) ;
2008-08-27 15:36:27 +04:00
2015-02-26 19:03:44 +03:00
status = gensec_set_credentials ( gensec_client_context , client_creds ) ;
2008-08-27 15:36:27 +04:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_set_credentials (client) failed " ) ;
status = gensec_start_mech_by_sasl_name ( gensec_client_context , " GSSAPI " ) ;
torture_assert_ntstatus_ok ( tctx , status , " gensec_start_mech_by_sasl_name (client) failed " ) ;
2011-10-17 11:22:33 +04:00
status = gensec_server_start ( tctx ,
2010-07-16 08:32:42 +04:00
lpcfg_gensec_settings ( tctx , tctx - > lp_ctx ) ,
2011-12-29 04:46:41 +04:00
auth_context , & gensec_server_context ) ;
2008-08-27 15:36:27 +04:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_server_start (server) failed " ) ;
2015-02-26 19:03:44 +03:00
status = gensec_set_credentials ( gensec_server_context , server_creds ) ;
2008-08-27 15:36:27 +04:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_set_credentials (server) failed " ) ;
status = gensec_start_mech_by_sasl_name ( gensec_server_context , " GSSAPI " ) ;
torture_assert_ntstatus_ok ( tctx , status , " gensec_start_mech_by_sasl_name (server) failed " ) ;
server_to_client = data_blob ( NULL , 0 ) ;
2012-12-05 02:11:10 +04:00
2008-08-27 15:36:27 +04:00
do {
/* Do a client-server update dance */
2013-12-13 22:56:13 +04:00
status = gensec_update ( gensec_client_context , tmp_ctx , server_to_client , & client_to_server ) ;
2008-08-27 15:36:27 +04:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_MORE_PROCESSING_REQUIRED ) ) { ;
torture_assert_ntstatus_ok ( tctx , status , " gensec_update (client) failed " ) ;
}
2013-12-13 22:56:13 +04:00
status = gensec_update ( gensec_server_context , tmp_ctx , client_to_server , & server_to_client ) ;
2008-08-27 15:36:27 +04:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_MORE_PROCESSING_REQUIRED ) ) { ;
torture_assert_ntstatus_ok ( tctx , status , " gensec_update (server) failed " ) ;
}
2008-09-23 04:14:26 +04:00
if ( NT_STATUS_IS_OK ( status ) ) {
2008-08-27 15:36:27 +04:00
break ;
}
} while ( 1 ) ;
/* Extract the PAC using Samba's code */
2011-08-01 09:39:01 +04:00
status = gensec_session_info ( gensec_server_context , gensec_server_context , & session_info ) ;
2008-08-28 10:30:17 +04:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_session_info failed " ) ;
2011-02-08 08:53:13 +03:00
2012-01-30 01:00:28 +04:00
pac_data = talloc_get_type ( auth_context - > private_data , struct pac_data ) ;
torture_assert ( tctx , pac_data ! = NULL , " gensec_update failed to fill in pac_data in auth_context " ) ;
torture_assert ( tctx , pac_data - > pac_srv_sig ! = NULL , " pac_srv_sig not present " ) ;
torture_assert ( tctx , pac_data - > pac_kdc_sig ! = NULL , " pac_kdc_sig not present " ) ;
2016-07-20 11:12:45 +03:00
ndr_err = ndr_pull_struct_blob ( & pac_data - > pac_blob , tmp_ctx , & pac_data_struct ,
( ndr_pull_flags_fn_t ) ndr_pull_PAC_DATA ) ;
torture_assert ( tctx , NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) , " ndr_pull_struct_blob of PAC_DATA structure failed " ) ;
num_pac_buffers = 4 ;
if ( expect_pac_upn_dns_info ) {
num_pac_buffers + = 1 ;
}
if ( pkinit_in_use ) {
num_pac_buffers + = 1 ;
}
torture_assert_int_equal ( tctx , pac_data_struct . version , 0 , " version " ) ;
torture_assert_int_equal ( tctx , pac_data_struct . num_buffers , num_pac_buffers , " num_buffers " ) ;
2016-12-21 21:08:58 +03:00
pac_buf = get_pac_buffer ( & pac_data_struct , PAC_TYPE_LOGON_INFO ) ;
torture_assert_not_null ( tctx , pac_buf , " PAC_TYPE_LOGON_INFO " ) ;
torture_assert ( tctx ,
pac_buf - > info ! = NULL ,
2016-07-20 11:12:45 +03:00
" PAC_TYPE_LOGON_INFO info " ) ;
2016-12-21 21:08:58 +03:00
2016-07-20 11:12:45 +03:00
if ( pkinit_in_use ) {
2016-12-21 21:08:58 +03:00
pac_buf = get_pac_buffer ( & pac_data_struct , PAC_TYPE_CREDENTIAL_INFO ) ;
torture_assert_not_null ( tctx , pac_buf , " PAC_TYPE_CREDENTIAL_INFO " ) ;
torture_assert ( tctx ,
pac_buf - > info ! = NULL ,
2016-07-20 11:12:45 +03:00
" PAC_TYPE_CREDENTIAL_INFO info " ) ;
}
2016-12-21 21:08:58 +03:00
pac_buf = get_pac_buffer ( & pac_data_struct , PAC_TYPE_LOGON_NAME ) ;
torture_assert_not_null ( tctx , pac_buf , " PAC_TYPE_LOGON_NAME " ) ;
torture_assert ( tctx ,
pac_buf - > info ! = NULL ,
2016-07-20 11:12:45 +03:00
" PAC_TYPE_LOGON_NAME info " ) ;
2016-12-21 21:08:58 +03:00
2016-07-20 11:12:45 +03:00
if ( expect_pac_upn_dns_info ) {
2016-12-21 21:08:58 +03:00
pac_buf = get_pac_buffer ( & pac_data_struct , PAC_TYPE_UPN_DNS_INFO ) ;
torture_assert_not_null ( tctx , pac_buf , " PAC_TYPE_UPN_DNS_INFO " ) ;
torture_assert ( tctx ,
pac_buf - > info ! = NULL ,
2016-07-20 11:12:45 +03:00
" PAC_TYPE_UPN_DNS_INFO info " ) ;
}
2016-12-21 21:08:58 +03:00
pac_buf = get_pac_buffer ( & pac_data_struct , PAC_TYPE_SRV_CHECKSUM ) ;
torture_assert_not_null ( tctx , pac_buf , " PAC_TYPE_SRV_CHECKSUM " ) ;
torture_assert ( tctx ,
pac_buf - > info ! = NULL ,
2016-07-20 11:12:45 +03:00
" PAC_TYPE_SRV_CHECKSUM info " ) ;
2016-12-21 21:08:58 +03:00
pac_buf = get_pac_buffer ( & pac_data_struct , PAC_TYPE_KDC_CHECKSUM ) ;
torture_assert_not_null ( tctx , pac_buf , " PAC_TYPE_KDC_CHECKSUM " ) ;
torture_assert ( tctx ,
pac_buf - > info ! = NULL ,
2016-07-20 11:12:45 +03:00
" PAC_TYPE_KDC_CHECKSUM info " ) ;
2012-01-30 01:00:28 +04:00
pac_wrapped_struct . ChecksumLength = pac_data - > pac_srv_sig - > signature . length ;
pac_wrapped_struct . SignatureType = pac_data - > pac_kdc_sig - > type ;
pac_wrapped_struct . SignatureLength = pac_data - > pac_kdc_sig - > signature . length ;
2008-08-28 10:30:17 +04:00
pac_wrapped_struct . ChecksumAndSignature = payload
2012-12-05 02:11:10 +04:00
= data_blob_talloc ( tmp_ctx , NULL ,
2008-08-28 10:30:17 +04:00
pac_wrapped_struct . ChecksumLength
+ pac_wrapped_struct . SignatureLength ) ;
2012-12-05 02:11:10 +04:00
memcpy ( & payload . data [ 0 ] ,
2012-01-30 01:00:28 +04:00
pac_data - > pac_srv_sig - > signature . data ,
2008-08-28 10:30:17 +04:00
pac_wrapped_struct . ChecksumLength ) ;
2012-12-05 02:11:10 +04:00
memcpy ( & payload . data [ pac_wrapped_struct . ChecksumLength ] ,
2012-01-30 01:00:28 +04:00
pac_data - > pac_kdc_sig - > signature . data ,
2008-08-28 10:30:17 +04:00
pac_wrapped_struct . SignatureLength ) ;
2008-08-27 15:36:27 +04:00
2010-05-09 19:20:01 +04:00
ndr_err = ndr_push_struct_blob ( & pac_wrapped , tmp_ctx , & pac_wrapped_struct ,
2008-08-27 15:36:27 +04:00
( ndr_push_flags_fn_t ) ndr_push_PAC_Validate ) ;
torture_assert ( tctx , NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) , " ndr_push_struct_blob of PACValidate structure failed " ) ;
2012-12-05 02:11:10 +04:00
2008-08-29 09:06:30 +04:00
torture_assert ( tctx , ( creds - > negotiate_flags & NETLOGON_NEG_ARCFOUR ) , " not willing to even try a PACValidate without RC4 encryption " ) ;
2012-12-05 19:23:34 +04:00
if ( creds - > negotiate_flags & NETLOGON_NEG_SUPPORTS_AES ) {
netlogon_creds_aes_encrypt ( creds , pac_wrapped . data , pac_wrapped . length ) ;
} else {
netlogon_creds_arcfour_crypt ( creds , pac_wrapped . data , pac_wrapped . length ) ;
}
2008-08-29 09:06:30 +04:00
2008-09-03 08:19:16 +04:00
generic . length = pac_wrapped . length ;
generic . data = pac_wrapped . data ;
2008-08-27 15:36:27 +04:00
/* Validate it over the netlogon pipe */
generic . identity_info . parameter_control = 0 ;
generic . identity_info . logon_id_high = 0 ;
generic . identity_info . logon_id_low = 0 ;
2011-02-08 08:53:13 +03:00
generic . identity_info . domain_name . string = session_info - > info - > domain_name ;
generic . identity_info . account_name . string = session_info - > info - > account_name ;
2010-03-04 12:07:12 +03:00
generic . identity_info . workstation . string = test_machine_name ;
2008-08-27 15:36:27 +04:00
generic . package_name . string = " Kerberos " ;
2008-10-28 21:03:50 +03:00
logon . generic = & generic ;
2008-08-27 15:36:27 +04:00
ZERO_STRUCT ( auth2 ) ;
2009-04-06 16:54:44 +04:00
netlogon_creds_client_authenticator ( creds , & auth ) ;
2008-08-27 15:36:27 +04:00
r . in . credential = & auth ;
r . in . return_authenticator = & auth2 ;
2008-10-28 21:03:50 +03:00
r . in . logon = & logon ;
2008-08-27 15:36:27 +04:00
r . in . logon_level = NetlogonGenericInformation ;
r . in . server_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2015-02-26 19:03:44 +03:00
r . in . computer_name = cli_credentials_get_workstation ( server_creds ) ;
2008-08-27 15:36:27 +04:00
r . in . validation_level = NetlogonValidationGenericInfo2 ;
2008-10-28 21:03:50 +03:00
r . out . validation = & validation ;
r . out . authoritative = & authoritative ;
r . out . return_authenticator = & return_authenticator ;
2008-08-27 15:36:27 +04:00
2010-03-19 16:48:36 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_netr_LogonSamLogon_r ( b , tctx , & r ) ,
" LogonSamLogon failed " ) ;
2008-08-27 15:36:27 +04:00
2010-03-19 16:48:36 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result , " LogonSamLogon failed " ) ;
2012-12-05 02:11:10 +04:00
2008-09-03 08:19:16 +04:00
/* This will break the signature nicely (even in the crypto wrapping), check we get a logon failure */
generic . data [ generic . length - 1 ] + + ;
2008-10-28 21:03:50 +03:00
logon . generic = & generic ;
2008-09-03 08:19:16 +04:00
ZERO_STRUCT ( auth2 ) ;
2009-04-06 16:54:44 +04:00
netlogon_creds_client_authenticator ( creds , & auth ) ;
2008-09-03 08:19:16 +04:00
r . in . credential = & auth ;
r . in . return_authenticator = & auth2 ;
r . in . logon_level = NetlogonGenericInformation ;
2008-10-28 21:03:50 +03:00
r . in . logon = & logon ;
2008-09-03 08:19:16 +04:00
r . in . server_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2015-02-26 19:03:44 +03:00
r . in . computer_name = cli_credentials_get_workstation ( server_creds ) ;
2008-09-03 08:19:16 +04:00
r . in . validation_level = NetlogonValidationGenericInfo2 ;
2010-03-19 16:48:36 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_netr_LogonSamLogon_r ( b , tctx , & r ) ,
" LogonSamLogon failed " ) ;
2008-09-03 08:19:16 +04:00
2010-03-19 16:48:36 +03:00
torture_assert_ntstatus_equal ( tctx , r . out . result , NT_STATUS_LOGON_FAILURE , " LogonSamLogon failed " ) ;
2012-12-05 02:11:10 +04:00
torture_assert ( tctx , netlogon_creds_client_check ( creds , & r . out . return_authenticator - > cred ) ,
2008-09-03 08:19:16 +04:00
" Credential chaining failed " ) ;
/* This will break the parsing nicely (even in the crypto wrapping), check we get INVALID_PARAMETER */
generic . length - - ;
2008-10-28 21:03:50 +03:00
logon . generic = & generic ;
2008-09-03 08:19:16 +04:00
ZERO_STRUCT ( auth2 ) ;
2009-04-06 16:54:44 +04:00
netlogon_creds_client_authenticator ( creds , & auth ) ;
2008-09-03 08:19:16 +04:00
r . in . credential = & auth ;
r . in . return_authenticator = & auth2 ;
r . in . logon_level = NetlogonGenericInformation ;
2008-10-28 21:03:50 +03:00
r . in . logon = & logon ;
2008-09-03 08:19:16 +04:00
r . in . server_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2015-02-26 19:03:44 +03:00
r . in . computer_name = cli_credentials_get_workstation ( server_creds ) ;
2008-09-03 08:19:16 +04:00
r . in . validation_level = NetlogonValidationGenericInfo2 ;
2010-03-19 16:48:36 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_netr_LogonSamLogon_r ( b , tctx , & r ) ,
" LogonSamLogon failed " ) ;
2008-09-03 08:19:16 +04:00
2010-03-19 16:48:36 +03:00
torture_assert_ntstatus_equal ( tctx , r . out . result , NT_STATUS_INVALID_PARAMETER , " LogonSamLogon failed " ) ;
2012-12-05 02:11:10 +04:00
torture_assert ( tctx , netlogon_creds_client_check ( creds ,
& r . out . return_authenticator - > cred ) ,
2008-09-03 08:19:16 +04:00
" Credential chaining failed " ) ;
2012-01-30 01:00:28 +04:00
pac_wrapped_struct . ChecksumLength = pac_data - > pac_srv_sig - > signature . length ;
pac_wrapped_struct . SignatureType = pac_data - > pac_kdc_sig - > type ;
2012-12-05 02:11:10 +04:00
2008-09-03 08:19:16 +04:00
/* Break the SignatureType */
pac_wrapped_struct . SignatureType + + ;
2012-01-30 01:00:28 +04:00
pac_wrapped_struct . SignatureLength = pac_data - > pac_kdc_sig - > signature . length ;
2008-09-03 08:19:16 +04:00
pac_wrapped_struct . ChecksumAndSignature = payload
2012-12-05 02:11:10 +04:00
= data_blob_talloc ( tmp_ctx , NULL ,
2008-09-03 08:19:16 +04:00
pac_wrapped_struct . ChecksumLength
+ pac_wrapped_struct . SignatureLength ) ;
2012-12-05 02:11:10 +04:00
memcpy ( & payload . data [ 0 ] ,
2012-01-30 01:00:28 +04:00
pac_data - > pac_srv_sig - > signature . data ,
2008-09-03 08:19:16 +04:00
pac_wrapped_struct . ChecksumLength ) ;
2012-12-05 02:11:10 +04:00
memcpy ( & payload . data [ pac_wrapped_struct . ChecksumLength ] ,
2012-01-30 01:00:28 +04:00
pac_data - > pac_kdc_sig - > signature . data ,
2008-09-03 08:19:16 +04:00
pac_wrapped_struct . SignatureLength ) ;
2012-12-05 02:11:10 +04:00
2010-05-09 19:20:01 +04:00
ndr_err = ndr_push_struct_blob ( & pac_wrapped , tmp_ctx , & pac_wrapped_struct ,
2008-09-03 08:19:16 +04:00
( ndr_push_flags_fn_t ) ndr_push_PAC_Validate ) ;
torture_assert ( tctx , NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) , " ndr_push_struct_blob of PACValidate structure failed " ) ;
2012-12-05 02:11:10 +04:00
2008-09-03 08:19:16 +04:00
torture_assert ( tctx , ( creds - > negotiate_flags & NETLOGON_NEG_ARCFOUR ) , " not willing to even try a PACValidate without RC4 encryption " ) ;
2012-12-05 19:23:34 +04:00
if ( creds - > negotiate_flags & NETLOGON_NEG_SUPPORTS_AES ) {
netlogon_creds_aes_encrypt ( creds , pac_wrapped . data , pac_wrapped . length ) ;
} else {
netlogon_creds_arcfour_crypt ( creds , pac_wrapped . data , pac_wrapped . length ) ;
}
2012-12-05 02:11:10 +04:00
2008-09-03 08:19:16 +04:00
generic . length = pac_wrapped . length ;
generic . data = pac_wrapped . data ;
2008-10-28 21:03:50 +03:00
logon . generic = & generic ;
2008-09-03 08:19:16 +04:00
ZERO_STRUCT ( auth2 ) ;
2009-04-06 16:54:44 +04:00
netlogon_creds_client_authenticator ( creds , & auth ) ;
2008-09-03 08:19:16 +04:00
r . in . credential = & auth ;
r . in . return_authenticator = & auth2 ;
r . in . logon_level = NetlogonGenericInformation ;
2008-10-28 21:03:50 +03:00
r . in . logon = & logon ;
2008-09-03 08:19:16 +04:00
r . in . server_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2015-02-26 19:03:44 +03:00
r . in . computer_name = cli_credentials_get_workstation ( server_creds ) ;
2008-09-03 08:19:16 +04:00
r . in . validation_level = NetlogonValidationGenericInfo2 ;
2012-12-05 02:11:10 +04:00
2010-03-19 16:48:36 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_netr_LogonSamLogon_r ( b , tctx , & r ) ,
" LogonSamLogon failed " ) ;
2012-12-05 02:11:10 +04:00
2010-03-19 16:48:36 +03:00
torture_assert_ntstatus_equal ( tctx , r . out . result , NT_STATUS_LOGON_FAILURE , " LogonSamLogon failed " ) ;
2012-12-05 02:11:10 +04:00
torture_assert ( tctx , netlogon_creds_client_check ( creds , & r . out . return_authenticator - > cred ) ,
2008-08-27 15:36:27 +04:00
" Credential chaining failed " ) ;
2012-01-30 01:00:28 +04:00
pac_wrapped_struct . ChecksumLength = pac_data - > pac_srv_sig - > signature . length ;
pac_wrapped_struct . SignatureType = pac_data - > pac_kdc_sig - > type ;
pac_wrapped_struct . SignatureLength = pac_data - > pac_kdc_sig - > signature . length ;
2008-09-03 08:19:16 +04:00
pac_wrapped_struct . ChecksumAndSignature = payload
2012-12-05 02:11:10 +04:00
= data_blob_talloc ( tmp_ctx , NULL ,
2008-09-03 08:19:16 +04:00
pac_wrapped_struct . ChecksumLength
+ pac_wrapped_struct . SignatureLength ) ;
2012-12-05 02:11:10 +04:00
memcpy ( & payload . data [ 0 ] ,
2012-01-30 01:00:28 +04:00
pac_data - > pac_srv_sig - > signature . data ,
2008-09-03 08:19:16 +04:00
pac_wrapped_struct . ChecksumLength ) ;
2012-12-05 02:11:10 +04:00
memcpy ( & payload . data [ pac_wrapped_struct . ChecksumLength ] ,
2012-01-30 01:00:28 +04:00
pac_data - > pac_kdc_sig - > signature . data ,
2008-09-03 08:19:16 +04:00
pac_wrapped_struct . SignatureLength ) ;
2012-12-05 02:11:10 +04:00
2008-09-03 08:19:16 +04:00
/* Break the signature length */
pac_wrapped_struct . SignatureLength + + ;
2010-05-09 19:20:01 +04:00
ndr_err = ndr_push_struct_blob ( & pac_wrapped , tmp_ctx , & pac_wrapped_struct ,
2008-09-03 08:19:16 +04:00
( ndr_push_flags_fn_t ) ndr_push_PAC_Validate ) ;
torture_assert ( tctx , NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) , " ndr_push_struct_blob of PACValidate structure failed " ) ;
2012-12-05 02:11:10 +04:00
2008-09-03 08:19:16 +04:00
torture_assert ( tctx , ( creds - > negotiate_flags & NETLOGON_NEG_ARCFOUR ) , " not willing to even try a PACValidate without RC4 encryption " ) ;
2012-12-05 19:23:34 +04:00
if ( creds - > negotiate_flags & NETLOGON_NEG_SUPPORTS_AES ) {
netlogon_creds_aes_encrypt ( creds , pac_wrapped . data , pac_wrapped . length ) ;
} else {
netlogon_creds_arcfour_crypt ( creds , pac_wrapped . data , pac_wrapped . length ) ;
}
2012-12-05 02:11:10 +04:00
2008-09-03 08:19:16 +04:00
generic . length = pac_wrapped . length ;
generic . data = pac_wrapped . data ;
2008-10-28 21:03:50 +03:00
logon . generic = & generic ;
2008-09-03 08:19:16 +04:00
ZERO_STRUCT ( auth2 ) ;
2009-04-06 16:54:44 +04:00
netlogon_creds_client_authenticator ( creds , & auth ) ;
2008-09-03 08:19:16 +04:00
r . in . credential = & auth ;
r . in . return_authenticator = & auth2 ;
r . in . logon_level = NetlogonGenericInformation ;
2008-10-28 21:03:50 +03:00
r . in . logon = & logon ;
2008-09-03 08:19:16 +04:00
r . in . server_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2015-02-26 19:03:44 +03:00
r . in . computer_name = cli_credentials_get_workstation ( server_creds ) ;
2008-09-03 08:19:16 +04:00
r . in . validation_level = NetlogonValidationGenericInfo2 ;
2012-12-05 02:11:10 +04:00
2010-03-19 16:48:36 +03:00
torture_assert_ntstatus_ok ( tctx , dcerpc_netr_LogonSamLogon_r ( b , tctx , & r ) ,
" LogonSamLogon failed " ) ;
2012-12-05 02:11:10 +04:00
2010-03-19 16:48:36 +03:00
torture_assert_ntstatus_equal ( tctx , r . out . result , NT_STATUS_INVALID_PARAMETER , " LogonSamLogon failed " ) ;
2012-12-05 02:11:10 +04:00
torture_assert ( tctx , netlogon_creds_client_check ( creds , & r . out . return_authenticator - > cred ) ,
2008-09-03 08:19:16 +04:00
" Credential chaining failed " ) ;
2010-03-04 12:07:12 +03:00
2015-04-14 11:56:53 +03:00
talloc_free ( tmp_ctx ) ;
2010-03-04 12:07:12 +03:00
return true ;
}
2012-12-05 19:23:34 +04:00
static bool test_PACVerify_bdc_arcfour ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct cli_credentials * credentials )
2010-03-04 12:07:12 +03:00
{
2012-12-05 19:23:34 +04:00
return test_PACVerify ( tctx , p , credentials , SEC_CHAN_BDC ,
TEST_MACHINE_NAME_BDC ,
NETLOGON_NEG_AUTH2_ADS_FLAGS ) ;
2010-03-04 12:07:12 +03:00
}
2012-12-05 19:23:34 +04:00
static bool test_PACVerify_bdc_aes ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct cli_credentials * credentials )
{
return test_PACVerify ( tctx , p , credentials , SEC_CHAN_BDC ,
TEST_MACHINE_NAME_BDC ,
NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES ) ;
}
static bool test_PACVerify_workstation_arcfour ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct cli_credentials * credentials )
2010-03-04 12:07:12 +03:00
{
2012-12-05 19:23:34 +04:00
return test_PACVerify ( tctx , p , credentials , SEC_CHAN_WKSTA ,
TEST_MACHINE_NAME_WKSTA ,
NETLOGON_NEG_AUTH2_ADS_FLAGS ) ;
}
static bool test_PACVerify_workstation_aes ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct cli_credentials * credentials )
{
return test_PACVerify ( tctx , p , credentials , SEC_CHAN_WKSTA ,
TEST_MACHINE_NAME_WKSTA ,
NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES ) ;
2010-03-04 12:07:12 +03:00
}
2010-11-02 09:14:55 +03:00
static bool test_PACVerify_workstation_des ( struct torture_context * tctx ,
struct dcerpc_pipe * p , struct cli_credentials * credentials , struct test_join * join_ctx )
{
struct samr_SetUserInfo r ;
union samr_UserInfo user_info ;
struct dcerpc_pipe * samr_pipe = torture_join_samr_pipe ( join_ctx ) ;
struct smb_krb5_context * smb_krb5_context ;
krb5_error_code ret ;
2017-05-10 02:10:03 +03:00
ret = cli_credentials_get_krb5_context ( popt_get_cmdline_credentials ( ) ,
tctx - > lp_ctx , & smb_krb5_context ) ;
2010-11-02 09:14:55 +03:00
torture_assert_int_equal ( tctx , ret , 0 , " cli_credentials_get_krb5_context() failed " ) ;
2014-04-29 20:14:35 +04:00
if ( smb_krb5_get_allowed_weak_crypto ( smb_krb5_context - > krb5_context ) = = FALSE ) {
2010-11-02 09:14:55 +03:00
torture_skip ( tctx , " Cannot test DES without [libdefaults] allow_weak_crypto = yes " ) ;
}
/* Mark this workstation with DES-only */
user_info . info16 . acct_flags = ACB_USE_DES_KEY_ONLY | ACB_WSTRUST ;
r . in . user_handle = torture_join_samr_user_policy ( join_ctx ) ;
r . in . level = 16 ;
r . in . info = & user_info ;
torture_assert_ntstatus_ok ( tctx , dcerpc_samr_SetUserInfo_r ( samr_pipe - > binding_handle , tctx , & r ) ,
" failed to set DES info account flags " ) ;
torture_assert_ntstatus_ok ( tctx , r . out . result ,
" failed to set DES into account flags " ) ;
2012-12-05 19:23:34 +04:00
return test_PACVerify ( tctx , p , credentials , SEC_CHAN_WKSTA ,
TEST_MACHINE_NAME_WKSTA_DES ,
NETLOGON_NEG_AUTH2_ADS_FLAGS ) ;
2010-11-02 09:14:55 +03:00
}
2010-03-04 12:07:12 +03:00
/* Check various ways to get the PAC, in particular check the group membership and other details between the PAC from a normal kinit, S2U4Self and a SamLogon */
2015-02-07 14:48:54 +03:00
# ifdef SAMBA4_USES_HEIMDAL
2010-03-04 12:07:12 +03:00
static bool test_S2U4Self ( struct torture_context * tctx ,
2015-12-22 14:10:12 +03:00
struct dcerpc_pipe * p1 ,
2010-03-04 12:07:12 +03:00
struct cli_credentials * credentials ,
enum netr_SchannelType secure_channel_type ,
2012-12-07 15:51:10 +04:00
const char * test_machine_name ,
uint32_t negotiate_flags )
2010-03-04 12:07:12 +03:00
{
NTSTATUS status ;
2015-12-22 14:10:12 +03:00
struct dcerpc_pipe * p = NULL ;
struct dcerpc_binding_handle * b = NULL ;
2010-03-04 12:07:12 +03:00
struct netr_LogonSamLogon r ;
union netr_LogonLevel logon ;
union netr_Validation validation ;
uint8_t authoritative ;
struct netr_Authenticator auth , auth2 ;
DATA_BLOB client_to_server , server_to_client ;
struct netlogon_creds_CredentialState * creds ;
struct gensec_security * gensec_client_context ;
struct gensec_security * gensec_server_context ;
2015-02-26 19:03:44 +03:00
struct cli_credentials * client_creds ;
struct cli_credentials * server_creds ;
2010-03-04 12:07:12 +03:00
2011-12-29 04:46:41 +04:00
struct auth4_context * auth_context ;
2010-03-04 12:07:12 +03:00
struct auth_session_info * kinit_session_info ;
struct auth_session_info * s2u4self_session_info ;
2011-02-08 08:53:13 +03:00
struct auth_user_info_dc * netlogon_user_info_dc ;
2010-03-04 12:07:12 +03:00
struct netr_NetworkInfo ninfo ;
DATA_BLOB names_blob , chal , lm_resp , nt_resp ;
size_t i ;
int flags = CLI_CRED_NTLMv2_AUTH ;
struct dom_sid * builtin_domain ;
TALLOC_CTX * tmp_ctx = talloc_new ( tctx ) ;
torture_assert ( tctx , tmp_ctx ! = NULL , " talloc_new() failed " ) ;
2012-12-07 15:51:10 +04:00
torture_comment ( tctx ,
" Testing S4U2SELF (secure_channel_type: %d, machine: %s, negotiate_flags: 0x%08x \n " ,
secure_channel_type , test_machine_name , negotiate_flags ) ;
2015-02-26 19:03:44 +03:00
/*
* Copy the credentials in order to use a different MEMORY krb5 ccache
* for each client / server setup . The MEMORY cache identifier is a
* pointer to the creds container . If we copy it the pointer changes and
* we will get a new clean memory cache .
*/
client_creds = cli_credentials_shallow_copy ( tmp_ctx ,
2017-05-10 02:10:03 +03:00
popt_get_cmdline_credentials ( ) ) ;
2015-02-26 19:03:44 +03:00
torture_assert ( tctx , client_creds , " Failed to copy of credentials " ) ;
server_creds = cli_credentials_shallow_copy ( tmp_ctx ,
credentials ) ;
torture_assert ( tctx , server_creds , " Failed to copy of credentials " ) ;
2015-12-22 14:10:12 +03:00
if ( ! test_SetupCredentials2 ( p1 , tctx , negotiate_flags ,
server_creds , secure_channel_type ,
& creds ) ) {
return false ;
}
if ( ! test_SetupCredentialsPipe ( p1 , tctx , server_creds , creds ,
DCERPC_SIGN | DCERPC_SEAL , & p ) ) {
return false ;
}
b = p - > binding_handle ;
2011-12-29 04:46:41 +04:00
auth_context = talloc_zero ( tmp_ctx , struct auth4_context ) ;
torture_assert ( tctx , auth_context ! = NULL , " talloc_new() failed " ) ;
auth_context - > generate_session_info_pac = test_generate_session_info_pac ;
2010-03-04 12:07:12 +03:00
/* First, do a normal Kerberos connection */
2011-10-17 11:22:33 +04:00
status = gensec_client_start ( tctx , & gensec_client_context ,
2010-07-16 08:32:42 +04:00
lpcfg_gensec_settings ( tctx , tctx - > lp_ctx ) ) ;
2010-03-04 12:07:12 +03:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_client_start (client) failed " ) ;
status = gensec_set_target_hostname ( gensec_client_context , test_machine_name ) ;
2015-02-26 19:03:44 +03:00
status = gensec_set_credentials ( gensec_client_context , client_creds ) ;
2010-03-04 12:07:12 +03:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_set_credentials (client) failed " ) ;
status = gensec_start_mech_by_sasl_name ( gensec_client_context , " GSSAPI " ) ;
torture_assert_ntstatus_ok ( tctx , status , " gensec_start_mech_by_sasl_name (client) failed " ) ;
2011-10-17 11:22:33 +04:00
status = gensec_server_start ( tctx ,
2010-07-16 08:32:42 +04:00
lpcfg_gensec_settings ( tctx , tctx - > lp_ctx ) ,
2011-12-29 04:46:41 +04:00
auth_context , & gensec_server_context ) ;
2010-03-04 12:07:12 +03:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_server_start (server) failed " ) ;
2015-02-26 19:03:44 +03:00
status = gensec_set_credentials ( gensec_server_context , server_creds ) ;
2010-03-04 12:07:12 +03:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_set_credentials (server) failed " ) ;
status = gensec_start_mech_by_sasl_name ( gensec_server_context , " GSSAPI " ) ;
torture_assert_ntstatus_ok ( tctx , status , " gensec_start_mech_by_sasl_name (server) failed " ) ;
server_to_client = data_blob ( NULL , 0 ) ;
do {
/* Do a client-server update dance */
2013-12-13 22:56:13 +04:00
status = gensec_update ( gensec_client_context , tmp_ctx , server_to_client , & client_to_server ) ;
2010-03-04 12:07:12 +03:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_MORE_PROCESSING_REQUIRED ) ) { ;
torture_assert_ntstatus_ok ( tctx , status , " gensec_update (client) failed " ) ;
}
2013-12-13 22:56:13 +04:00
status = gensec_update ( gensec_server_context , tmp_ctx , client_to_server , & server_to_client ) ;
2010-03-04 12:07:12 +03:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_MORE_PROCESSING_REQUIRED ) ) { ;
torture_assert_ntstatus_ok ( tctx , status , " gensec_update (server) failed " ) ;
}
if ( NT_STATUS_IS_OK ( status ) ) {
break ;
}
} while ( 1 ) ;
/* Extract the PAC using Samba's code */
2011-08-01 09:39:01 +04:00
status = gensec_session_info ( gensec_server_context , gensec_server_context , & kinit_session_info ) ;
2010-03-04 12:07:12 +03:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_session_info failed " ) ;
/* Now do the dance with S2U4Self */
/* Wipe out any existing ccache */
2015-02-26 19:03:44 +03:00
cli_credentials_invalidate_ccache ( client_creds , CRED_SPECIFIED ) ;
cli_credentials_invalidate_ccache ( server_creds , CRED_SPECIFIED ) ;
cli_credentials_set_impersonate_principal ( server_creds ,
cli_credentials_get_principal ( client_creds , tmp_ctx ) ,
2011-04-22 13:22:50 +04:00
talloc_asprintf ( tmp_ctx , " host/%s " , test_machine_name ) ) ;
2010-03-04 12:07:12 +03:00
2011-10-17 11:22:33 +04:00
status = gensec_client_start ( tctx , & gensec_client_context ,
2010-07-16 08:32:42 +04:00
lpcfg_gensec_settings ( tctx , tctx - > lp_ctx ) ) ;
2010-03-04 12:07:12 +03:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_client_start (client) failed " ) ;
status = gensec_set_target_hostname ( gensec_client_context , test_machine_name ) ;
/* We now set the same credentials on both client and server contexts */
2015-02-26 19:03:44 +03:00
status = gensec_set_credentials ( gensec_client_context , server_creds ) ;
2010-03-04 12:07:12 +03:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_set_credentials (client) failed " ) ;
status = gensec_start_mech_by_sasl_name ( gensec_client_context , " GSSAPI " ) ;
torture_assert_ntstatus_ok ( tctx , status , " gensec_start_mech_by_sasl_name (client) failed " ) ;
2011-10-17 11:22:33 +04:00
status = gensec_server_start ( tctx ,
2010-07-16 08:32:42 +04:00
lpcfg_gensec_settings ( tctx , tctx - > lp_ctx ) ,
2011-12-29 04:46:41 +04:00
auth_context , & gensec_server_context ) ;
2010-03-04 12:07:12 +03:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_server_start (server) failed " ) ;
2015-02-26 19:03:44 +03:00
status = gensec_set_credentials ( gensec_server_context , server_creds ) ;
2010-03-04 12:07:12 +03:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_set_credentials (server) failed " ) ;
status = gensec_start_mech_by_sasl_name ( gensec_server_context , " GSSAPI " ) ;
torture_assert_ntstatus_ok ( tctx , status , " gensec_start_mech_by_sasl_name (server) failed " ) ;
server_to_client = data_blob ( NULL , 0 ) ;
do {
/* Do a client-server update dance */
2013-12-13 22:56:13 +04:00
status = gensec_update ( gensec_client_context , tmp_ctx , server_to_client , & client_to_server ) ;
2010-03-04 12:07:12 +03:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_MORE_PROCESSING_REQUIRED ) ) { ;
torture_assert_ntstatus_ok ( tctx , status , " gensec_update (client) failed " ) ;
}
2013-12-13 22:56:13 +04:00
status = gensec_update ( gensec_server_context , tmp_ctx , client_to_server , & server_to_client ) ;
2010-03-04 12:07:12 +03:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_MORE_PROCESSING_REQUIRED ) ) { ;
torture_assert_ntstatus_ok ( tctx , status , " gensec_update (server) failed " ) ;
}
if ( NT_STATUS_IS_OK ( status ) ) {
break ;
}
} while ( 1 ) ;
/* Don't pollute the remaining tests with the changed credentials */
2015-02-26 19:03:44 +03:00
cli_credentials_invalidate_ccache ( server_creds , CRED_SPECIFIED ) ;
cli_credentials_set_target_service ( server_creds , NULL ) ;
cli_credentials_set_impersonate_principal ( server_creds , NULL , NULL ) ;
2010-03-04 12:07:12 +03:00
/* Extract the PAC using Samba's code */
2011-08-01 09:39:01 +04:00
status = gensec_session_info ( gensec_server_context , gensec_server_context , & s2u4self_session_info ) ;
2010-03-04 12:07:12 +03:00
torture_assert_ntstatus_ok ( tctx , status , " gensec_session_info failed " ) ;
2015-02-26 19:03:44 +03:00
cli_credentials_get_ntlm_username_domain ( client_creds , tctx ,
2010-03-04 12:07:12 +03:00
& ninfo . identity_info . account_name . string ,
& ninfo . identity_info . domain_name . string ) ;
/* Now try with SamLogon */
generate_random_buffer ( ninfo . challenge ,
sizeof ( ninfo . challenge ) ) ;
chal = data_blob_const ( ninfo . challenge ,
sizeof ( ninfo . challenge ) ) ;
2015-12-13 00:23:18 +03:00
names_blob = NTLMv2_generate_names_blob ( tctx , cli_credentials_get_workstation ( server_creds ) ,
cli_credentials_get_domain ( server_creds ) ) ;
2010-03-04 12:07:12 +03:00
2015-02-26 19:03:44 +03:00
status = cli_credentials_get_ntlm_response ( client_creds , tctx ,
2010-03-04 12:07:12 +03:00
& flags ,
chal ,
2015-11-20 11:29:11 +03:00
NULL , /* server_timestamp */
2010-03-04 12:07:12 +03:00
names_blob ,
& lm_resp , & nt_resp ,
NULL , NULL ) ;
torture_assert_ntstatus_ok ( tctx , status , " cli_credentials_get_ntlm_response failed " ) ;
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 ;
2015-02-26 19:03:44 +03:00
ninfo . identity_info . workstation . string = cli_credentials_get_workstation ( server_creds ) ;
2010-03-04 12:07:12 +03:00
logon . network = & ninfo ;
r . in . server_name = talloc_asprintf ( tctx , " \\ \\ %s " , dcerpc_server_name ( p ) ) ;
2015-02-26 19:03:44 +03:00
r . in . computer_name = cli_credentials_get_workstation ( server_creds ) ;
2010-03-04 12:07:12 +03:00
r . in . credential = & auth ;
r . in . return_authenticator = & auth2 ;
2012-12-05 19:11:19 +04:00
r . in . logon_level = NetlogonNetworkInformation ;
2010-03-04 12:07:12 +03:00
r . in . logon = & logon ;
r . out . validation = & validation ;
r . out . authoritative = & authoritative ;
ZERO_STRUCT ( auth2 ) ;
netlogon_creds_client_authenticator ( creds , & auth ) ;
r . in . validation_level = 3 ;
2010-06-17 01:11:05 +04:00
status = dcerpc_netr_LogonSamLogon_r ( b , tctx , & r ) ;
2010-03-04 12:07:12 +03:00
torture_assert_ntstatus_ok ( tctx , status , " LogonSamLogon failed " ) ;
torture_assert ( tctx , netlogon_creds_client_check ( creds ,
& r . out . return_authenticator - > cred ) ,
" Credential chaining failed " ) ;
2014-12-16 08:07:44 +03:00
torture_assert_ntstatus_ok ( tctx , r . out . result , " LogonSamLogon failed " ) ;
2010-03-04 12:07:12 +03:00
2011-02-08 08:53:13 +03:00
status = make_user_info_dc_netlogon_validation ( tmp_ctx ,
2010-03-04 12:07:12 +03:00
ninfo . identity_info . account_name . string ,
r . in . validation_level ,
r . out . validation ,
2011-07-18 07:55:20 +04:00
true , /* This user was authenticated */
2011-02-08 08:53:13 +03:00
& netlogon_user_info_dc ) ;
2010-03-04 12:07:12 +03:00
2011-02-08 08:53:13 +03:00
torture_assert_ntstatus_ok ( tctx , status , " make_user_info_dc_netlogon_validation failed " ) ;
2010-03-04 12:07:12 +03:00
2011-02-08 08:53:13 +03:00
torture_assert_str_equal ( tctx , netlogon_user_info_dc - > info - > account_name = = NULL ? " " : netlogon_user_info_dc - > info - > account_name ,
kinit_session_info - > info - > account_name , " Account name differs for kinit-based PAC " ) ;
torture_assert_str_equal ( tctx , netlogon_user_info_dc - > info - > account_name = = NULL ? " " : netlogon_user_info_dc - > info - > account_name ,
s2u4self_session_info - > info - > account_name , " Account name differs for S2U4Self " ) ;
torture_assert_str_equal ( tctx , netlogon_user_info_dc - > info - > full_name = = NULL ? " " : netlogon_user_info_dc - > info - > full_name , kinit_session_info - > info - > full_name , " Full name differs for kinit-based PAC " ) ;
torture_assert_str_equal ( tctx , netlogon_user_info_dc - > info - > full_name = = NULL ? " " : netlogon_user_info_dc - > info - > full_name , s2u4self_session_info - > info - > full_name , " Full name differs for S2U4Self " ) ;
torture_assert_int_equal ( tctx , netlogon_user_info_dc - > num_sids , kinit_session_info - > torture - > num_dc_sids , " Different numbers of domain groups for kinit-based PAC " ) ;
torture_assert_int_equal ( tctx , netlogon_user_info_dc - > num_sids , s2u4self_session_info - > torture - > num_dc_sids , " Different numbers of domain groups for S2U4Self " ) ;
2010-03-04 12:07:12 +03:00
builtin_domain = dom_sid_parse_talloc ( tmp_ctx , SID_BUILTIN ) ;
2011-02-08 08:53:13 +03:00
for ( i = 0 ; i < kinit_session_info - > torture - > num_dc_sids ; i + + ) {
torture_assert ( tctx , dom_sid_equal ( & netlogon_user_info_dc - > sids [ i ] , & kinit_session_info - > torture - > dc_sids [ i ] ) , " Different domain groups for kinit-based PAC " ) ;
torture_assert ( tctx , dom_sid_equal ( & netlogon_user_info_dc - > sids [ i ] , & s2u4self_session_info - > torture - > dc_sids [ i ] ) , " Different domain groups for S2U4Self " ) ;
torture_assert ( tctx , ! dom_sid_in_domain ( builtin_domain , & s2u4self_session_info - > torture - > dc_sids [ i ] ) , " Returned BUILTIN domain in groups for S2U4Self " ) ;
torture_assert ( tctx , ! dom_sid_in_domain ( builtin_domain , & kinit_session_info - > torture - > dc_sids [ i ] ) , " Returned BUILTIN domain in groups kinit-based PAC " ) ;
torture_assert ( tctx , ! dom_sid_in_domain ( builtin_domain , & netlogon_user_info_dc - > sids [ i ] ) , " Returned BUILTIN domian in groups from NETLOGON SamLogon reply " ) ;
2010-03-04 12:07:12 +03:00
}
2008-08-27 15:36:27 +04:00
return true ;
}
2012-12-07 15:51:10 +04:00
static bool test_S2U4Self_bdc_arcfour ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct cli_credentials * credentials )
2010-03-04 12:07:12 +03:00
{
2012-12-07 15:51:10 +04:00
return test_S2U4Self ( tctx , p , credentials , SEC_CHAN_BDC ,
TEST_MACHINE_NAME_S2U4SELF_BDC ,
NETLOGON_NEG_AUTH2_ADS_FLAGS ) ;
2010-03-04 12:07:12 +03:00
}
2012-12-07 15:51:10 +04:00
static bool test_S2U4Self_bdc_aes ( struct torture_context * tctx ,
2010-03-04 12:07:12 +03:00
struct dcerpc_pipe * p ,
struct cli_credentials * credentials )
{
2012-12-07 15:51:10 +04:00
return test_S2U4Self ( tctx , p , credentials , SEC_CHAN_BDC ,
TEST_MACHINE_NAME_S2U4SELF_BDC ,
NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES ) ;
}
static bool test_S2U4Self_workstation_arcfour ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct cli_credentials * credentials )
{
return test_S2U4Self ( tctx , p , credentials , SEC_CHAN_WKSTA ,
TEST_MACHINE_NAME_S2U4SELF_WKSTA ,
NETLOGON_NEG_AUTH2_ADS_FLAGS ) ;
}
static bool test_S2U4Self_workstation_aes ( struct torture_context * tctx ,
struct dcerpc_pipe * p ,
struct cli_credentials * credentials )
{
return test_S2U4Self ( tctx , p , credentials , SEC_CHAN_WKSTA ,
TEST_MACHINE_NAME_S2U4SELF_WKSTA ,
NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES ) ;
2010-03-04 12:07:12 +03:00
}
2015-02-07 14:48:54 +03:00
# endif
2010-03-04 12:07:12 +03:00
2008-08-27 15:36:27 +04:00
struct torture_suite * torture_rpc_remote_pac ( TALLOC_CTX * mem_ctx )
{
2010-12-11 05:26:31 +03:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " pac " ) ;
2008-08-27 15:36:27 +04:00
struct torture_rpc_tcase * tcase ;
2012-12-05 19:23:34 +04:00
tcase = torture_suite_add_machine_bdc_rpc_iface_tcase ( suite , " netr-bdc-arcfour " ,
2010-03-04 12:07:12 +03:00
& ndr_table_netlogon , TEST_MACHINE_NAME_BDC ) ;
2012-12-05 19:23:34 +04:00
torture_rpc_tcase_add_test_creds ( tcase , " verify-sig-arcfour " , test_PACVerify_bdc_arcfour ) ;
2010-03-04 12:07:12 +03:00
2012-12-05 19:23:34 +04:00
tcase = torture_suite_add_machine_bdc_rpc_iface_tcase ( suite , " netr-bdc-aes " ,
& ndr_table_netlogon , TEST_MACHINE_NAME_BDC ) ;
torture_rpc_tcase_add_test_creds ( tcase , " verify-sig-aes " , test_PACVerify_bdc_aes ) ;
tcase = torture_suite_add_machine_workstation_rpc_iface_tcase ( suite , " netr-mem-arcfour " ,
& ndr_table_netlogon , TEST_MACHINE_NAME_WKSTA ) ;
torture_rpc_tcase_add_test_creds ( tcase , " verify-sig-arcfour " , test_PACVerify_workstation_arcfour ) ;
tcase = torture_suite_add_machine_workstation_rpc_iface_tcase ( suite , " netr-mem-aes " ,
2010-03-04 12:07:12 +03:00
& ndr_table_netlogon , TEST_MACHINE_NAME_WKSTA ) ;
2012-12-05 19:23:34 +04:00
torture_rpc_tcase_add_test_creds ( tcase , " verify-sig-aes " , test_PACVerify_workstation_aes ) ;
2010-03-04 12:07:12 +03:00
2010-11-02 09:14:55 +03:00
tcase = torture_suite_add_machine_workstation_rpc_iface_tcase ( suite , " netlogon-member-des " ,
& ndr_table_netlogon , TEST_MACHINE_NAME_WKSTA_DES ) ;
torture_rpc_tcase_add_test_join ( tcase , " verify-sig " , test_PACVerify_workstation_des ) ;
2015-02-07 14:48:54 +03:00
# ifdef SAMBA4_USES_HEIMDAL
2012-12-07 15:51:10 +04:00
tcase = torture_suite_add_machine_bdc_rpc_iface_tcase ( suite , " netr-bdc-arcfour " ,
& ndr_table_netlogon , TEST_MACHINE_NAME_S2U4SELF_BDC ) ;
torture_rpc_tcase_add_test_creds ( tcase , " s2u4self-arcfour " , test_S2U4Self_bdc_arcfour ) ;
tcase = torture_suite_add_machine_bdc_rpc_iface_tcase ( suite , " netr-bcd-aes " ,
2010-03-04 12:07:12 +03:00
& ndr_table_netlogon , TEST_MACHINE_NAME_S2U4SELF_BDC ) ;
2012-12-07 15:51:10 +04:00
torture_rpc_tcase_add_test_creds ( tcase , " s2u4self-aes " , test_S2U4Self_bdc_aes ) ;
2010-03-04 12:07:12 +03:00
2012-12-07 15:51:10 +04:00
tcase = torture_suite_add_machine_workstation_rpc_iface_tcase ( suite , " netr-mem-arcfour " ,
& ndr_table_netlogon , TEST_MACHINE_NAME_S2U4SELF_WKSTA ) ;
torture_rpc_tcase_add_test_creds ( tcase , " s2u4self-arcfour " , test_S2U4Self_workstation_arcfour ) ;
tcase = torture_suite_add_machine_workstation_rpc_iface_tcase ( suite , " netr-mem-aes " ,
2010-03-04 12:07:12 +03:00
& ndr_table_netlogon , TEST_MACHINE_NAME_S2U4SELF_WKSTA ) ;
2012-12-07 15:51:10 +04:00
torture_rpc_tcase_add_test_creds ( tcase , " s2u4self-aes " , test_S2U4Self_workstation_aes ) ;
2015-02-07 14:48:54 +03:00
# endif
2008-08-27 15:36:27 +04:00
return suite ;
}