2 * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
3 * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
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)
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
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.
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
,
35 unsigned int mac_file_len
;
40 pstrcpy(mac_file
, lp_smb_passwd_file());
41 p
= strrchr(mac_file
, '/');
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",
54 fstrcpy(dom_name
, domain
);
56 fstrcpy(trust_name
, 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
)
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
) ));
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
);
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
);
118 /************************************************************************
119 Routine to delete the trust account password file for a domain.
120 ************************************************************************/
122 BOOL
trust_password_delete( char *domain
, char *name
)
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
)
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",
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",
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
));
175 * Get the hex password.
178 if (!pwdb_gethexpwd((char *)linebuf
, (char *)ret_pwd
, NULL
) ||
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
));
188 #ifdef DEBUG_PASSWORD
189 DEBUG(100,("get_trust_account_password:"));
190 dump_data(100, ret_pwd
, 16);
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
));
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
)
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",
225 pwdb_sethexpwd((char *)linebuf
, (uchar
*)md4_new_pwd
, 0);
226 pwdb_set_time_last_changed(&linebuf
[32], 32, (unsigned)time(NULL
));
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
) ));
235 fflush(mach_passwd_fp
);
239 BOOL
trust_get_passwd_time( uchar trust_passwd
[16],
240 const char *domain
, const char *myname
,
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
));
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();
261 trust_password_unlock();
263 unix_to_nt_time(modtime
, lct
);
268 BOOL
trust_get_passwd( uchar trust_passwd
[16],
269 const char *domain
, const char *myname
)
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
));
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();
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
;
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
));
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();
331 trust_password_unlock();