r25407: Revert Longhorn join patch as it is not correct for the 3.2 tree.
[Samba/bb.git] / source3 / libsmb / trusts_util.c
blob0922f9f41eacccc806082a2a7e57914674a5b96c
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 3 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, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
23 /*********************************************************
24 Change the domain password on the PDC.
26 Just changes the password betwen the two values specified.
28 Caller must have the cli connected to the netlogon pipe
29 already.
30 **********************************************************/
32 static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
33 const unsigned char orig_trust_passwd_hash[16],
34 const unsigned char new_trust_passwd_hash[16],
35 uint32 sec_channel_type)
37 NTSTATUS result;
39 /* Check if the netlogon pipe is open using schannel. If so we
40 already have valid creds. If not we must set them up. */
42 if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
43 uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
45 result = rpccli_netlogon_setup_creds(cli,
46 cli->cli->desthost, /* server name */
47 lp_workgroup(), /* domain */
48 global_myname(), /* client name */
49 global_myname(), /* machine account name */
50 orig_trust_passwd_hash,
51 sec_channel_type,
52 &neg_flags);
54 if (!NT_STATUS_IS_OK(result)) {
55 DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
56 nt_errstr(result)));
57 return result;
61 result = rpccli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash);
63 if (!NT_STATUS_IS_OK(result)) {
64 DEBUG(0,("just_change_the_password: unable to change password (%s)!\n",
65 nt_errstr(result)));
67 return result;
70 /*********************************************************
71 Change the domain password on the PDC.
72 Store the password ourselves, but use the supplied password
73 Caller must have already setup the connection to the NETLOGON pipe
74 **********************************************************/
76 NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
77 const char *domain,
78 unsigned char orig_trust_passwd_hash[16],
79 uint32 sec_channel_type)
81 unsigned char new_trust_passwd_hash[16];
82 char *new_trust_passwd;
83 char *str;
84 NTSTATUS nt_status;
86 /* Create a random machine account password */
87 str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
89 if ((new_trust_passwd = talloc_strdup(mem_ctx, str)) == NULL) {
90 DEBUG(0, ("talloc_strdup failed\n"));
91 return NT_STATUS_NO_MEMORY;
94 E_md4hash(new_trust_passwd, new_trust_passwd_hash);
96 nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash,
97 new_trust_passwd_hash, sec_channel_type);
99 if (NT_STATUS_IS_OK(nt_status)) {
100 DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n",
101 current_timestring(False)));
103 * Return the result of trying to write the new password
104 * back into the trust account file.
106 if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) {
107 nt_status = NT_STATUS_UNSUCCESSFUL;
111 return nt_status;
114 /*********************************************************
115 Change the domain password on the PDC.
116 Do most of the legwork ourselfs. Caller must have
117 already setup the connection to the NETLOGON pipe
118 **********************************************************/
120 NTSTATUS trust_pw_find_change_and_store_it(struct rpc_pipe_client *cli,
121 TALLOC_CTX *mem_ctx,
122 const char *domain)
124 unsigned char old_trust_passwd_hash[16];
125 uint32 sec_channel_type = 0;
127 if (!secrets_fetch_trust_account_password(domain,
128 old_trust_passwd_hash,
129 NULL, &sec_channel_type)) {
130 DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain));
131 return NT_STATUS_UNSUCCESSFUL;
134 return trust_pw_change_and_store_it(cli, mem_ctx, domain,
135 old_trust_passwd_hash,
136 sec_channel_type);
139 /*********************************************************************
140 Enumerate the list of trusted domains from a DC
141 *********************************************************************/
143 BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
144 char ***domain_names, uint32 *num_domains,
145 DOM_SID **sids )
147 POLICY_HND pol;
148 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
149 fstring dc_name;
150 struct in_addr dc_ip;
151 uint32 enum_ctx = 0;
152 struct cli_state *cli = NULL;
153 struct rpc_pipe_client *lsa_pipe;
154 BOOL retry;
156 *domain_names = NULL;
157 *num_domains = 0;
158 *sids = NULL;
160 /* lookup a DC first */
162 if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
163 DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n",
164 domain));
165 return False;
168 /* setup the anonymous connection */
170 result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC",
171 "", "", "", 0, Undefined, &retry);
172 if ( !NT_STATUS_IS_OK(result) )
173 goto done;
175 /* open the LSARPC_PIPE */
177 lsa_pipe = cli_rpc_pipe_open_noauth( cli, PI_LSARPC, &result );
178 if ( !lsa_pipe) {
179 goto done;
182 /* get a handle */
184 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
185 POLICY_VIEW_LOCAL_INFORMATION, &pol);
186 if ( !NT_STATUS_IS_OK(result) )
187 goto done;
189 /* Lookup list of trusted domains */
191 result = rpccli_lsa_enum_trust_dom(lsa_pipe, mem_ctx, &pol, &enum_ctx,
192 num_domains, domain_names, sids);
193 if ( !NT_STATUS_IS_OK(result) )
194 goto done;
196 done:
197 /* cleanup */
198 if (cli) {
199 DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n"));
200 cli_shutdown( cli );
203 return NT_STATUS_IS_OK(result);