Merge from 3.0: quieten debug message for trust acct password change.
[tprouty/samba.git] / source3 / libsmb / trusts_util.c
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 **********************************************************/
32 static 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         uint32 neg_flags = 0x000001ff;
39
40         result = cli_nt_setup_creds(cli, sec_channel_type, orig_trust_passwd_hash, &neg_flags, 2);
41         
42         if (!NT_STATUS_IS_OK(result)) {
43                 DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
44                          nt_errstr(result)));
45                 return result;
46         }
47
48         result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash);
49
50         if (!NT_STATUS_IS_OK(result)) {
51                 DEBUG(0,("just_change_the_password: unable to change password (%s)!\n",
52                          nt_errstr(result)));
53         }
54         return result;
55 }
56
57 /*********************************************************
58  Change the domain password on the PDC.
59  Store the password ourselves, but use the supplied password
60  Caller must have already setup the connection to the NETLOGON pipe
61 **********************************************************/
62
63 NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
64                                       const char *domain,
65                                       unsigned char orig_trust_passwd_hash[16],
66                                       uint32 sec_channel_type)
67 {
68         unsigned char new_trust_passwd_hash[16];
69         char *new_trust_passwd;
70         char *str;
71         NTSTATUS nt_status;
72                 
73         /* Create a random machine account password */
74         str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
75         new_trust_passwd = talloc_strdup(mem_ctx, str);
76         
77         E_md4hash(new_trust_passwd, new_trust_passwd_hash);
78
79         nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash,
80                                              new_trust_passwd_hash, sec_channel_type);
81         
82         if (NT_STATUS_IS_OK(nt_status)) {
83                 DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", 
84                          timestring(False)));
85                 /*
86                  * Return the result of trying to write the new password
87                  * back into the trust account file.
88                  */
89                 if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) {
90                         nt_status = NT_STATUS_UNSUCCESSFUL;
91                 }
92         }
93
94         return nt_status;
95 }
96
97 /*********************************************************
98  Change the domain password on the PDC.
99  Do most of the legwork ourselfs.  Caller must have
100  already setup the connection to the NETLOGON pipe
101 **********************************************************/
102
103 NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, 
104                                            TALLOC_CTX *mem_ctx, 
105                                            const char *domain) 
106 {
107         unsigned char old_trust_passwd_hash[16];
108         char *up_domain;
109         uint32 sec_channel_type = 0;
110
111         up_domain = talloc_strdup(mem_ctx, domain);
112
113         if (!secrets_fetch_trust_account_password(domain,
114                                                   old_trust_passwd_hash, 
115                                                   NULL, &sec_channel_type)) {
116                 DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain));
117                 return NT_STATUS_UNSUCCESSFUL;
118         }
119         
120         return trust_pw_change_and_store_it(cli, mem_ctx, domain,
121                                             old_trust_passwd_hash,
122                                             sec_channel_type);
123         
124 }
125
126
127 /**
128  * Verify whether or not given domain is trusted.
129  *
130  * @param domain_name name of the domain to be verified
131  * @return true if domain is one of the trusted once or
132  *         false if otherwise
133  **/
134  
135 BOOL is_trusted_domain(const char* dom_name)
136 {
137         DOM_SID trustdom_sid;
138         char *pass = NULL;
139         time_t lct;
140         BOOL ret;
141
142         if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
143                 /*
144                  * Query the secrets db as an ultimate source of information
145                  * about trusted domain names. This is PDC or BDC case.
146                  */
147                 ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
148                 SAFE_FREE(pass);
149                 if (ret) 
150                         return ret;
151         }
152
153         /*
154          * Query the trustdom_cache updated periodically. The only
155          * way for domain member server.
156          */
157         if (trustdom_cache_enable() &&
158                 trustdom_cache_fetch(dom_name, &trustdom_sid)) {
159                 trustdom_cache_shutdown();
160                 return True;
161         }
162
163         /*
164          * if nothing's been found, then give up here, although
165          * the last resort might be to query the PDC.
166          */
167         return False;
168 }
169