This commit was manufactured by cvs2svn to create tag
[Samba.git] / source / passdb / smbpassfile.c
blob806932fe351b054437fadd7244ecfa10f34297e7
1 /*
2 * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
3 * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 675
17 * Mass Ave, Cambridge, MA 02139, USA.
20 #include "includes.h"
22 extern int DEBUGLEVEL;
24 BOOL global_machine_password_needs_changing = False;
25 static int mach_passwd_lock_depth = 0;
26 static FILE *mach_passwd_fp = NULL;
28 /************************************************************************
29 Routine to get the name for a trust account file.
30 ************************************************************************/
32 static void get_trust_account_file_name( const char *domain, const char *name,
33 char *mac_file)
35 unsigned int mac_file_len;
36 char *p;
37 fstring dom_name;
38 fstring trust_name;
40 pstrcpy(mac_file, lp_smb_passwd_file());
41 p = strrchr(mac_file, '/');
42 if(p != NULL)
43 *++p = '\0';
45 mac_file_len = strlen(mac_file);
47 if ((int)(sizeof(pstring) - mac_file_len - strlen(domain) - strlen(name) - 6) < 0)
49 DEBUG(0,("get_trust_account_file_name: path %s too long to add trust details.\n",
50 mac_file));
51 return;
54 fstrcpy(dom_name, domain);
55 strupper(dom_name);
56 fstrcpy(trust_name, name);
57 strupper(trust_name);
59 pstrcat(mac_file, dom_name);
60 pstrcat(mac_file, ".");
61 pstrcat(mac_file, trust_name);
62 pstrcat(mac_file, ".mac");
64 DEBUG(5,("trust_account_file_name: %s\n", mac_file));
67 /************************************************************************
68 Routine to lock the trust account password file for a domain.
69 ************************************************************************/
71 BOOL trust_password_lock( const char *domain, const char *name, BOOL update)
73 pstring mac_file;
75 if(mach_passwd_lock_depth == 0) {
77 get_trust_account_file_name( domain, name, mac_file);
79 if((mach_passwd_fp = sys_fopen(mac_file, "r+b")) == NULL) {
80 if(errno == ENOENT && update) {
81 mach_passwd_fp = sys_fopen(mac_file, "w+b");
84 if(mach_passwd_fp == NULL) {
85 DEBUG(0,("trust_password_lock: cannot open file %s - Error was %s.\n",
86 mac_file, strerror(errno) ));
87 return False;
91 chmod(mac_file, 0600);
93 if(!file_lock(fileno(mach_passwd_fp), (update ? F_WRLCK : F_RDLCK),
94 60, &mach_passwd_lock_depth))
96 DEBUG(0,("trust_password_lock: cannot lock file %s\n", mac_file));
97 fclose(mach_passwd_fp);
98 return False;
103 return True;
106 /************************************************************************
107 Routine to unlock the trust account password file for a domain.
108 ************************************************************************/
110 BOOL trust_password_unlock(void)
112 BOOL ret = file_unlock(fileno(mach_passwd_fp), &mach_passwd_lock_depth);
113 if(mach_passwd_lock_depth == 0)
114 fclose(mach_passwd_fp);
115 return ret;
118 /************************************************************************
119 Routine to delete the trust account password file for a domain.
120 ************************************************************************/
122 BOOL trust_password_delete( char *domain, char *name )
124 pstring mac_file;
126 get_trust_account_file_name( domain, name, mac_file);
127 return (unlink( mac_file ) == 0);
130 /************************************************************************
131 Routine to get the trust account password for a domain.
132 The user of this function must have locked the trust password file.
133 ************************************************************************/
135 BOOL get_trust_account_password( uchar *ret_pwd, time_t *pass_last_set_time)
137 char linebuf[256];
139 linebuf[0] = '\0';
141 *pass_last_set_time = (time_t)0;
142 memset(ret_pwd, '\0', 16);
144 if(sys_fseek( mach_passwd_fp, (SMB_OFF_T)0, SEEK_SET) == -1) {
145 DEBUG(0,("get_trust_account_password: Failed to seek to start of file. Error was %s.\n",
146 strerror(errno) ));
147 return False;
150 fgets(linebuf, sizeof(linebuf), mach_passwd_fp);
151 if(ferror(mach_passwd_fp)) {
152 DEBUG(0,("get_trust_account_password: Failed to read password. Error was %s.\n",
153 strerror(errno) ));
154 return False;
157 if(linebuf[strlen(linebuf)-1] == '\n')
158 linebuf[strlen(linebuf)-1] = '\0';
161 * The length of the line read
162 * must be 45 bytes ( <---XXXX 32 bytes-->:TLC-12345678
165 if(strlen(linebuf) != 45) {
166 DEBUG(0,("get_trust_account_password: Malformed trust password file (wrong length \
167 - was %d, should be 45).\n", strlen(linebuf)));
168 #ifdef DEBUG_PASSWORD
169 DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
170 #endif
171 return False;
175 * Get the hex password.
178 if (!pwdb_gethexpwd((char *)linebuf, (char *)ret_pwd, NULL) ||
179 linebuf[32] != ':')
181 DEBUG(0,("get_trust_account_password: Malformed trust password file (incorrect format).\n"));
182 #ifdef DEBUG_PASSWORD
183 DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
184 #endif
185 return False;
188 #ifdef DEBUG_PASSWORD
189 DEBUG(100,("get_trust_account_password:"));
190 dump_data(100, ret_pwd, 16);
191 #endif
193 * Get the last changed time.
196 (*pass_last_set_time) = pwdb_get_time_last_changed(&linebuf[33]);
198 if ((*pass_last_set_time) == -1)
200 DEBUG(0,("get_trust_account_password: Malformed trust password file (no timestamp).\n"));
201 #ifdef DEBUG_PASSWORD
202 DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
203 #endif
204 return False;
207 return True;
210 /************************************************************************
211 Routine to get the trust account password for a domain.
212 The user of this function must have locked the trust password file.
213 ************************************************************************/
215 BOOL set_trust_account_password( uchar *md4_new_pwd)
217 char linebuf[64];
219 if(sys_fseek( mach_passwd_fp, (SMB_OFF_T)0, SEEK_SET) == -1) {
220 DEBUG(0,("set_trust_account_password: Failed to seek to start of file. Error was %s.\n",
221 strerror(errno) ));
222 return False;
225 pwdb_sethexpwd((char *)linebuf, (uchar*)md4_new_pwd, 0);
226 pwdb_set_time_last_changed(&linebuf[32], 32, (unsigned)time(NULL));
227 linebuf[45] = '\n';
229 if(fwrite( linebuf, 1, 46, mach_passwd_fp)!= 46) {
230 DEBUG(0,("set_trust_account_password: Failed to write file. Warning - the trust \
231 account is now invalid. Please recreate. Error was %s.\n", strerror(errno) ));
232 return False;
235 fflush(mach_passwd_fp);
236 return True;
239 BOOL trust_get_passwd_time( uchar trust_passwd[16],
240 const char *domain, const char *myname,
241 NTTIME *modtime)
243 time_t lct;
246 * Get the trust account password.
248 if(!trust_password_lock( domain, myname, False)) {
249 DEBUG(0,("trust_get_passwd: unable to open the trust account password file for \
250 trust %s in domain %s.\n", myname, domain ));
251 return False;
254 if(get_trust_account_password( trust_passwd, &lct) == False) {
255 DEBUG(0,("trust_get_passwd: unable to read the trust account password for \
256 trust %s in domain %s.\n", myname, domain ));
257 trust_password_unlock();
258 return False;
261 trust_password_unlock();
263 unix_to_nt_time(modtime, lct);
265 return True;
268 BOOL trust_get_passwd( uchar trust_passwd[16],
269 const char *domain, const char *myname)
271 time_t lct;
274 * Get the trust account password.
276 if(!trust_password_lock( domain, myname, False)) {
277 DEBUG(0,("trust_get_passwd: unable to open the trust account password file for \
278 trust %s in domain %s.\n", myname, domain ));
279 return False;
282 if(get_trust_account_password( trust_passwd, &lct) == False) {
283 DEBUG(0,("trust_get_passwd: unable to read the trust account password for \
284 trust %s in domain %s.\n", myname, domain ));
285 trust_password_unlock();
286 return False;
289 trust_password_unlock();
292 * Here we check the last change time to see if the trust
293 * password needs changing. JRA.
296 if(time(NULL) > lct + lp_machine_password_timeout())
298 global_machine_password_needs_changing = True;
300 return True;
303 /*********************************************************
304 record Trust Account password.
305 **********************************************************/
306 BOOL create_trust_account_file(char *domain, char *name, uchar pass[16])
309 * Create the machine account password file.
312 if (!trust_password_lock( domain, name, True))
314 DEBUG(0,("unable to open the trust account password file for \
315 account %s in domain %s.\n", name, domain));
316 return False;
320 * Write the old machine account password.
323 if (!set_trust_account_password( pass))
325 DEBUG(0,("unable to write the trust account password for \
326 %s in domain %s.\n", name, domain));
327 trust_password_unlock();
328 return False;
331 trust_password_unlock();
333 return True;