Samba 3: added Samba 3.0.24 sources
[tomato.git] / release / src / router / samba3 / source / libsmb / trusts_util.c
blob55108bf72f2c0fa6827654cbd96060aed966e3e5
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);
90 if ((new_trust_passwd = talloc_strdup(mem_ctx, str)) == NULL) {
91 DEBUG(0, ("talloc_strdup failed\n"));
92 return NT_STATUS_NO_MEMORY;
95 E_md4hash(new_trust_passwd, new_trust_passwd_hash);
97 nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash,
98 new_trust_passwd_hash, sec_channel_type);
100 if (NT_STATUS_IS_OK(nt_status)) {
101 DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n",
102 timestring(False)));
104 * Return the result of trying to write the new password
105 * back into the trust account file.
107 if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) {
108 nt_status = NT_STATUS_UNSUCCESSFUL;
112 return nt_status;
115 /*********************************************************
116 Change the domain password on the PDC.
117 Do most of the legwork ourselfs. Caller must have
118 already setup the connection to the NETLOGON pipe
119 **********************************************************/
121 NTSTATUS trust_pw_find_change_and_store_it(struct rpc_pipe_client *cli,
122 TALLOC_CTX *mem_ctx,
123 const char *domain)
125 unsigned char old_trust_passwd_hash[16];
126 uint32 sec_channel_type = 0;
128 if (!secrets_fetch_trust_account_password(domain,
129 old_trust_passwd_hash,
130 NULL, &sec_channel_type)) {
131 DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain));
132 return NT_STATUS_UNSUCCESSFUL;
135 return trust_pw_change_and_store_it(cli, mem_ctx, domain,
136 old_trust_passwd_hash,
137 sec_channel_type);
140 /*********************************************************************
141 Enumerate the list of trusted domains from a DC
142 *********************************************************************/
144 BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
145 char ***domain_names, uint32 *num_domains,
146 DOM_SID **sids )
148 POLICY_HND pol;
149 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
150 fstring dc_name;
151 struct in_addr dc_ip;
152 uint32 enum_ctx = 0;
153 struct cli_state *cli = NULL;
154 struct rpc_pipe_client *lsa_pipe;
155 BOOL retry;
157 *domain_names = NULL;
158 *num_domains = 0;
159 *sids = NULL;
161 /* lookup a DC first */
163 if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
164 DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n",
165 domain));
166 return False;
169 /* setup the anonymous connection */
171 result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC",
172 "", "", "", 0, Undefined, &retry);
173 if ( !NT_STATUS_IS_OK(result) )
174 goto done;
176 /* open the LSARPC_PIPE */
178 lsa_pipe = cli_rpc_pipe_open_noauth( cli, PI_LSARPC, &result );
179 if ( !lsa_pipe) {
180 goto done;
183 /* get a handle */
185 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
186 POLICY_VIEW_LOCAL_INFORMATION, &pol);
187 if ( !NT_STATUS_IS_OK(result) )
188 goto done;
190 /* Lookup list of trusted domains */
192 result = rpccli_lsa_enum_trust_dom(lsa_pipe, mem_ctx, &pol, &enum_ctx,
193 num_domains, domain_names, sids);
194 if ( !NT_STATUS_IS_OK(result) )
195 goto done;
197 done:
198 /* cleanup */
199 if (cli) {
200 DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n"));
201 cli_shutdown( cli );
204 return NT_STATUS_IS_OK(result);