2003-07-01 21:51:52 +04:00
/*
2002-01-30 09:08:46 +03:00
* Unix SMB / CIFS implementation .
2003-03-14 20:05:13 +03:00
* Routines to operate on various trust relationships
* Copyright ( C ) Andrew Bartlett 2001
* Copyright ( C ) Rafal Szczesniak 2003
2001-12-05 14:00:26 +03: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 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
/*********************************************************
Change the domain password on the PDC .
Just changes the password betwen the two values specified .
Caller must have the cli connected to the netlogon pipe
already .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
static NTSTATUS just_change_the_password ( struct rpc_pipe_client * cli , TALLOC_CTX * mem_ctx ,
2005-10-18 07:24:00 +04:00
const unsigned char orig_trust_passwd_hash [ 16 ] ,
const unsigned char new_trust_passwd_hash [ 16 ] ,
2003-04-16 14:20:14 +04:00
uint32 sec_channel_type )
2001-12-05 14:00:26 +03:00
{
NTSTATUS result ;
2002-08-30 14:46:59 +04:00
2005-09-30 21:13:37 +04:00
/* Check if the netlogon pipe is open using schannel. If so we
already have valid creds . If not we must set them up . */
if ( cli - > auth . auth_type ! = PIPE_AUTH_TYPE_SCHANNEL ) {
uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS ;
result = rpccli_netlogon_setup_creds ( cli ,
2005-11-04 03:03:55 +03:00
cli - > cli - > desthost , /* server name */
lp_workgroup ( ) , /* domain */
global_myname ( ) , /* client name */
global_myname ( ) , /* machine account name */
2005-09-30 21:13:37 +04:00
orig_trust_passwd_hash ,
sec_channel_type ,
& neg_flags ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
DEBUG ( 3 , ( " just_change_the_password: unable to setup creds (%s)! \n " ,
nt_errstr ( result ) ) ) ;
return result ;
}
2001-12-05 14:00:26 +03:00
}
2005-09-30 21:13:37 +04:00
result = rpccli_net_srv_pwset ( cli , mem_ctx , global_myname ( ) , new_trust_passwd_hash ) ;
2001-12-05 14:00:26 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
DEBUG ( 0 , ( " just_change_the_password: unable to change password (%s)! \n " ,
2002-03-17 07:36:35 +03:00
nt_errstr ( result ) ) ) ;
2001-12-05 14:00:26 +03:00
}
return result ;
}
/*********************************************************
Change the domain password on the PDC .
Store the password ourselves , but use the supplied password
Caller must have already setup the connection to the NETLOGON pipe
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
NTSTATUS trust_pw_change_and_store_it ( struct rpc_pipe_client * cli , TALLOC_CTX * mem_ctx ,
2003-04-16 14:20:14 +04:00
const char * domain ,
unsigned char orig_trust_passwd_hash [ 16 ] ,
uint32 sec_channel_type )
2001-12-05 14:00:26 +03:00
{
unsigned char new_trust_passwd_hash [ 16 ] ;
char * new_trust_passwd ;
char * str ;
NTSTATUS nt_status ;
/* Create a random machine account password */
str = generate_random_str ( DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH ) ;
2006-06-20 00:00:51 +04:00
if ( ( new_trust_passwd = talloc_strdup ( mem_ctx , str ) ) = = NULL ) {
DEBUG ( 0 , ( " talloc_strdup failed \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
2001-12-05 14:00:26 +03:00
2002-06-25 11:58:29 +04:00
E_md4hash ( new_trust_passwd , new_trust_passwd_hash ) ;
2001-12-05 14:00:26 +03:00
nt_status = just_change_the_password ( cli , mem_ctx , orig_trust_passwd_hash ,
2003-04-16 14:20:14 +04:00
new_trust_passwd_hash , sec_channel_type ) ;
2001-12-05 14:00:26 +03:00
if ( NT_STATUS_IS_OK ( nt_status ) ) {
2002-06-25 12:57:24 +04:00
DEBUG ( 3 , ( " %s : trust_pw_change_and_store_it: Changed password. \n " ,
2006-07-11 22:01:26 +04:00
current_timestring ( False ) ) ) ;
2001-12-05 14:00:26 +03:00
/*
* Return the result of trying to write the new password
* back into the trust account file .
*/
2003-04-16 14:20:14 +04:00
if ( ! secrets_store_machine_password ( new_trust_passwd , domain , sec_channel_type ) ) {
2001-12-05 14:00:26 +03:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
}
}
return nt_status ;
}
/*********************************************************
Change the domain password on the PDC .
Do most of the legwork ourselfs . Caller must have
already setup the connection to the NETLOGON pipe
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
NTSTATUS trust_pw_find_change_and_store_it ( struct rpc_pipe_client * cli ,
2003-04-16 14:20:14 +04:00
TALLOC_CTX * mem_ctx ,
2002-11-13 02:15:52 +03:00
const char * domain )
2001-12-05 14:00:26 +03:00
{
unsigned char old_trust_passwd_hash [ 16 ] ;
2003-04-16 14:20:14 +04:00
uint32 sec_channel_type = 0 ;
2001-12-05 14:00:26 +03:00
if ( ! secrets_fetch_trust_account_password ( domain ,
old_trust_passwd_hash ,
2003-04-16 14:20:14 +04:00
NULL , & sec_channel_type ) ) {
2001-12-05 14:00:26 +03:00
DEBUG ( 0 , ( " could not fetch domain secrets for domain %s! \n " , domain ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2003-04-16 14:20:14 +04:00
return trust_pw_change_and_store_it ( cli , mem_ctx , domain ,
old_trust_passwd_hash ,
sec_channel_type ) ;
2003-03-14 20:05:13 +03:00
}
2003-07-01 07:49:41 +04:00
/*********************************************************************
Enumerate the list of trusted domains from a DC
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-07-01 21:51:52 +04:00
BOOL enumerate_domain_trusts ( TALLOC_CTX * mem_ctx , const char * domain ,
char * * * domain_names , uint32 * num_domains ,
2003-07-01 07:49:41 +04:00
DOM_SID * * sids )
{
POLICY_HND pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
fstring dc_name ;
struct in_addr dc_ip ;
uint32 enum_ctx = 0 ;
struct cli_state * cli = NULL ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * lsa_pipe ;
2003-07-01 07:49:41 +04:00
BOOL retry ;
2003-07-01 21:51:52 +04:00
2003-07-01 07:49:41 +04:00
* domain_names = NULL ;
* num_domains = 0 ;
* sids = NULL ;
2003-07-01 21:51:52 +04:00
2003-07-01 07:49:41 +04:00
/* lookup a DC first */
2003-07-01 21:51:52 +04:00
2004-01-05 07:10:28 +03:00
if ( ! get_dc_name ( domain , NULL , dc_name , & dc_ip ) ) {
2003-07-01 07:49:41 +04:00
DEBUG ( 3 , ( " enumerate_domain_trusts: can't locate a DC for domain %s \n " ,
domain ) ) ;
return False ;
}
2003-07-01 21:51:52 +04:00
2003-07-01 07:49:41 +04:00
/* setup the anonymous connection */
2003-07-01 21:51:52 +04:00
result = cli_full_connection ( & cli , global_myname ( ) , dc_name , & dc_ip , 0 , " IPC$ " , " IPC " ,
2003-07-31 03:49:29 +04:00
" " , " " , " " , 0 , Undefined , & retry ) ;
2003-07-01 07:49:41 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
2003-07-01 21:51:52 +04:00
2003-07-01 07:49:41 +04:00
/* open the LSARPC_PIPE */
2003-07-01 21:51:52 +04:00
2005-09-30 21:13:37 +04:00
lsa_pipe = cli_rpc_pipe_open_noauth ( cli , PI_LSARPC , & result ) ;
if ( ! lsa_pipe ) {
2003-07-01 07:49:41 +04:00
goto done ;
}
2003-07-01 21:51:52 +04:00
2003-07-01 07:49:41 +04:00
/* get a handle */
2003-07-01 21:51:52 +04:00
2005-09-30 21:13:37 +04:00
result = rpccli_lsa_open_policy ( lsa_pipe , mem_ctx , True ,
2003-07-01 07:49:41 +04:00
POLICY_VIEW_LOCAL_INFORMATION , & pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
/* Lookup list of trusted domains */
2005-09-30 21:13:37 +04:00
result = rpccli_lsa_enum_trust_dom ( lsa_pipe , mem_ctx , & pol , & enum_ctx ,
2003-07-01 07:49:41 +04:00
num_domains , domain_names , sids ) ;
2003-07-01 21:51:52 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
2003-07-01 07:49:41 +04:00
goto done ;
2003-07-01 21:51:52 +04:00
done :
2003-07-01 07:49:41 +04:00
/* cleanup */
2003-09-16 07:54:42 +04:00
if ( cli ) {
2003-11-22 09:15:28 +03:00
DEBUG ( 10 , ( " enumerate_domain_trusts: shutting down connection... \n " ) ) ;
2003-09-16 07:54:42 +04:00
cli_shutdown ( cli ) ;
}
2003-03-15 11:18:29 +03:00
2003-07-01 21:51:52 +04:00
return NT_STATUS_IS_OK ( result ) ;
2003-03-14 20:05:13 +03:00
}