r14683: Get rid of hardcoded output file. With no arg, print to stdout,
[Samba.git] / source / libsmb / trusts_util.c
blob9d94c1d00a1e813fa5a4795d6be77647f5366076
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 unsigned char new_trust_passwd_hash[16],
36 uint32 sec_channel_type)
38 NTSTATUS result;
40 /* Check if the netlogon pipe is open using schannel. If so we
41 already have valid creds. If not we must set them up. */
43 if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
44 uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
46 result = rpccli_netlogon_setup_creds(cli,
47 cli->cli->desthost, /* server name */
48 lp_workgroup(), /* domain */
49 global_myname(), /* client name */
50 global_myname(), /* machine account name */
51 orig_trust_passwd_hash,
52 sec_channel_type,
53 &neg_flags);
55 if (!NT_STATUS_IS_OK(result)) {
56 DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
57 nt_errstr(result)));
58 return result;
62 result = rpccli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash);
64 if (!NT_STATUS_IS_OK(result)) {
65 DEBUG(0,("just_change_the_password: unable to change password (%s)!\n",
66 nt_errstr(result)));
68 return result;
71 /*********************************************************
72 Change the domain password on the PDC.
73 Store the password ourselves, but use the supplied password
74 Caller must have already setup the connection to the NETLOGON pipe
75 **********************************************************/
77 NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
78 const char *domain,
79 unsigned char orig_trust_passwd_hash[16],
80 uint32 sec_channel_type)
82 unsigned char new_trust_passwd_hash[16];
83 char *new_trust_passwd;
84 char *str;
85 NTSTATUS nt_status;
87 /* Create a random machine account password */
88 str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
89 new_trust_passwd = talloc_strdup(mem_ctx, str);
91 E_md4hash(new_trust_passwd, new_trust_passwd_hash);
93 nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash,
94 new_trust_passwd_hash, sec_channel_type);
96 if (NT_STATUS_IS_OK(nt_status)) {
97 DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n",
98 timestring(False)));
100 * Return the result of trying to write the new password
101 * back into the trust account file.
103 if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) {
104 nt_status = NT_STATUS_UNSUCCESSFUL;
108 return nt_status;
111 /*********************************************************
112 Change the domain password on the PDC.
113 Do most of the legwork ourselfs. Caller must have
114 already setup the connection to the NETLOGON pipe
115 **********************************************************/
117 NTSTATUS trust_pw_find_change_and_store_it(struct rpc_pipe_client *cli,
118 TALLOC_CTX *mem_ctx,
119 const char *domain)
121 unsigned char old_trust_passwd_hash[16];
122 uint32 sec_channel_type = 0;
124 if (!secrets_fetch_trust_account_password(domain,
125 old_trust_passwd_hash,
126 NULL, &sec_channel_type)) {
127 DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain));
128 return NT_STATUS_UNSUCCESSFUL;
131 return trust_pw_change_and_store_it(cli, mem_ctx, domain,
132 old_trust_passwd_hash,
133 sec_channel_type);
136 /*********************************************************************
137 Enumerate the list of trusted domains from a DC
138 *********************************************************************/
140 BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
141 char ***domain_names, uint32 *num_domains,
142 DOM_SID **sids )
144 POLICY_HND pol;
145 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
146 fstring dc_name;
147 struct in_addr dc_ip;
148 uint32 enum_ctx = 0;
149 struct cli_state *cli = NULL;
150 struct rpc_pipe_client *lsa_pipe;
151 BOOL retry;
153 *domain_names = NULL;
154 *num_domains = 0;
155 *sids = NULL;
157 /* lookup a DC first */
159 if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
160 DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n",
161 domain));
162 return False;
165 /* setup the anonymous connection */
167 result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC",
168 "", "", "", 0, Undefined, &retry);
169 if ( !NT_STATUS_IS_OK(result) )
170 goto done;
172 /* open the LSARPC_PIPE */
174 lsa_pipe = cli_rpc_pipe_open_noauth( cli, PI_LSARPC, &result );
175 if ( !lsa_pipe) {
176 goto done;
179 /* get a handle */
181 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
182 POLICY_VIEW_LOCAL_INFORMATION, &pol);
183 if ( !NT_STATUS_IS_OK(result) )
184 goto done;
186 /* Lookup list of trusted domains */
188 result = rpccli_lsa_enum_trust_dom(lsa_pipe, mem_ctx, &pol, &enum_ctx,
189 num_domains, domain_names, sids);
190 if ( !NT_STATUS_IS_OK(result) )
191 goto done;
193 done:
194 /* cleanup */
195 if (cli) {
196 DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n"));
197 cli_shutdown( cli );
200 return NT_STATUS_IS_OK(result);