From 2958dfcdf87d5169fe1152806be6ad03acb04d88 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 8 May 2000 10:42:21 +0000 Subject: added secrets.tdb and changed storage of trust account password to use it (This used to be commit 88ad00b82acc4636ab57dfe710af08ea85b82ff1) --- source3/include/includes.h | 1 + source3/include/proto.h | 16 ++- source3/include/secrets.h | 11 ++ source3/passdb/smbpassfile.c | 241 ++++---------------------------------- source3/rpc_client/cli_netlogon.c | 4 +- source3/rpcclient/cmd_netlogon.c | 6 +- source3/smbd/password.c | 2 +- source3/smbd/process.c | 11 +- source3/smbd/reply.c | 9 +- source3/smbd/server.c | 2 + source3/utils/smbpasswd.c | 17 +-- 11 files changed, 58 insertions(+), 262 deletions(-) create mode 100644 source3/include/secrets.h diff --git a/source3/include/includes.h b/source3/include/includes.h index bb5d8192cb..68872f39f0 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -611,6 +611,7 @@ extern int errno; #include "hash.h" #include "trans2.h" #include "nterr.h" +#include "secrets.h" #ifdef HAVE_FNMATCH #include diff --git a/source3/include/proto.h b/source3/include/proto.h index 146775bd2a..b19eb7e662 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.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 */ diff --git a/source3/include/secrets.h b/source3/include/secrets.h new file mode 100644 index 0000000000..a87bdef56b --- /dev/null +++ b/source3/include/secrets.h @@ -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; +}; + diff --git a/source3/passdb/smbpassfile.c b/source3/passdb/smbpassfile.c index bbe24131b8..035da2a4cf 100644 --- a/source3/passdb/smbpassfile.c +++ b/source3/passdb/smbpassfile.c @@ -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)); } diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index dab4aa7ad5..ce4468d112 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -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; diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index 944eda86b7..639453b4d7 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -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); diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 782d04631a..0478e205d1 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -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; } diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 6482ccd538..805bbe4415 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -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; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 90d4200f5e..7a818971d9 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -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); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 574be64553..d2ccd75059 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -498,6 +498,8 @@ static void init_structs(void ) init_printer_hnd(); init_dptrs(); + + secrets_init(); } /**************************************************************************** diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index 7a0d0eeea9..047a69419c 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -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)) { -- cgit