Backport bugfix for bug #5710.
[Samba.git] / source / libsmb / trusts_util.c
blob257d04effca95e4850f7573436d5eb5bd789c7b4
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
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.
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.
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.
22 #include "includes.h"
24 /*********************************************************
25 Change the domain password on the PDC.
27 Just changes the password betwen the two values specified.
29 Caller must have the cli connected to the netlogon pipe
30 already.
31 **********************************************************/
33 static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
34 const unsigned char orig_trust_passwd_hash[16],
35 const char *new_trust_pwd_cleartext,
36 const unsigned char new_trust_passwd_hash[16],
37 uint32 sec_channel_type)
39 NTSTATUS result;
40 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
42 result = rpccli_netlogon_setup_creds(cli,
43 cli->cli->desthost, /* server name */
44 lp_workgroup(), /* domain */
45 global_myname(), /* client name */
46 global_myname(), /* machine account name */
47 orig_trust_passwd_hash,
48 sec_channel_type,
49 &neg_flags);
51 if (!NT_STATUS_IS_OK(result)) {
52 DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
53 nt_errstr(result)));
54 return result;
57 if (neg_flags & NETLOGON_NEG_PASSWORD_SET2) {
58 result = rpccli_net_srv_pwset2(cli, mem_ctx, global_myname(),
59 new_trust_pwd_cleartext);
60 } else {
61 result = rpccli_net_srv_pwset(cli, mem_ctx, global_myname(),
62 new_trust_passwd_hash);
65 if (!NT_STATUS_IS_OK(result)) {
66 DEBUG(0,("just_change_the_password: unable to change password (%s)!\n",
67 nt_errstr(result)));
69 return result;
72 /*********************************************************
73 Change the domain password on the PDC.
74 Store the password ourselves, but use the supplied password
75 Caller must have already setup the connection to the NETLOGON pipe
76 **********************************************************/
78 NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
79 const char *domain,
80 unsigned char orig_trust_passwd_hash[16],
81 uint32 sec_channel_type)
83 unsigned char new_trust_passwd_hash[16];
84 char *new_trust_passwd;
85 char *str;
86 NTSTATUS nt_status;
88 /* Create a random machine account password */
89 str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
91 if ((new_trust_passwd = talloc_strdup(mem_ctx, str)) == NULL) {
92 DEBUG(0, ("talloc_strdup failed\n"));
93 return NT_STATUS_NO_MEMORY;
96 E_md4hash(new_trust_passwd, new_trust_passwd_hash);
98 nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash,
99 new_trust_passwd,
100 new_trust_passwd_hash, sec_channel_type);
102 if (NT_STATUS_IS_OK(nt_status)) {
103 DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n",
104 current_timestring(False)));
106 * Return the result of trying to write the new password
107 * back into the trust account file.
109 if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) {
110 nt_status = NT_STATUS_UNSUCCESSFUL;
114 return nt_status;
117 /*********************************************************
118 Change the domain password on the PDC.
119 Do most of the legwork ourselfs. Caller must have
120 already setup the connection to the NETLOGON pipe
121 **********************************************************/
123 NTSTATUS trust_pw_find_change_and_store_it(struct rpc_pipe_client *cli,
124 TALLOC_CTX *mem_ctx,
125 const char *domain)
127 unsigned char old_trust_passwd_hash[16];
128 uint32 sec_channel_type = 0;
130 if (!secrets_fetch_trust_account_password(domain,
131 old_trust_passwd_hash,
132 NULL, &sec_channel_type)) {
133 DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain));
134 return NT_STATUS_UNSUCCESSFUL;
137 return trust_pw_change_and_store_it(cli, mem_ctx, domain,
138 old_trust_passwd_hash,
139 sec_channel_type);
142 /*********************************************************************
143 Enumerate the list of trusted domains from a DC
144 *********************************************************************/
146 BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
147 char ***domain_names, uint32 *num_domains,
148 DOM_SID **sids )
150 POLICY_HND pol;
151 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
152 fstring dc_name;
153 struct in_addr dc_ip;
154 uint32 enum_ctx = 0;
155 struct cli_state *cli = NULL;
156 struct rpc_pipe_client *lsa_pipe;
157 BOOL retry;
159 *domain_names = NULL;
160 *num_domains = 0;
161 *sids = NULL;
163 /* lookup a DC first */
165 if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
166 DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n",
167 domain));
168 return False;
171 /* setup the anonymous connection */
173 result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC",
174 "", "", "", 0, Undefined, &retry);
175 if ( !NT_STATUS_IS_OK(result) )
176 goto done;
178 /* open the LSARPC_PIPE */
180 lsa_pipe = cli_rpc_pipe_open_noauth( cli, PI_LSARPC, &result );
181 if ( !lsa_pipe) {
182 goto done;
185 /* get a handle */
187 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
188 POLICY_VIEW_LOCAL_INFORMATION, &pol);
189 if ( !NT_STATUS_IS_OK(result) )
190 goto done;
192 /* Lookup list of trusted domains */
194 result = rpccli_lsa_enum_trust_dom(lsa_pipe, mem_ctx, &pol, &enum_ctx,
195 num_domains, domain_names, sids);
196 if ( !NT_STATUS_IS_OK(result) )
197 goto done;
199 done:
200 /* cleanup */
201 if (cli) {
202 DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n"));
203 cli_shutdown( cli );
206 return NT_STATUS_IS_OK(result);