1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-15 23:24:37 +03:00
samba-mirror/source/passdb/smbpassfile.c
Luke Leighton 2e58ed7424 SAM database "set user info".
----------------------------

- removed DOM_RID4

- removed SAMR_UNKNOWN_32

- added SAMR_SET_USERINFO (opcode 0x32)

- added level 0x1 to SAMR_QUERY_DOM_INFO (needed for create user)

- fixed pwdb_gethexpwd() it was failing on XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

- added mod_sam21pwd_entry()

- preparing to call mod_sam21pwd_entry()

- added "user session key" to user_struct.dc.  this is md4(nt#) and is
  needed to decode user's clear-text passwords in SAMR_SET_USERINFO.

- split code out in chgpasswd.c to decode 516 byte password buffers.
-

269 lines
7.8 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;
BOOL global_machine_password_needs_changing = False;
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 = sys_fopen(mac_file, "r+b")) == NULL) {
if(errno == ENOENT && update) {
mach_passwd_fp = sys_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(!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 = 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 (!pwdb_gethexpwd((char *)linebuf, (char *)ret_pwd, NULL) || 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;
}
BOOL trust_get_passwd( unsigned char trust_passwd[16], char *domain, char *myname)
{
time_t lct;
/*
* Get the trust account password.
*/
if(!trust_password_lock( domain, myname, False)) {
DEBUG(0,("domain_client_validate: unable to open the trust account password file for \
trust %s in domain %s.\n", myname, domain ));
return False;
}
if(get_trust_account_password( trust_passwd, &lct) == False) {
DEBUG(0,("domain_client_validate: unable to read the trust account password for \
trust %s in domain %s.\n", myname, domain ));
trust_password_unlock();
return False;
}
trust_password_unlock();
/*
* Here we check the last change time to see if the trust
* password needs changing. JRA.
*/
if(time(NULL) > lct + lp_machine_password_timeout())
{
global_machine_password_needs_changing = True;
}
return True;
}