mirror of
https://github.com/samba-team/samba.git
synced 2024-12-27 03:21:53 +03:00
ac9b687cc2
config.h.in: Added fseek64 and ftell64.
includes.h: Added definition of SMB_BIG_INTEGER.
smb.h: Changed (*getsmbpwpos) and (*setsmbpwpos) to use SMB_BIG_INTEGER.
access.c: Tidyup of dbug statement.
system.c: Added sys_fseek and sys_ftell. Changed mode calls to use mode_t.
asyncdns.c: Tidyup of comment.
loadparm.c: Tidyup of set_default_server_announce_type() function definition.
ldap.c: Changed (*getsmbpwpos) and (*setsmbpwpos) to use SMB_BIG_INTEGER.
nispass.c: Changed (*getsmbpwpos) and (*setsmbpwpos) to use SMB_BIG_INTEGER.
smbpass.c: Changed (*getsmbpwpos) and (*setsmbpwpos) to use SMB_BIG_INTEGER.
smbpassfile.c: Use sys_fseek().
chgpasswd.c: Tidyup of debug statement.
dosmode.c: Changed mode calls to use mode_t.
ipc.c: Removal of dead code.
nttrans.c: Changed mode calls to use mode_t.
open.c: Changed mode calls to use mode_t.
pipes.c: Removal of dead code.
reply.c: Removal of dead code.
trans2.c: Removal of dead code. Changed mode calls to use mode_t.
Jeremy.
(This used to be commit c381d32e3d
)
321 lines
8.9 KiB
C
321 lines
8.9 KiB
C
/*
|
|
* Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
|
|
* Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it under
|
|
* the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program; if not, write to the Free Software Foundation, Inc., 675
|
|
* Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include "includes.h"
|
|
|
|
extern int DEBUGLEVEL;
|
|
|
|
static int gotalarm;
|
|
int pw_file_lock_depth = 0;
|
|
|
|
/***************************************************************
|
|
Signal function to tell us we timed out.
|
|
****************************************************************/
|
|
|
|
static void gotalarm_sig(void)
|
|
{
|
|
gotalarm = 1;
|
|
}
|
|
|
|
/***************************************************************
|
|
Lock or unlock a fd for a known lock type. Abandon after waitsecs
|
|
seconds.
|
|
****************************************************************/
|
|
|
|
BOOL do_file_lock(int fd, int waitsecs, int type)
|
|
{
|
|
SMB_STRUCT_FLOCK lock;
|
|
int ret;
|
|
|
|
gotalarm = 0;
|
|
CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
|
|
|
|
lock.l_type = type;
|
|
lock.l_whence = SEEK_SET;
|
|
lock.l_start = 0;
|
|
lock.l_len = 1;
|
|
lock.l_pid = 0;
|
|
|
|
alarm(5);
|
|
ret = fcntl(fd, SMB_F_SETLKW, &lock);
|
|
alarm(0);
|
|
CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
|
|
|
|
if (gotalarm) {
|
|
DEBUG(0, ("do_file_lock: failed to %s file.\n",
|
|
type == F_UNLCK ? "unlock" : "lock"));
|
|
return False;
|
|
}
|
|
|
|
return (ret == 0);
|
|
}
|
|
|
|
|
|
/***************************************************************
|
|
Lock an fd. Abandon after waitsecs seconds.
|
|
****************************************************************/
|
|
|
|
BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
|
|
{
|
|
if (fd < 0)
|
|
return False;
|
|
|
|
(*plock_depth)++;
|
|
|
|
if(pw_file_lock_depth == 0) {
|
|
if (!do_file_lock(fd, secs, type)) {
|
|
DEBUG(10,("pw_file_lock: locking file failed, error = %s.\n",
|
|
strerror(errno)));
|
|
return False;
|
|
}
|
|
}
|
|
|
|
return True;
|
|
}
|
|
|
|
/***************************************************************
|
|
Unlock an fd. Abandon after waitsecs seconds.
|
|
****************************************************************/
|
|
|
|
BOOL pw_file_unlock(int fd, int *plock_depth)
|
|
{
|
|
BOOL ret=True;
|
|
|
|
if(*plock_depth == 1)
|
|
ret = do_file_lock(fd, 5, F_UNLCK);
|
|
|
|
(*plock_depth)--;
|
|
|
|
if(!ret)
|
|
DEBUG(10,("pw_file_unlock: unlocking file failed, error = %s.\n",
|
|
strerror(errno)));
|
|
return ret;
|
|
}
|
|
|
|
static int mach_passwd_lock_depth;
|
|
static FILE *mach_passwd_fp;
|
|
|
|
/************************************************************************
|
|
Routine to get the name for a trust account file.
|
|
************************************************************************/
|
|
|
|
static void get_trust_account_file_name( char *domain, char *name, char *mac_file)
|
|
{
|
|
unsigned int mac_file_len;
|
|
char *p;
|
|
|
|
pstrcpy(mac_file, lp_smb_passwd_file());
|
|
p = strrchr(mac_file, '/');
|
|
if(p != NULL)
|
|
*++p = '\0';
|
|
|
|
mac_file_len = strlen(mac_file);
|
|
|
|
if ((int)(sizeof(pstring) - mac_file_len - strlen(domain) - strlen(name) - 6) < 0)
|
|
{
|
|
DEBUG(0,("trust_password_lock: path %s too long to add trust details.\n",
|
|
mac_file));
|
|
return;
|
|
}
|
|
|
|
pstrcat(mac_file, domain);
|
|
pstrcat(mac_file, ".");
|
|
pstrcat(mac_file, name);
|
|
pstrcat(mac_file, ".mac");
|
|
}
|
|
|
|
/************************************************************************
|
|
Routine to lock the trust account password file for a domain.
|
|
************************************************************************/
|
|
|
|
BOOL trust_password_lock( char *domain, char *name, BOOL update)
|
|
{
|
|
pstring mac_file;
|
|
|
|
if(mach_passwd_lock_depth == 0) {
|
|
|
|
get_trust_account_file_name( domain, name, mac_file);
|
|
|
|
if((mach_passwd_fp = fopen(mac_file, "r+b")) == NULL) {
|
|
if(errno == ENOENT && update) {
|
|
mach_passwd_fp = fopen(mac_file, "w+b");
|
|
}
|
|
|
|
if(mach_passwd_fp == NULL) {
|
|
DEBUG(0,("trust_password_lock: cannot open file %s - Error was %s.\n",
|
|
mac_file, strerror(errno) ));
|
|
return False;
|
|
}
|
|
}
|
|
|
|
chmod(mac_file, 0600);
|
|
|
|
if(!pw_file_lock(fileno(mach_passwd_fp), (update ? F_WRLCK : F_RDLCK),
|
|
60, &mach_passwd_lock_depth))
|
|
{
|
|
DEBUG(0,("trust_password_lock: cannot lock file %s\n", mac_file));
|
|
fclose(mach_passwd_fp);
|
|
return False;
|
|
}
|
|
|
|
}
|
|
|
|
return True;
|
|
}
|
|
|
|
/************************************************************************
|
|
Routine to unlock the trust account password file for a domain.
|
|
************************************************************************/
|
|
|
|
BOOL trust_password_unlock(void)
|
|
{
|
|
BOOL ret = pw_file_unlock(fileno(mach_passwd_fp), &mach_passwd_lock_depth);
|
|
if(mach_passwd_lock_depth == 0)
|
|
fclose(mach_passwd_fp);
|
|
return ret;
|
|
}
|
|
|
|
/************************************************************************
|
|
Routine to delete the trust account password file for a domain.
|
|
************************************************************************/
|
|
|
|
BOOL trust_password_delete( char *domain, char *name )
|
|
{
|
|
pstring mac_file;
|
|
|
|
get_trust_account_file_name( domain, name, mac_file);
|
|
return (unlink( mac_file ) == 0);
|
|
}
|
|
|
|
/************************************************************************
|
|
Routine to get the trust account password for a domain.
|
|
The user of this function must have locked the trust password file.
|
|
************************************************************************/
|
|
|
|
BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_time)
|
|
{
|
|
char linebuf[256];
|
|
char *p;
|
|
int i;
|
|
|
|
linebuf[0] = '\0';
|
|
|
|
*pass_last_set_time = (time_t)0;
|
|
memset(ret_pwd, '\0', 16);
|
|
|
|
if(sys_fseek( mach_passwd_fp, (SMB_OFF_T)0, SEEK_SET) == -1) {
|
|
DEBUG(0,("get_trust_account_password: Failed to seek to start of file. Error was %s.\n",
|
|
strerror(errno) ));
|
|
return False;
|
|
}
|
|
|
|
fgets(linebuf, sizeof(linebuf), mach_passwd_fp);
|
|
if(ferror(mach_passwd_fp)) {
|
|
DEBUG(0,("get_trust_account_password: Failed to read password. Error was %s.\n",
|
|
strerror(errno) ));
|
|
return False;
|
|
}
|
|
|
|
if(linebuf[strlen(linebuf)-1] == '\n')
|
|
linebuf[strlen(linebuf)-1] = '\0';
|
|
|
|
/*
|
|
* The length of the line read
|
|
* must be 45 bytes ( <---XXXX 32 bytes-->:TLC-12345678
|
|
*/
|
|
|
|
if(strlen(linebuf) != 45) {
|
|
DEBUG(0,("get_trust_account_password: Malformed trust password file (wrong length \
|
|
- was %d, should be 45).\n", strlen(linebuf)));
|
|
#ifdef DEBUG_PASSWORD
|
|
DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
|
|
#endif
|
|
return False;
|
|
}
|
|
|
|
/*
|
|
* Get the hex password.
|
|
*/
|
|
|
|
if (!pdb_gethexpwd((char *)linebuf, (char *)ret_pwd) || linebuf[32] != ':' ||
|
|
strncmp(&linebuf[33], "TLC-", 4)) {
|
|
DEBUG(0,("get_trust_account_password: Malformed trust password file (incorrect format).\n"));
|
|
#ifdef DEBUG_PASSWORD
|
|
DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
|
|
#endif
|
|
return False;
|
|
}
|
|
|
|
/*
|
|
* Get the last changed time.
|
|
*/
|
|
p = &linebuf[37];
|
|
|
|
for(i = 0; i < 8; i++) {
|
|
if(p[i] == '\0' || !isxdigit((int)p[i])) {
|
|
DEBUG(0,("get_trust_account_password: Malformed trust password file (no timestamp).\n"));
|
|
#ifdef DEBUG_PASSWORD
|
|
DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
|
|
#endif
|
|
return False;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* p points at 8 characters of hex digits -
|
|
* read into a time_t as the seconds since
|
|
* 1970 that the password was last changed.
|
|
*/
|
|
|
|
*pass_last_set_time = (time_t)strtol(p, NULL, 16);
|
|
|
|
return True;
|
|
}
|
|
|
|
/************************************************************************
|
|
Routine to get the trust account password for a domain.
|
|
The user of this function must have locked the trust password file.
|
|
************************************************************************/
|
|
|
|
BOOL set_trust_account_password( unsigned char *md4_new_pwd)
|
|
{
|
|
char linebuf[64];
|
|
int i;
|
|
|
|
if(sys_fseek( mach_passwd_fp, (SMB_OFF_T)0, SEEK_SET) == -1) {
|
|
DEBUG(0,("set_trust_account_password: Failed to seek to start of file. Error was %s.\n",
|
|
strerror(errno) ));
|
|
return False;
|
|
}
|
|
|
|
for (i = 0; i < 16; i++)
|
|
slprintf(&linebuf[(i*2)], sizeof(linebuf) - (i*2) - 1, "%02X", md4_new_pwd[i]);
|
|
|
|
slprintf(&linebuf[32], 32, ":TLC-%08X\n", (unsigned)time(NULL));
|
|
|
|
if(fwrite( linebuf, 1, 46, mach_passwd_fp)!= 46) {
|
|
DEBUG(0,("set_trust_account_password: Failed to write file. Warning - the trust \
|
|
account is now invalid. Please recreate. Error was %s.\n", strerror(errno) ));
|
|
return False;
|
|
}
|
|
|
|
fflush(mach_passwd_fp);
|
|
return True;
|
|
}
|