1/* 2 * Unix SMB/CIFS implementation. 3 * Routines to operate on various trust relationships 4 * Copyright (C) Andrew Bartlett 2001 5 * Copyright (C) Rafal Szczesniak 2003 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22#include "includes.h" 23 24/********************************************************* 25 Change the domain password on the PDC. 26 27 Just changes the password betwen the two values specified. 28 29 Caller must have the cli connected to the netlogon pipe 30 already. 31**********************************************************/ 32static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx, 33 unsigned char orig_trust_passwd_hash[16], 34 unsigned char new_trust_passwd_hash[16], 35 uint32 sec_channel_type) 36{ 37 NTSTATUS result; 38 39 /* ensure that schannel uses the right domain */ 40 fstrcpy(cli->domain, lp_workgroup()); 41 if (! NT_STATUS_IS_OK(result = cli_nt_establish_netlogon(cli, sec_channel_type, orig_trust_passwd_hash))) { 42 DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n", 43 nt_errstr(result))); 44 return result; 45 } 46 47 result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash); 48 49 if (!NT_STATUS_IS_OK(result)) { 50 DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", 51 nt_errstr(result))); 52 } 53 return result; 54} 55 56/********************************************************* 57 Change the domain password on the PDC. 58 Store the password ourselves, but use the supplied password 59 Caller must have already setup the connection to the NETLOGON pipe 60**********************************************************/ 61 62NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, 63 const char *domain, 64 unsigned char orig_trust_passwd_hash[16], 65 uint32 sec_channel_type) 66{ 67 unsigned char new_trust_passwd_hash[16]; 68 char *new_trust_passwd; 69 char *str; 70 NTSTATUS nt_status; 71 72 /* Create a random machine account password */ 73 str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); 74 new_trust_passwd = talloc_strdup(mem_ctx, str); 75 76 E_md4hash(new_trust_passwd, new_trust_passwd_hash); 77 78 nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, 79 new_trust_passwd_hash, sec_channel_type); 80 81 if (NT_STATUS_IS_OK(nt_status)) { 82 DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", 83 timestring(False))); 84 /* 85 * Return the result of trying to write the new password 86 * back into the trust account file. 87 */ 88 if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) { 89 nt_status = NT_STATUS_UNSUCCESSFUL; 90 } 91 } 92 93 return nt_status; 94} 95 96/********************************************************* 97 Change the domain password on the PDC. 98 Do most of the legwork ourselfs. Caller must have 99 already setup the connection to the NETLOGON pipe 100**********************************************************/ 101 102NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, 103 TALLOC_CTX *mem_ctx, 104 const char *domain) 105{ 106 unsigned char old_trust_passwd_hash[16]; 107 char *up_domain; 108 uint32 sec_channel_type = 0; 109 110 up_domain = talloc_strdup(mem_ctx, domain); 111 112 if (!secrets_fetch_trust_account_password(domain, 113 old_trust_passwd_hash, 114 NULL, &sec_channel_type)) { 115 DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain)); 116 return NT_STATUS_UNSUCCESSFUL; 117 } 118 119 return trust_pw_change_and_store_it(cli, mem_ctx, domain, 120 old_trust_passwd_hash, 121 sec_channel_type); 122 123} 124 125/********************************************************************* 126 Enumerate the list of trusted domains from a DC 127*********************************************************************/ 128 129BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, 130 char ***domain_names, uint32 *num_domains, 131 DOM_SID **sids ) 132{ 133 POLICY_HND pol; 134 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 135 fstring dc_name; 136 struct in_addr dc_ip; 137 uint32 enum_ctx = 0; 138 struct cli_state *cli = NULL; 139 BOOL retry; 140 141 *domain_names = NULL; 142 *num_domains = 0; 143 *sids = NULL; 144 145 /* lookup a DC first */ 146 147 if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) { 148 DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n", 149 domain)); 150 return False; 151 } 152 153 /* setup the anonymous connection */ 154 155 result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC", 156 "", "", "", 0, Undefined, &retry); 157 if ( !NT_STATUS_IS_OK(result) ) 158 goto done; 159 160 /* open the LSARPC_PIPE */ 161 162 if ( !cli_nt_session_open( cli, PI_LSARPC ) ) { 163 result = NT_STATUS_UNSUCCESSFUL; 164 goto done; 165 } 166 167 /* get a handle */ 168 169 result = cli_lsa_open_policy(cli, mem_ctx, True, 170 POLICY_VIEW_LOCAL_INFORMATION, &pol); 171 if ( !NT_STATUS_IS_OK(result) ) 172 goto done; 173 174 /* Lookup list of trusted domains */ 175 176 result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx, 177 num_domains, domain_names, sids); 178 if ( !NT_STATUS_IS_OK(result) ) 179 goto done; 180 181done: 182 /* cleanup */ 183 if (cli) { 184 DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n")); 185 cli_shutdown( cli ); 186 } 187 188 return NT_STATUS_IS_OK(result); 189} 190 191