mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
added secrets.tdb and changed storage of trust account password to use
it
This commit is contained in:
parent
1d3bd3c486
commit
88ad00b82a
@ -611,6 +611,7 @@ extern int errno;
|
||||
#include "hash.h"
|
||||
#include "trans2.h"
|
||||
#include "nterr.h"
|
||||
#include "secrets.h"
|
||||
|
||||
#ifdef HAVE_FNMATCH
|
||||
#include <fnmatch.h>
|
||||
|
@ -1561,6 +1561,13 @@ BOOL pdb_rid_is_user(uint32 rid);
|
||||
BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use);
|
||||
BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use);
|
||||
|
||||
/*The following definitions come from passdb/secrets.c */
|
||||
|
||||
BOOL secrets_init(void);
|
||||
void *secrets_fetch(char *key, size_t *size);
|
||||
BOOL secrets_store(char *key, void *data, size_t size);
|
||||
BOOL secrets_delete(char *key);
|
||||
|
||||
/*The following definitions come from passdb/smbpass.c */
|
||||
|
||||
char *format_new_smbpasswd_entry(struct smb_passwd *newpwd);
|
||||
@ -1577,12 +1584,9 @@ BOOL local_password_change(char *user_name, int local_flags,
|
||||
|
||||
BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth);
|
||||
BOOL pw_file_unlock(int fd, int *plock_depth);
|
||||
BOOL trust_password_lock( char *domain, char *name, BOOL update);
|
||||
BOOL trust_password_unlock(void);
|
||||
BOOL trust_password_delete( char *domain, char *name );
|
||||
BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_time);
|
||||
BOOL set_trust_account_password( unsigned char *md4_new_pwd);
|
||||
BOOL trust_get_passwd( unsigned char trust_passwd[16], char *domain, char *myname);
|
||||
BOOL trust_password_delete(char *domain);
|
||||
BOOL get_trust_account_password(char *domain, unsigned char *ret_pwd, time_t *pass_last_set_time);
|
||||
BOOL set_trust_account_password(char *domain, unsigned char *md4_new_pwd);
|
||||
|
||||
/*The following definitions come from printing/load.c */
|
||||
|
||||
|
11
source/include/secrets.h
Normal file
11
source/include/secrets.h
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
|
||||
#define SECRETS_MACHINE_ACCT_PASS "SECRETS/$MACHINE.ACC"
|
||||
#define SECRETS_SAM_SID "SAM/SAM_SID"
|
||||
|
||||
struct machine_acct_pass {
|
||||
uint8 hash[16];
|
||||
time_t mod_time;
|
||||
};
|
||||
|
@ -19,14 +19,11 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
BOOL global_machine_password_needs_changing = False;
|
||||
|
||||
/***************************************************************
|
||||
Lock an fd. Abandon after waitsecs seconds.
|
||||
****************************************************************/
|
||||
|
||||
BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
|
||||
{
|
||||
if (fd < 0)
|
||||
@ -48,7 +45,6 @@ BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
|
||||
/***************************************************************
|
||||
Unlock an fd. Abandon after waitsecs seconds.
|
||||
****************************************************************/
|
||||
|
||||
BOOL pw_file_unlock(int fd, int *plock_depth)
|
||||
{
|
||||
BOOL ret=True;
|
||||
@ -65,247 +61,54 @@ BOOL pw_file_unlock(int fd, int *plock_depth)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mach_passwd_lock_depth;
|
||||
static FILE *mach_passwd_fp;
|
||||
|
||||
/************************************************************************
|
||||
Routine to get the name for a trust account file.
|
||||
form a key for fetching a domain trust password
|
||||
************************************************************************/
|
||||
|
||||
static void get_trust_account_file_name( char *domain, char *name, char *mac_file)
|
||||
static char *trust_keystr(char *domain)
|
||||
{
|
||||
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(!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;
|
||||
static fstring keystr;
|
||||
slprintf(keystr,sizeof(keystr),"%s/%s", SECRETS_MACHINE_ACCT_PASS, domain);
|
||||
return keystr;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
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 )
|
||||
BOOL trust_password_delete(char *domain)
|
||||
{
|
||||
pstring mac_file;
|
||||
|
||||
get_trust_account_file_name( domain, name, mac_file);
|
||||
return (unlink( mac_file ) == 0);
|
||||
return secrets_delete(trust_keystr(domain));
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
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)
|
||||
BOOL get_trust_account_password(char *domain, unsigned char *ret_pwd, time_t *pass_last_set_time)
|
||||
{
|
||||
char linebuf[256];
|
||||
char *p;
|
||||
int i;
|
||||
struct machine_acct_pass *pass;
|
||||
size_t size;
|
||||
|
||||
linebuf[0] = '\0';
|
||||
if (!(pass = secrets_fetch(trust_keystr(domain), &size)) ||
|
||||
size != sizeof(*pass)) return False;
|
||||
|
||||
*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", (int)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, 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;
|
||||
if (pass_last_set_time) *pass_last_set_time = pass->mod_time;
|
||||
memcpy(ret_pwd, pass->hash, 16);
|
||||
free(pass);
|
||||
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)
|
||||
BOOL set_trust_account_password(char *domain, unsigned char *md4_new_pwd)
|
||||
{
|
||||
char linebuf[64];
|
||||
int i;
|
||||
struct machine_acct_pass pass;
|
||||
|
||||
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;
|
||||
}
|
||||
pass.mod_time = time(NULL);
|
||||
memcpy(pass.hash, md4_new_pwd, 16);
|
||||
|
||||
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 machine account password.
|
||||
*/
|
||||
if(!trust_password_lock( domain, myname, False)) {
|
||||
DEBUG(0,("domain_client_validate: unable to open the machine account password file for \
|
||||
machine %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 machine account password for \
|
||||
machine %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 machine
|
||||
* password needs changing. JRA.
|
||||
*/
|
||||
|
||||
if(time(NULL) > lct + lp_machine_password_timeout())
|
||||
{
|
||||
global_machine_password_needs_changing = True;
|
||||
}
|
||||
return True;
|
||||
return secrets_store(trust_keystr(domain), (void *)&pass, sizeof(pass));
|
||||
}
|
||||
|
@ -629,7 +629,7 @@ BOOL change_trust_account_password( char *domain, char *remote_machine_list)
|
||||
time_t lct;
|
||||
BOOL res = False;
|
||||
|
||||
if(!get_trust_account_password( old_trust_passwd_hash, &lct)) {
|
||||
if(!get_trust_account_password(domain, old_trust_passwd_hash, &lct)) {
|
||||
DEBUG(0,("change_trust_account_password: unable to read the machine \
|
||||
account password for domain %s.\n", domain));
|
||||
return False;
|
||||
@ -686,7 +686,7 @@ domain %s.\n", timestring(False), domain));
|
||||
* Return the result of trying to write the new password
|
||||
* back into the trust account file.
|
||||
*/
|
||||
res = set_trust_account_password(new_trust_passwd_hash);
|
||||
res = set_trust_account_password(domain, new_trust_passwd_hash);
|
||||
memset(new_trust_passwd_hash, 0, 16);
|
||||
memset(old_trust_passwd_hash, 0, 16);
|
||||
return res;
|
||||
|
@ -79,7 +79,8 @@ void cmd_netlogon_login_test(struct client_info *info)
|
||||
|
||||
DEBUG(5,("do_nt_login_test: username %s\n", nt_user_name));
|
||||
|
||||
res = res ? trust_get_passwd(trust_passwd, smb_cli->domain, info->myhostname) : False;
|
||||
res = res ? get_trust_account_password(smb_cli->domain,
|
||||
trust_passwd, NULL) : False;
|
||||
|
||||
#if 0
|
||||
/* check whether the user wants to change their machine password */
|
||||
@ -101,7 +102,8 @@ void cmd_netlogon_login_test(struct client_info *info)
|
||||
|
||||
if (res)
|
||||
{
|
||||
global_machine_password_needs_changing = !set_trust_account_password(new_trust_passwd);
|
||||
global_machine_password_needs_changing = !set_trust_account_password(smb_cli->domain,
|
||||
new_trust_passwd);
|
||||
}
|
||||
|
||||
memset(new_trust_passwd, 0, 16);
|
||||
|
@ -1435,7 +1435,7 @@ BOOL domain_client_validate( char *user, char *domain,
|
||||
/*
|
||||
* Get the machine account password.
|
||||
*/
|
||||
if (!trust_get_passwd( trust_passwd, global_myworkgroup, global_myname))
|
||||
if (!get_trust_account_password(domain, trust_passwd, NULL))
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
@ -920,16 +920,9 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
|
||||
* First, open the machine password file with an exclusive lock.
|
||||
*/
|
||||
|
||||
if(!trust_password_lock( global_myworkgroup, global_myname, True)) {
|
||||
DEBUG(0,("process: unable to open the machine account password file for \
|
||||
machine %s in domain %s.\n", global_myname, global_myworkgroup ));
|
||||
return True;
|
||||
}
|
||||
|
||||
if(!get_trust_account_password( trust_passwd_hash, &lct)) {
|
||||
if(!get_trust_account_password(global_myworkgroup, trust_passwd_hash, &lct)) {
|
||||
DEBUG(0,("process: unable to read the machine account password for \
|
||||
machine %s in domain %s.\n", global_myname, global_myworkgroup ));
|
||||
trust_password_unlock();
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -938,7 +931,6 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup ));
|
||||
*/
|
||||
|
||||
if(t < lct + lp_machine_password_timeout()) {
|
||||
trust_password_unlock();
|
||||
global_machine_password_needs_changing = False;
|
||||
return True;
|
||||
}
|
||||
@ -946,7 +938,6 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup ));
|
||||
pstrcpy(remote_machine_list, lp_passwordserver());
|
||||
|
||||
change_trust_account_password( global_myworkgroup, remote_machine_list);
|
||||
trust_password_unlock();
|
||||
global_machine_password_needs_changing = False;
|
||||
}
|
||||
|
||||
|
@ -838,14 +838,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
|
||||
|
||||
strlower(user);
|
||||
|
||||
/*
|
||||
* In share level security, only overwrite sesssetup_use if
|
||||
* it's a non null-session share. Helps keep %U and %G
|
||||
* working.
|
||||
*/
|
||||
|
||||
if((lp_security() != SEC_SHARE) || (*user && !guest))
|
||||
pstrcpy(sesssetup_user,user);
|
||||
pstrcpy(sesssetup_user,user);
|
||||
|
||||
reload_services(True);
|
||||
|
||||
|
@ -498,6 +498,8 @@ static void init_structs(void )
|
||||
init_printer_hnd();
|
||||
|
||||
init_dptrs();
|
||||
|
||||
secrets_init();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -96,23 +96,13 @@ static int join_domain(char *domain, char *remote)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the machine account password file.
|
||||
*/
|
||||
if(!trust_password_lock( domain, global_myname, True)) {
|
||||
fprintf(stderr, "Unable to open the machine account password file for \
|
||||
machine %s in domain %s.\n", global_myname, domain);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the old machine account password.
|
||||
*/
|
||||
|
||||
if(!set_trust_account_password( orig_trust_passwd_hash)) {
|
||||
if(!set_trust_account_password(domain, orig_trust_passwd_hash)) {
|
||||
fprintf(stderr, "Unable to write the machine account password for \
|
||||
machine %s in domain %s.\n", global_myname, domain);
|
||||
trust_password_unlock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -127,15 +117,13 @@ machine %s in domain %s.\n", global_myname, domain);
|
||||
if(!*remote_machine) {
|
||||
fprintf(stderr, "No password server list given in smb.conf - \
|
||||
unable to join domain.\n");
|
||||
trust_password_unlock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = change_trust_account_password( domain, remote_machine);
|
||||
trust_password_unlock();
|
||||
|
||||
if(!ret) {
|
||||
trust_password_delete( domain, global_myname);
|
||||
trust_password_delete(domain);
|
||||
fprintf(stderr,"Unable to join domain %s.\n",domain);
|
||||
} else {
|
||||
printf("Joined domain %s.\n",domain);
|
||||
@ -579,6 +567,7 @@ int main(int argc, char **argv)
|
||||
codepage_initialise(lp_client_code_page());
|
||||
|
||||
load_interfaces();
|
||||
secrets_init();
|
||||
|
||||
/* Check the effective uid - make sure we are not setuid */
|
||||
if ((geteuid() == (uid_t)0) && (getuid() != (uid_t)0)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user