2006-07-11 22:01:26 +04:00
/*
Unix SMB / CIFS implementation .
passdb testing utility
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
Copyright ( C ) Wilco Baan Hofman 2006
Copyright ( C ) Jelmer Vernooij 2006
2012-08-08 09:22:03 +04:00
Copyright ( C ) Andrew Bartlett 2012
2006-07-11 22:01:26 +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-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-07-11 22:01:26 +04:00
( at your option ) any later version .
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +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-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-07-11 22:01:26 +04:00
*/
# include "includes.h"
2021-01-12 14:53:08 +03:00
# include "lib/cmdline/cmdline.h"
2011-03-18 20:58:37 +03:00
# include "passdb.h"
2006-07-11 22:01:26 +04:00
2011-05-31 17:32:29 +04:00
# include "../librpc/gen_ndr/drsblobs.h"
# include "../librpc/gen_ndr/ndr_drsblobs.h"
# include "../libcli/security/dom_sid.h"
2012-08-08 09:22:03 +04:00
# include "../libcli/auth/libcli_auth.h"
# include "../auth/common_auth.h"
# include "lib/tsocket/tsocket.h"
# include "include/auth.h"
2017-12-07 15:03:55 +03:00
# include "nsswitch/libwbclient/wbclient.h"
# include "auth/auth_sam_reply.h"
2011-05-31 17:32:29 +04:00
# define TRUST_DOM "trustdom"
# define TRUST_PWD "trustpwd1232"
# define TRUST_SID "S-1-5-21-1111111111-2222222222-3333333333"
2007-10-19 04:40:25 +04:00
static bool samu_correct ( struct samu * s1 , struct samu * s2 )
2006-07-11 22:01:26 +04:00
{
2007-10-19 04:40:25 +04:00
bool ret = True ;
2015-05-09 06:10:12 +03:00
uint32_t s1_len , s2_len ;
2006-07-11 22:01:26 +04:00
const char * s1_buf , * s2_buf ;
2015-05-09 06:10:12 +03:00
const uint8_t * d1_buf , * d2_buf ;
2012-08-08 09:22:03 +04:00
const struct dom_sid * s1_sid , * s2_sid ;
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
/* Check Unix username */
s1_buf = pdb_get_username ( s1 ) ;
s2_buf = pdb_get_username ( s2 ) ;
if ( s2_buf = = NULL & & s1_buf ! = NULL ) {
DEBUG ( 0 , ( " Username is not set \n " ) ) ;
ret = False ;
} else if ( s1_buf = = NULL ) {
/* Do nothing */
} else if ( strcmp ( s1_buf , s2_buf ) ) {
DEBUG ( 0 , ( " Username not written correctly, want %s, got \" %s \" \n " ,
pdb_get_username ( s1 ) ,
pdb_get_username ( s2 ) ) ) ;
ret = False ;
}
/* Check NT username */
s1_buf = pdb_get_nt_username ( s1 ) ;
s2_buf = pdb_get_nt_username ( s2 ) ;
if ( s2_buf = = NULL & & s1_buf ! = NULL ) {
DEBUG ( 0 , ( " NT Username is not set \n " ) ) ;
ret = False ;
} else if ( s1_buf = = NULL ) {
/* Do nothing */
} else if ( strcmp ( s1_buf , s2_buf ) ) {
DEBUG ( 0 , ( " NT Username not written correctly, want \" %s \" , got \" %s \" \n " ,
pdb_get_nt_username ( s1 ) ,
pdb_get_nt_username ( s2 ) ) ) ;
ret = False ;
}
/* Check acct ctrl */
if ( pdb_get_acct_ctrl ( s1 ) ! = pdb_get_acct_ctrl ( s2 ) ) {
DEBUG ( 0 , ( " Acct ctrl field not written correctly, want %d (0x%X), got %d (0x%X) \n " ,
pdb_get_acct_ctrl ( s1 ) ,
pdb_get_acct_ctrl ( s1 ) ,
pdb_get_acct_ctrl ( s2 ) ,
pdb_get_acct_ctrl ( s2 ) ) ) ;
ret = False ;
}
/* Check NT password */
d1_buf = pdb_get_nt_passwd ( s1 ) ;
d2_buf = pdb_get_nt_passwd ( s2 ) ;
if ( d2_buf = = NULL & & d1_buf ! = NULL ) {
DEBUG ( 0 , ( " NT password is not set \n " ) ) ;
ret = False ;
} else if ( d1_buf = = NULL ) {
/* Do nothing */
} else if ( memcmp ( d1_buf , d2_buf , NT_HASH_LEN ) ) {
DEBUG ( 0 , ( " NT password not written correctly \n " ) ) ;
ret = False ;
}
/* Check lanman password */
d1_buf = pdb_get_lanman_passwd ( s1 ) ;
d2_buf = pdb_get_lanman_passwd ( s2 ) ;
if ( d2_buf = = NULL & & d1_buf ! = NULL ) {
DEBUG ( 0 , ( " Lanman password is not set \n " ) ) ;
} else if ( d1_buf = = NULL ) {
/* Do nothing */
} else if ( memcmp ( d1_buf , d2_buf , NT_HASH_LEN ) ) {
DEBUG ( 0 , ( " Lanman password not written correctly \n " ) ) ;
ret = False ;
}
/* Check password history */
d1_buf = pdb_get_pw_history ( s1 , & s1_len ) ;
d2_buf = pdb_get_pw_history ( s2 , & s2_len ) ;
if ( d2_buf = = NULL & & d1_buf ! = NULL ) {
DEBUG ( 0 , ( " Password history is not set \n " ) ) ;
} else if ( d1_buf = = NULL ) {
/* Do nothing */
2013-12-26 08:28:58 +04:00
} else if ( s1_len ! = s2_len ) {
2006-07-11 22:01:26 +04:00
DEBUG ( 0 , ( " Password history not written correctly, lengths differ, want %d, got %d \n " ,
s1_len , s2_len ) ) ;
ret = False ;
} else if ( strncmp ( s1_buf , s2_buf , s1_len ) ) {
DEBUG ( 0 , ( " Password history not written correctly \n " ) ) ;
ret = False ;
}
/* Check logon time */
if ( pdb_get_logon_time ( s1 ) ! = pdb_get_logon_time ( s2 ) ) {
DEBUG ( 0 , ( " Logon time is not written correctly \n " ) ) ;
ret = False ;
}
/* Check logoff time */
if ( pdb_get_logoff_time ( s1 ) ! = pdb_get_logoff_time ( s2 ) ) {
2012-06-27 03:04:46 +04:00
DEBUG ( 0 , ( " Logoff time is not written correctly: %s vs %s \n " ,
http_timestring ( talloc_tos ( ) , pdb_get_logoff_time ( s1 ) ) ,
http_timestring ( talloc_tos ( ) , pdb_get_logoff_time ( s2 ) ) ) ) ;
2006-07-11 22:01:26 +04:00
ret = False ;
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
/* Check kickoff time */
2012-06-26 15:06:25 +04:00
if ( pdb_get_kickoff_time ( s1 ) ! = pdb_get_kickoff_time ( s2 ) ) {
2012-06-27 03:04:46 +04:00
DEBUG ( 0 , ( " Kickoff time is not written correctly: %s vs %s \n " ,
http_timestring ( talloc_tos ( ) , pdb_get_kickoff_time ( s1 ) ) ,
http_timestring ( talloc_tos ( ) , pdb_get_kickoff_time ( s2 ) ) ) ) ;
2006-07-11 22:01:26 +04:00
ret = False ;
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
/* Check bad password time */
if ( pdb_get_bad_password_time ( s1 ) ! = pdb_get_bad_password_time ( s2 ) ) {
DEBUG ( 0 , ( " Bad password time is not written correctly \n " ) ) ;
ret = False ;
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
/* Check password last set time */
if ( pdb_get_pass_last_set_time ( s1 ) ! = pdb_get_pass_last_set_time ( s2 ) ) {
2012-06-27 03:04:46 +04:00
DEBUG ( 0 , ( " Password last set time is not written correctly: %s vs %s \n " ,
http_timestring ( talloc_tos ( ) , pdb_get_pass_last_set_time ( s1 ) ) ,
http_timestring ( talloc_tos ( ) , pdb_get_pass_last_set_time ( s2 ) ) ) ) ;
2006-07-11 22:01:26 +04:00
ret = False ;
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
/* Check password can change time */
if ( pdb_get_pass_can_change_time ( s1 ) ! = pdb_get_pass_can_change_time ( s2 ) ) {
2012-06-27 03:04:46 +04:00
DEBUG ( 0 , ( " Password can change time is not written correctly %s vs %s \n " ,
http_timestring ( talloc_tos ( ) , pdb_get_pass_can_change_time ( s1 ) ) ,
http_timestring ( talloc_tos ( ) , pdb_get_pass_can_change_time ( s2 ) ) ) ) ;
2006-07-11 22:01:26 +04:00
ret = False ;
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
/* Check password must change time */
if ( pdb_get_pass_must_change_time ( s1 ) ! = pdb_get_pass_must_change_time ( s2 ) ) {
DEBUG ( 0 , ( " Password must change time is not written correctly \n " ) ) ;
ret = False ;
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
/* Check logon divs */
if ( pdb_get_logon_divs ( s1 ) ! = pdb_get_logon_divs ( s2 ) ) {
DEBUG ( 0 , ( " Logon divs not written correctly \n " ) ) ;
ret = False ;
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
/* Check logon hours */
if ( pdb_get_hours_len ( s1 ) ! = pdb_get_hours_len ( s2 ) ) {
DEBUG ( 0 , ( " Logon hours length not written correctly \n " ) ) ;
ret = False ;
} else if ( pdb_get_hours_len ( s1 ) ! = 0 ) {
d1_buf = pdb_get_hours ( s1 ) ;
d2_buf = pdb_get_hours ( s2 ) ;
2021-12-09 08:06:15 +03:00
if ( d2_buf = = NULL & & d1_buf ! = NULL ) {
2006-07-11 22:01:26 +04:00
DEBUG ( 0 , ( " Logon hours is not set \n " ) ) ;
ret = False ;
} else if ( d1_buf = = NULL ) {
/* Do nothing */
} else if ( memcmp ( d1_buf , d2_buf , MAX_HOURS_LEN ) ) {
DEBUG ( 0 , ( " Logon hours is not written correctly \n " ) ) ;
ret = False ;
}
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
/* Check profile path */
s1_buf = pdb_get_profile_path ( s1 ) ;
s2_buf = pdb_get_profile_path ( s2 ) ;
if ( s2_buf = = NULL & & s1_buf ! = NULL ) {
DEBUG ( 0 , ( " Profile path is not set \n " ) ) ;
ret = False ;
} else if ( s1_buf = = NULL ) {
/* Do nothing */
} else if ( strcmp ( s1_buf , s2_buf ) ) {
DEBUG ( 0 , ( " Profile path is not written correctly \n " ) ) ;
ret = False ;
}
/* Check home dir */
s1_buf = pdb_get_homedir ( s1 ) ;
s2_buf = pdb_get_homedir ( s2 ) ;
if ( s2_buf = = NULL & & s1_buf ! = NULL ) {
DEBUG ( 0 , ( " Home dir is not set \n " ) ) ;
ret = False ;
} else if ( s1_buf = = NULL ) {
/* Do nothing */
} else if ( strcmp ( s1_buf , s2_buf ) ) {
DEBUG ( 0 , ( " Home dir is not written correctly \n " ) ) ;
ret = False ;
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
/* Check logon script */
s1_buf = pdb_get_logon_script ( s1 ) ;
s2_buf = pdb_get_logon_script ( s2 ) ;
if ( s2_buf = = NULL & & s1_buf ! = NULL ) {
DEBUG ( 0 , ( " Logon script not set \n " ) ) ;
ret = False ;
} else if ( s1_buf = = NULL ) {
/* Do nothing */
} else if ( strcmp ( s1_buf , s2_buf ) ) {
DEBUG ( 0 , ( " Logon script is not written correctly \n " ) ) ;
ret = False ;
}
2011-08-05 17:38:33 +04:00
2012-08-08 09:22:03 +04:00
/* Check user and group sids */
s1_sid = pdb_get_user_sid ( s1 ) ;
s2_sid = pdb_get_user_sid ( s2 ) ;
if ( s2_sid = = NULL & & s1_sid ! = NULL ) {
DEBUG ( 0 , ( " USER SID not set \n " ) ) ;
ret = False ;
} else if ( s1_sid = = NULL ) {
/* Do nothing */
} else if ( ! dom_sid_equal ( s1_sid , s2_sid ) ) {
DEBUG ( 0 , ( " USER SID is not written correctly \n " ) ) ;
ret = False ;
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
return ret ;
}
2012-08-08 09:22:03 +04:00
static bool test_auth ( TALLOC_CTX * mem_ctx , struct samu * pdb_entry )
{
struct auth_usersupplied_info * user_info ;
struct auth_context * auth_context ;
static const uint8_t challenge_8 [ 8 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 } ;
DATA_BLOB challenge = data_blob_const ( challenge_8 , sizeof ( challenge_8 ) ) ;
2017-02-24 03:29:12 +03:00
struct tsocket_address * remote_address ;
struct tsocket_address * local_address ;
2012-08-08 09:22:03 +04:00
unsigned char local_nt_response [ 24 ] ;
DATA_BLOB nt_resp = data_blob_const ( local_nt_response , sizeof ( local_nt_response ) ) ;
unsigned char local_nt_session_key [ 16 ] ;
struct netr_SamInfo3 * info3_sam , * info3_auth ;
struct auth_serversupplied_info * server_info ;
2017-12-07 15:03:55 +03:00
struct wbcAuthUserParams params = { . flags = 0 } ;
struct wbcAuthUserInfo * info = NULL ;
struct wbcAuthErrorInfo * err = NULL ;
wbcErr wbc_status ;
struct netr_SamInfo6 * info6_wbc = NULL ;
2012-08-08 09:22:03 +04:00
NTSTATUS status ;
2017-03-13 10:19:41 +03:00
bool ok ;
2021-10-26 18:42:41 +03:00
uint8_t authoritative = 1 ;
2019-11-08 17:40:01 +03:00
int rc ;
rc = SMBOWFencrypt ( pdb_get_nt_passwd ( pdb_entry ) , challenge_8 ,
local_nt_response ) ;
if ( rc ! = 0 ) {
return False ;
}
2017-03-17 11:43:59 +03:00
2012-08-08 09:22:03 +04:00
SMBsesskeygen_ntv1 ( pdb_get_nt_passwd ( pdb_entry ) , local_nt_session_key ) ;
2017-02-24 03:29:12 +03:00
if ( tsocket_address_inet_from_strings ( NULL , " ip " , NULL , 0 , & remote_address ) ! = 0 ) {
2012-08-08 09:22:03 +04:00
return False ;
}
2017-02-24 03:29:12 +03:00
if ( tsocket_address_inet_from_strings ( NULL , " ip " , NULL , 0 , & local_address ) ! = 0 ) {
return False ;
}
2014-03-27 00:17:15 +04:00
status = make_user_info ( mem_ctx ,
& user_info , pdb_get_username ( pdb_entry ) , pdb_get_username ( pdb_entry ) ,
2017-02-24 03:29:12 +03:00
pdb_get_domain ( pdb_entry ) , pdb_get_domain ( pdb_entry ) , lp_netbios_name ( ) ,
remote_address , local_address , " pdbtest " ,
2017-02-20 04:52:07 +03:00
NULL , & nt_resp , NULL , NULL , NULL ,
2012-08-08 09:22:03 +04:00
AUTH_PASSWORD_RESPONSE ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " Failed to test authentication with check_sam_security_info3: %s \n " , nt_errstr ( status ) ) ) ;
return False ;
}
status = check_sam_security_info3 ( & challenge , NULL , user_info , & info3_sam ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " Failed to test authentication with check_sam_security_info3: %s \n " , nt_errstr ( status ) ) ) ;
return False ;
}
if ( memcmp ( info3_sam - > base . key . key , local_nt_session_key , 16 ) ! = 0 ) {
DEBUG ( 0 , ( " Returned NT session key is incorrect \n " ) ) ;
return False ;
}
2017-03-17 14:29:26 +03:00
status = make_auth3_context_for_ntlm ( NULL , & auth_context ) ;
2012-08-08 09:22:03 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " Failed to test authentication with check_sam_security_info3: %s \n " , nt_errstr ( status ) ) ) ;
return False ;
}
2017-03-13 10:19:41 +03:00
ok = auth3_context_set_challenge (
auth_context , challenge . data , " fixed " ) ;
if ( ! ok ) {
DBG_ERR ( " auth3_context_set_challenge failed \n " ) ;
return false ;
}
2014-02-18 13:19:57 +04:00
status = auth_check_ntlm_password ( mem_ctx ,
auth_context ,
user_info ,
2017-03-17 11:43:59 +03:00
& server_info ,
& authoritative ) ;
2012-08-08 09:22:03 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2017-03-17 11:43:59 +03:00
DEBUG ( 0 , ( " Failed to test authentication with auth module: "
" %s authoritative[%u]. \n " ,
nt_errstr ( status ) , authoritative ) ) ;
2012-08-08 09:22:03 +04:00
return False ;
}
info3_auth = talloc_zero ( mem_ctx , struct netr_SamInfo3 ) ;
if ( info3_auth = = NULL ) {
return False ;
}
2012-12-06 18:21:02 +04:00
status = serverinfo_to_SamInfo3 ( server_info , info3_auth ) ;
2012-08-08 09:22:03 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " serverinfo_to_SamInfo3 failed: %s \n " ,
nt_errstr ( status ) ) ) ;
return False ;
}
if ( memcmp ( info3_auth - > base . key . key , local_nt_session_key , 16 ) ! = 0 ) {
DEBUG ( 0 , ( " Returned NT session key is incorrect \n " ) ) ;
return False ;
}
if ( ! dom_sid_equal ( info3_sam - > base . domain_sid , info3_auth - > base . domain_sid ) ) {
2019-01-10 23:04:33 +03:00
struct dom_sid_buf buf1 , buf2 ;
2023-07-18 12:35:22 +03:00
DEBUG ( 0 , ( " domain_sid in SAM info3 %s does not match domain_sid in AUTH info3 %s \n " ,
2019-01-10 23:04:33 +03:00
dom_sid_str_buf ( info3_sam - > base . domain_sid , & buf1 ) ,
dom_sid_str_buf ( info3_auth - > base . domain_sid ,
& buf2 ) ) ) ;
2012-08-08 09:22:03 +04:00
return False ;
}
2023-07-18 12:35:22 +03:00
/* TODO:
* Compare more details from the two info3 structures ,
2012-08-08 09:22:03 +04:00
* then test that an expired / disabled / pwdmustchange account
* returns the correct errors
*/
2017-12-07 15:03:55 +03:00
params . parameter_control = user_info - > logon_parameters ;
params . parameter_control | = WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT |
WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT ;
params . level = WBC_AUTH_USER_LEVEL_RESPONSE ;
params . account_name = user_info - > client . account_name ;
params . domain_name = user_info - > client . domain_name ;
params . workstation_name = user_info - > workstation_name ;
memcpy ( params . password . response . challenge ,
challenge . data ,
sizeof ( params . password . response . challenge ) ) ;
params . password . response . lm_length =
user_info - > password . response . lanman . length ;
params . password . response . nt_length =
user_info - > password . response . nt . length ;
params . password . response . lm_data =
user_info - > password . response . lanman . data ;
params . password . response . nt_data =
user_info - > password . response . nt . data ;
wbc_status = wbcAuthenticateUserEx ( & params , & info , & err ) ;
if ( wbc_status ! = WBC_ERR_WINBIND_NOT_AVAILABLE ) {
if ( wbc_status = = WBC_ERR_AUTH_ERROR ) {
if ( err ) {
DEBUG ( 1 , ( " error was %s (0x%08x) \n error message was '%s' \n " ,
err - > nt_string , err - > nt_status , err - > display_string ) ) ;
status = NT_STATUS ( err - > nt_status ) ;
wbcFreeMemory ( err ) ;
} else {
status = NT_STATUS_LOGON_FAILURE ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
return false ;
}
} else if ( ! WBC_ERROR_IS_OK ( wbc_status ) ) {
DEBUG ( 1 , ( " wbcAuthenticateUserEx: failed with %u - %s \n " ,
wbc_status , wbcErrorString ( wbc_status ) ) ) ;
if ( err ) {
DEBUG ( 1 , ( " error was %s (0x%08x) \n error message was '%s' \n " ,
err - > nt_string , err - > nt_status , err - > display_string ) ) ;
}
return false ;
}
info6_wbc = wbcAuthUserInfo_to_netr_SamInfo6 ( mem_ctx , info ) ;
wbcFreeMemory ( info ) ;
if ( ! info6_wbc ) {
DEBUG ( 1 , ( " wbcAuthUserInfo_to_netr_SamInfo6 failed \n " ) ) ;
return false ;
}
if ( memcmp ( info6_wbc - > base . key . key , local_nt_session_key , 16 ) ! = 0 ) {
DEBUG ( 0 , ( " Returned NT session key is incorrect \n " ) ) ;
return false ;
}
if ( ! dom_sid_equal ( info3_sam - > base . domain_sid , info6_wbc - > base . domain_sid ) ) {
2019-01-10 23:04:33 +03:00
struct dom_sid_buf buf1 , buf2 ;
2017-12-07 15:03:55 +03:00
DEBUG ( 0 , ( " domain_sid in SAM info3 %s does not match domain_sid in AUTH info3 %s \n " ,
2019-01-10 23:04:33 +03:00
dom_sid_str_buf ( info3_sam - > base . domain_sid ,
& buf1 ) ,
dom_sid_str_buf ( info6_wbc - > base . domain_sid ,
& buf2 ) ) ) ;
2017-12-07 15:03:55 +03:00
return false ;
}
}
2012-08-08 09:22:03 +04:00
return True ;
}
2012-01-06 20:27:03 +04:00
static bool test_trusted_domains ( TALLOC_CTX * ctx ,
struct pdb_methods * pdb ,
bool * error )
{
NTSTATUS rv ;
/* test trustdom calls */
struct pdb_trusted_domain * td ;
struct pdb_trusted_domain * new_td ;
struct trustAuthInOutBlob taiob ;
struct AuthenticationInformation aia ;
enum ndr_err_code ndr_err ;
2017-12-11 09:56:02 +03:00
bool ok ;
2012-01-06 20:27:03 +04:00
td = talloc_zero ( ctx , struct pdb_trusted_domain ) ;
if ( ! td ) {
fprintf ( stderr , " talloc failed \n " ) ;
return false ;
}
td - > domain_name = talloc_strdup ( td , TRUST_DOM ) ;
td - > netbios_name = talloc_strdup ( td , TRUST_DOM ) ;
if ( ! td - > domain_name | | ! td - > netbios_name ) {
fprintf ( stderr , " talloc failed \n " ) ;
return false ;
}
2017-12-11 09:56:02 +03:00
ok = dom_sid_parse ( " S-1-5-21-123-456-789 " , & td - > security_identifier ) ;
if ( ! ok ) {
fprintf ( stderr , " dom_sid_parse S-1-5-21-123-456-789 failed \n " ) ;
return false ;
}
2012-01-06 20:27:03 +04:00
td - > trust_auth_incoming = data_blob_null ;
ZERO_STRUCT ( taiob ) ;
ZERO_STRUCT ( aia ) ;
taiob . count = 1 ;
taiob . current . count = 1 ;
taiob . current . array = & aia ;
unix_to_nt_time ( & aia . LastUpdateTime , time ( NULL ) ) ;
aia . AuthType = TRUST_AUTH_TYPE_CLEAR ;
aia . AuthInfo . clear . password = ( uint8_t * ) talloc_strdup ( ctx , TRUST_PWD ) ;
aia . AuthInfo . clear . size = strlen ( TRUST_PWD ) ;
taiob . previous . count = 0 ;
taiob . previous . array = NULL ;
ndr_err = ndr_push_struct_blob ( & td - > trust_auth_outgoing ,
td , & taiob ,
( ndr_push_flags_fn_t ) ndr_push_trustAuthInOutBlob ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
fprintf ( stderr , " ndr_push_struct_blob failed. \n " ) ;
return false ;
}
td - > trust_direction = LSA_TRUST_DIRECTION_OUTBOUND ;
td - > trust_type = LSA_TRUST_TYPE_DOWNLEVEL ;
td - > trust_attributes = 0 ;
td - > trust_forest_trust_info = data_blob_null ;
rv = pdb - > set_trusted_domain ( pdb , TRUST_DOM , td ) ;
if ( ! NT_STATUS_IS_OK ( rv ) ) {
fprintf ( stderr , " Error in set_trusted_domain %s \n " ,
get_friendly_nt_error_msg ( rv ) ) ;
* error = true ;
}
rv = pdb - > get_trusted_domain ( pdb , ctx , TRUST_DOM , & new_td ) ;
if ( ! NT_STATUS_IS_OK ( rv ) ) {
2017-12-09 21:27:22 +03:00
fprintf ( stderr , " Error in get_trusted_domain %s \n " ,
2012-01-06 20:27:03 +04:00
get_friendly_nt_error_msg ( rv ) ) ;
* error = true ;
}
if ( ! strequal ( td - > domain_name , new_td - > domain_name ) | |
! strequal ( td - > netbios_name , new_td - > netbios_name ) | |
! dom_sid_equal ( & td - > security_identifier ,
& new_td - > security_identifier ) | |
td - > trust_direction ! = new_td - > trust_direction | |
td - > trust_type ! = new_td - > trust_type | |
td - > trust_attributes ! = new_td - > trust_attributes | |
td - > trust_auth_incoming . length ! = new_td - > trust_auth_incoming . length | |
td - > trust_forest_trust_info . length ! = new_td - > trust_forest_trust_info . length | |
data_blob_cmp ( & td - > trust_auth_outgoing , & new_td - > trust_auth_outgoing ) ! = 0 ) {
fprintf ( stderr , " Old and new trusdet domain data do not match \n " ) ;
* error = true ;
}
2017-12-11 09:56:40 +03:00
rv = pdb - > del_trusted_domain ( pdb , TRUST_DOM ) ;
if ( ! NT_STATUS_IS_OK ( rv ) ) {
fprintf ( stderr , " Error in del_trusted_domain %s \n " ,
get_friendly_nt_error_msg ( rv ) ) ;
* error = true ;
}
2012-01-06 20:27:03 +04:00
return true ;
}
2006-07-11 22:01:26 +04:00
2014-02-26 23:16:26 +04:00
int main ( int argc , const char * * argv )
2006-07-11 22:01:26 +04:00
{
TALLOC_CTX * ctx ;
struct samu * out = NULL ;
struct samu * in = NULL ;
NTSTATUS rv ;
int i ;
2021-09-10 08:03:21 +03:00
int opt ;
2006-07-11 22:01:26 +04:00
struct timeval tv ;
2007-10-19 04:40:25 +04:00
bool error = False ;
2006-07-11 22:01:26 +04:00
struct passwd * pwd ;
2015-05-09 06:10:12 +03:00
uint8_t * buf ;
uint32_t expire , min_age , history ;
2006-07-11 22:01:26 +04:00
struct pdb_methods * pdb ;
poptContext pc ;
2007-03-26 20:40:29 +04:00
static const char * backend = NULL ;
2006-07-11 22:01:26 +04:00
static const char * unix_user = " nobody " ;
2021-01-12 14:53:08 +03:00
bool ok ;
2006-07-11 22:01:26 +04:00
struct poptOption long_options [ ] = {
{ " username " , ' u ' , POPT_ARG_STRING , & unix_user , 0 , " Unix user to use for testing " , " USERNAME " } ,
{ " backend " , ' b ' , POPT_ARG_STRING , & backend , 0 , " Backend to use if not default " , " BACKEND[:SETTINGS] " } ,
POPT_AUTOHELP
POPT_COMMON_SAMBA
2021-01-12 14:53:08 +03:00
POPT_COMMON_VERSION
2006-07-11 22:01:26 +04:00
POPT_TABLEEND
} ;
2012-07-18 09:37:28 +04:00
ctx = talloc_stackframe ( ) ;
2015-03-21 22:00:06 +03:00
smb_init_locale ( ) ;
2006-07-11 22:01:26 +04:00
2021-01-12 14:53:08 +03:00
ok = samba_cmdline_init ( ctx ,
SAMBA_CMDLINE_CONFIG_CLIENT ,
true /* require_smbconf */ ) ;
if ( ! ok ) {
TALLOC_FREE ( ctx ) ;
exit ( 1 ) ;
}
pc = samba_popt_get_context ( getprogname ( ) , argc , argv , long_options , 0 ) ;
if ( pc = = NULL ) {
TALLOC_FREE ( ctx ) ;
exit ( 1 ) ;
}
2006-07-11 22:01:26 +04:00
poptSetOtherOptionHelp ( pc , " backend[:settings] username " ) ;
2011-08-05 17:38:33 +04:00
2021-09-10 08:03:21 +03:00
while ( ( opt = poptGetNextOpt ( pc ) ) ! = - 1 ) {
switch ( opt ) {
case POPT_ERROR_BADOPT :
fprintf ( stderr , " \n Invalid option %s: %s \n \n " ,
poptBadOption ( pc , 0 ) , poptStrerror ( opt ) ) ;
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( 1 ) ;
}
}
2006-07-11 22:01:26 +04:00
poptFreeContext ( pc ) ;
if ( backend = = NULL ) {
backend = lp_passdb_backend ( ) ;
}
rv = make_pdb_method_name ( & pdb , backend ) ;
if ( NT_STATUS_IS_ERR ( rv ) ) {
fprintf ( stderr , " Error initializing '%s': %s \n " , backend , get_friendly_nt_error_msg ( rv ) ) ;
exit ( 1 ) ;
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
if ( ! ( out = samu_new ( ctx ) ) ) {
fprintf ( stderr , " Can't create samu structure. \n " ) ;
exit ( 1 ) ;
}
2011-08-05 17:38:33 +04:00
2010-10-20 19:16:23 +04:00
if ( ( pwd = Get_Pwnam_alloc ( ctx , unix_user ) ) = = NULL ) {
2006-07-11 22:01:26 +04:00
fprintf ( stderr , " Error getting user information for %s \n " , unix_user ) ;
exit ( 1 ) ;
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
samu_set_unix ( out , pwd ) ;
pdb_set_profile_path ( out , " \\ \\ torture \\ profile " , PDB_SET ) ;
pdb_set_homedir ( out , " \\ \\ torture \\ home " , PDB_SET ) ;
pdb_set_logon_script ( out , " torture_script.cmd " , PDB_SET ) ;
2012-06-27 08:36:31 +04:00
pdb_set_acct_ctrl ( out , ACB_NORMAL , PDB_SET ) ;
2009-07-14 01:53:49 +04:00
pdb_get_account_policy ( PDB_POLICY_PASSWORD_HISTORY , & history ) ;
2006-07-11 22:01:26 +04:00
if ( history * PW_HISTORY_ENTRY_LEN < NT_HASH_LEN ) {
2015-05-09 06:10:12 +03:00
buf = ( uint8_t * ) TALLOC ( ctx , NT_HASH_LEN ) ;
2006-07-11 22:01:26 +04:00
} else {
2015-05-09 06:10:12 +03:00
buf = ( uint8_t * ) TALLOC ( ctx , history * PW_HISTORY_ENTRY_LEN ) ;
2006-07-11 22:01:26 +04:00
}
/* Generate some random hashes */
GetTimeOfDay ( & tv ) ;
srand ( tv . tv_usec ) ;
for ( i = 0 ; i < NT_HASH_LEN ; i + + ) {
2015-05-09 06:10:12 +03:00
buf [ i ] = ( uint8_t ) rand ( ) ;
2006-07-11 22:01:26 +04:00
}
pdb_set_nt_passwd ( out , buf , PDB_SET ) ;
for ( i = 0 ; i < LM_HASH_LEN ; i + + ) {
2015-05-09 06:10:12 +03:00
buf [ i ] = ( uint8_t ) rand ( ) ;
2006-07-11 22:01:26 +04:00
}
pdb_set_lanman_passwd ( out , buf , PDB_SET ) ;
for ( i = 0 ; i < history * PW_HISTORY_ENTRY_LEN ; i + + ) {
2015-05-09 06:10:12 +03:00
buf [ i ] = ( uint8_t ) rand ( ) ;
2006-07-11 22:01:26 +04:00
}
pdb_set_pw_history ( out , buf , history , PDB_SET ) ;
2009-07-14 01:53:49 +04:00
pdb_get_account_policy ( PDB_POLICY_MAX_PASSWORD_AGE , & expire ) ;
pdb_get_account_policy ( PDB_POLICY_MIN_PASSWORD_AGE , & min_age ) ;
2006-07-11 22:01:26 +04:00
pdb_set_pass_last_set_time ( out , time ( NULL ) , PDB_SET ) ;
2011-08-05 17:38:33 +04:00
2015-05-09 06:10:12 +03:00
if ( min_age = = ( uint32_t ) - 1 ) {
2006-07-11 22:01:26 +04:00
pdb_set_pass_can_change_time ( out , 0 , PDB_SET ) ;
} else {
pdb_set_pass_can_change_time ( out , time ( NULL ) + min_age , PDB_SET ) ;
}
2011-08-05 17:38:33 +04:00
2012-06-27 08:36:31 +04:00
pdb_set_logon_time ( out , time ( NULL ) - 3600 , PDB_SET ) ;
pdb_set_logoff_time ( out , time ( NULL ) , PDB_SET ) ;
pdb_set_kickoff_time ( out , time ( NULL ) + 3600 , PDB_SET ) ;
2006-07-11 22:01:26 +04:00
/* Create account */
if ( ! NT_STATUS_IS_OK ( rv = pdb - > add_sam_account ( pdb , out ) ) ) {
fprintf ( stderr , " Error in add_sam_account: %s \n " ,
get_friendly_nt_error_msg ( rv ) ) ;
exit ( 1 ) ;
}
if ( ! ( in = samu_new ( ctx ) ) ) {
fprintf ( stderr , " Can't create samu structure. \n " ) ;
exit ( 1 ) ;
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
/* Get account information through getsampwnam() */
2012-06-26 14:52:07 +04:00
rv = pdb - > getsampwnam ( pdb , in , out - > username ) ;
if ( NT_STATUS_IS_ERR ( rv ) ) {
fprintf ( stderr , " Error getting sampw of added user %s: %s \n " ,
out - > username , nt_errstr ( rv ) ) ;
2006-07-11 22:01:26 +04:00
if ( ! NT_STATUS_IS_OK ( rv = pdb - > delete_sam_account ( pdb , out ) ) ) {
fprintf ( stderr , " Error in delete_sam_account %s \n " ,
get_friendly_nt_error_msg ( rv ) ) ;
}
TALLOC_FREE ( ctx ) ;
2012-06-26 14:52:07 +04:00
exit ( 1 ) ;
2006-07-11 22:01:26 +04:00
}
2011-08-05 17:38:33 +04:00
2006-07-11 22:01:26 +04:00
/* Verify integrity */
if ( samu_correct ( out , in ) ) {
printf ( " User info written correctly \n " ) ;
} else {
printf ( " User info NOT written correctly \n " ) ;
error = True ;
}
2011-08-05 17:38:33 +04:00
2012-08-08 09:22:03 +04:00
if ( test_auth ( ctx , out ) ) {
printf ( " Authentication module test passed \n " ) ;
} else {
printf ( " Authentication module test failed! \n " ) ;
error = True ;
}
2006-07-11 22:01:26 +04:00
/* Delete account */
if ( ! NT_STATUS_IS_OK ( rv = pdb - > delete_sam_account ( pdb , out ) ) ) {
fprintf ( stderr , " Error in delete_sam_account %s \n " ,
get_friendly_nt_error_msg ( rv ) ) ;
}
2012-01-06 20:27:03 +04:00
if ( pdb_capabilities ( ) & PDB_CAP_TRUSTED_DOMAINS_EX ) {
if ( ! test_trusted_domains ( ctx , pdb , & error ) ) {
fprintf ( stderr , " failed testing trusted domains. \n " ) ;
exit ( 1 ) ;
}
2011-05-31 17:32:29 +04:00
}
2006-07-11 22:01:26 +04:00
TALLOC_FREE ( ctx ) ;
if ( error ) {
return 1 ;
}
return 0 ;
}