diff options
-rw-r--r-- | source3/include/proto.h | 1 | ||||
-rw-r--r-- | source3/include/smb.h | 1 | ||||
-rw-r--r-- | source3/lib/util.c | 5 | ||||
-rw-r--r-- | source3/nmbd/nmbd.c | 2 | ||||
-rw-r--r-- | source3/passdb/smbpass.c | 137 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 3 | ||||
-rw-r--r-- | source3/utils/smbpasswd.c | 89 |
7 files changed, 187 insertions, 51 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 07df90e1bd..c5c7c1e846 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1697,6 +1697,7 @@ unsigned long getsmbpwpos(void *vp); BOOL setsmbpwpos(void *vp, unsigned long tok); struct smb_passwd *getsmbpwnam(char *name); struct smb_passwd *getsmbpwuid(unsigned int uid); +char *encode_acct_ctrl(uint16 acct_ctrl); BOOL add_smbpwd_entry(struct smb_passwd *newpwd); BOOL mod_smbpwd_entry(struct smb_passwd* pwd); diff --git a/source3/include/smb.h b/source3/include/smb.h index 95521217e9..46e282b2ba 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -287,6 +287,7 @@ struct smb_passwd unsigned char *smb_nt_passwd; /* Null if no password */ /* Other fields / flags may be added later */ uint16 acct_ctrl; + time_t last_change_time; }; struct cli_state { diff --git a/source3/lib/util.c b/source3/lib/util.c index 2990a336c5..54bbdfa30a 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -270,7 +270,10 @@ va_dcl { if (!dbf) { int oldumask = umask(022); - dbf = fopen(debugf,"w"); + if(append_log) + dbf = fopen(debugf,"a"); + else + dbf = fopen(debugf,"w"); umask(oldumask); if (dbf) { setbuf(dbf,NULL); diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 8373997e64..5de1d3291d 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -653,6 +653,8 @@ int main(int argc,char *argv[]) } } + reopen_logs(); + DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION)); DEBUG(1,("Copyright Andrew Tridgell 1994-1997\n")); diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c index 58029a1b61..e504607eb6 100644 --- a/source3/passdb/smbpass.c +++ b/source3/passdb/smbpass.c @@ -192,6 +192,7 @@ struct smb_passwd *getsmbpwent(void *vp) } pw_buf.acct_ctrl = ACB_NORMAL; + pw_buf.last_change_time = (time_t)-1; /* * Scan the file, a line at a time and check if the name matches. @@ -229,14 +230,16 @@ struct smb_passwd *getsmbpwent(void *vp) /* * The line we have should be of the form :- * - * username:uid:[32hex bytes]:....other flags presently + * username:uid:32hex bytes:[Account type]:LCT-12345678....other flags presently * ignored.... * * or, * - * username:uid:[32hex bytes]:[32hex bytes]:....ignored.... + * username:uid:32hex bytes:32hex bytes:[Account type]:LCT-12345678....ignored.... * * if Windows NT compatible passwords are also present. + * [Account type] is an ascii encoding of the type of account. + * LCT-(8 hex digits) is the time_t value of the last change time. */ if (linebuf[0] == '#' || linebuf[0] == '\0') { @@ -412,6 +415,28 @@ struct smb_passwd *getsmbpwent(void *vp) if(pw_buf.acct_ctrl == 0) pw_buf.acct_ctrl = ACB_NORMAL; + /* Now try and get the last change time. */ + if(*p == ']') + p++; + if(*p == ':') { + p++; + if(*p && StrnCaseCmp( p, "LCT-", 4)) { + int i; + p += 4; + for(i = 0; i < 8; i++) { + if(p[i] == '\0' || !isxdigit(p[i])) + break; + } + if(i == 8) { + /* + * p points at 8 characters of hex digits - + * read into a time_t as the seconds since + * 1970 that the password was last changed. + */ + pw_buf.last_change_time = (time_t)strtol(p, NULL, 16); + } + } + } } else { /* 'Old' style file. Fake up based on user name. */ /* @@ -519,6 +544,41 @@ struct smb_passwd *getsmbpwuid(unsigned int uid) return get_smbpwd_entry(NULL, uid); } +/********************************************************** + Encode the account control bits into a string. +**********************************************************/ + +char *encode_acct_ctrl(uint16 acct_ctrl) +{ + static fstring acct_str; + char *p = acct_str; + + *p++ = '['; + + if(acct_ctrl & ACB_HOMDIRREQ) + *p++ = 'H'; + if(acct_ctrl & ACB_TEMPDUP) + *p++ = 'T'; + if(acct_ctrl & ACB_NORMAL) + *p++ = 'U'; + if(acct_ctrl & ACB_MNS) + *p++ = 'M'; + if(acct_ctrl & ACB_WSTRUST) + *p++ = 'W'; + if(acct_ctrl & ACB_SVRTRUST) + *p++ = 'S'; + if(acct_ctrl & ACB_AUTOLOCK) + *p++ = 'L'; + if(acct_ctrl & ACB_PWNOEXP) + *p++ = 'X'; + if(acct_ctrl & ACB_DOMTRUST) + *p++ = 'I'; + + *p++ = ']'; + *p = '\0'; + return acct_str; +} + /************************************************************************ Routine to add an entry to the smbpasswd file. *************************************************************************/ @@ -574,7 +634,7 @@ Error was %s\n", pwd->smb_name, pfile, strerror(errno))); return False; } - new_entry_length = strlen(pwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + 2; + new_entry_length = strlen(pwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + 5 + 1 + 13 + 2; if((new_entry = (char *)malloc( new_entry_length )) == NULL) { DEBUG(0, ("add_smbpwd_entry(malloc): Failed to add entry for user %s to file %s. \ @@ -600,10 +660,13 @@ Error was %s\n", pwd->smb_name, pfile, strerror(errno))); p += 32; *p++ = ':'; - sprintf((char *)p,"\n"); + + /* Add the account encoding and the last change time. */ + sprintf((char *)p, "%s:LCT-%08X:\n", encode_acct_ctrl(pwd->acct_ctrl), + (uint32)time(NULL)); #ifdef DEBUG_PASSWORD - DEBUG(100, ("add_smbpwd_entry(%d): new_entry_len %d entry_len %d made line |%s|\n", + DEBUG(100, ("add_smbpwd_entry(%d): new_entry_len %d entry_len %d made line |%s|", fd, new_entry_length, strlen(new_entry), new_entry)); #endif @@ -641,13 +704,15 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd) char linebuf[256]; char readbuf[16 * 1024]; unsigned char c; - char ascii_p16[66]; + fstring ascii_p16; + fstring encode_bits; unsigned char *p = NULL; long linebuf_len = 0; FILE *fp; int lockfd; char *pfile = lp_smb_passwd_file(); BOOL found_entry = False; + BOOL got_last_change_time = False; long pwd_seekpos = 0; @@ -837,6 +902,55 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd) return False; } + /* + * Now check if the account info and the password last + * change time is available. + */ + p += 33; /* Move to the first character of the line after + the NT password. */ + + if (*p == '[') { + + /* + * Note that here we are assuming that the account + * info in the pwd struct matches the account info + * here in the file. It better..... JRA. + */ + + i = 0; + p++; + while((linebuf_len > PTR_DIFF(p, linebuf)) && (*p != ']')) + encode_bits[i++] = *p++; + + encode_bits[i] = '\0'; + + /* Go past the ']' */ + if(linebuf_len > PTR_DIFF(p, linebuf)) + p++; + + if((linebuf_len > PTR_DIFF(p, linebuf)) && (*p == ':')) { + p++; + + /* We should be pointing at the TLC entry. */ + if((linebuf_len > (PTR_DIFF(p, linebuf) + 13)) && StrnCaseCmp( p, "LCT-", 4)) { + + p += 4; + for(i = 0; i < 8; i++) { + if(p[i] == '\0' || !isxdigit(p[i])) + break; + } + if(i == 8) { + /* + * p points at 8 characters of hex digits - + * read into a time_t as the seconds since + * 1970 that the password was last changed. + */ + got_last_change_time = True; + } /* i == 8 */ + } /* *p && StrnCaseCmp() */ + } /* p == ':' */ + } /* p == '[' */ + /* Entry is correctly formed. */ /* @@ -889,6 +1003,17 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd) strcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); } + /* Add on the account info bits and the time of last + password change. */ + + pwd->last_change_time = time(NULL); + + if(got_last_change_time) { + sprintf(&ascii_p16[strlen(ascii_p16)], ":[%s]:TLC-%08X", + encode_bits, (uint32)pwd->last_change_time ); + wr_len = strlen(ascii_p16); + } + #ifdef DEBUG_PASSWORD DEBUG(100,("mod_smbpwd_entry: ")); dump_data(100, ascii_p16, wr_len); diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index e4ddcbec69..7cf4d6f5b8 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -330,8 +330,9 @@ static BOOL init_package(struct pack_desc* p, int count, int subcount) p->subcount = 0; p->curpos = p->format; if (i > n) { + p->neededlen = i; i = n = 0; - p->errcode = NERR_BufTooSmall; + p->errcode = ERROR_MORE_DATA; } else p->errcode = NERR_Success; diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index b569ba96b3..ca59ae52e9 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -106,7 +106,7 @@ static int gethexpwd(char *p, char *pwd) static struct smb_passwd * _my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd, - BOOL *got_valid_nt_entry, long *pwd_seekpos) + BOOL *got_valid_nt_entry, BOOL *got_valid_last_change_time, long *pwd_seekpos) { /* Static buffers we will return. */ static struct smb_passwd pw_buf; @@ -121,6 +121,9 @@ _my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd, long linebuf_len; pw_buf.acct_ctrl = ACB_NORMAL; + *got_valid_last_change_time = False; + *got_valid_nt_entry = False; + *valid_old_pwd = False; /* * Scan the file, a line at a time and check if the name matches. @@ -337,7 +340,31 @@ _my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd, /* Must have some account type set. */ if(pw_buf.acct_ctrl == 0) pw_buf.acct_ctrl = ACB_NORMAL; - + + /* Now try and get the last change time. */ + if(*p == ']') + p++; + if(*p == ':') { + p++; + if(*p && StrnCaseCmp( p, "LCT-", 4)) { + int i; + p += 4; + for(i = 0; i < 8; i++) { + if(p[i] == '\0' || !isxdigit(p[i])) + break; + } + if(i == 8) { + /* + * p points at 8 characters of hex digits - + * read into a time_t as the seconds since + * 1970 that the password was last changed. + */ + pw_buf.last_change_time = (time_t)strtol(p, NULL, 16); + *got_valid_last_change_time = True; + } /* i == 8 */ + } /* *p && StrnCaseCmp() */ + } /* *p == ':' */ + } else { /* 'Old' style file. Fake up based on user name. */ /* @@ -356,41 +383,6 @@ _my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd, } /********************************************************** - Encode the account control bits into a string. -**********************************************************/ - -char *encode_acct_ctrl(uint16 acct_ctrl) -{ - static fstring acct_str; - char *p = acct_str; - - *p++ = '['; - - if(acct_ctrl & ACB_HOMDIRREQ) - *p++ = 'H'; - if(acct_ctrl & ACB_TEMPDUP) - *p++ = 'T'; - if(acct_ctrl & ACB_NORMAL) - *p++ = 'U'; - if(acct_ctrl & ACB_MNS) - *p++ = 'M'; - if(acct_ctrl & ACB_WSTRUST) - *p++ = 'W'; - if(acct_ctrl & ACB_SVRTRUST) - *p++ = 'S'; - if(acct_ctrl & ACB_AUTOLOCK) - *p++ = 'L'; - if(acct_ctrl & ACB_PWNOEXP) - *p++ = 'X'; - if(acct_ctrl & ACB_DOMTRUST) - *p++ = 'I'; - - *p++ = ']'; - *p = '\0'; - return acct_str; -} - -/********************************************************** Allocate an unused uid in the smbpasswd file to a new machine account. ***********************************************************/ @@ -454,7 +446,7 @@ int main(int argc, char **argv) BOOL got_valid_nt_entry = False; long seekpos; int pwfd; - char ascii_p16[66]; + pstring ascii_p16; char c; int ch; int ret, i, err, writelen; @@ -467,6 +459,7 @@ int main(int argc, char **argv) char *remote_machine = NULL; BOOL add_user = False; BOOL got_new_pass = False; + BOOL got_valid_last_change_time = False; BOOL machine_account = False; BOOL disable_user = False; BOOL set_no_password = False; @@ -833,7 +826,7 @@ int main(int argc, char **argv) /* Get the smb passwd entry for this user */ smb_pwent = _my_get_smbpwnam(fp, user_name, &valid_old_pwd, - &got_valid_nt_entry, &seekpos); + &got_valid_nt_entry, &got_valid_last_change_time, &seekpos); if (smb_pwent == NULL) { if(add_user == False) { fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n", @@ -866,6 +859,7 @@ Error was %s\n", prog_name, user_name, pfile, strerror(errno)); new_entry_length = strlen(user_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + sizeof(fstring) + + 1 + 13 + 1 + strlen(pwd->pw_dir) + 1 + strlen(pwd->pw_shell) + 1; if((new_entry = (char *)malloc( new_entry_length )) == 0) { @@ -898,8 +892,8 @@ Error was %s\n", prog_name, pwd->pw_name, pfile, strerror(errno)); } p += 32; *p++ = ':'; - sprintf(p, "%s:%s:%s\n", encode_acct_ctrl(acct_ctrl), - pwd->pw_dir, pwd->pw_shell); + sprintf(p, "%s:TLC-%08X:%s:%s\n", encode_acct_ctrl(acct_ctrl), + (uint32)time(NULL), pwd->pw_dir, pwd->pw_shell); if(write(fd, new_entry, strlen(new_entry)) != strlen(new_entry)) { fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \ Error was %s\n", prog_name, pwd->pw_name, pfile, strerror(errno)); @@ -924,7 +918,8 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n", } /* - * We are root - just write the new password. + * We are root - just write the new password + * and the valid last change time. */ /* Create the 32 byte representation of the new p16 */ @@ -950,6 +945,13 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n", } } } + ascii_p16[65] = ':'; + ascii_p16[66] = '\0'; + if(got_valid_last_change_time) { + strcpy(&ascii_p16[66], encode_acct_ctrl(smb_pwent->acct_ctrl)); + sprintf(&ascii_p16[strlen(ascii_p16)], ":TLC-%08X", (uint32)time(NULL)); + } + /* * Do an atomic write into the file at the position defined by * seekpos. @@ -984,7 +986,8 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n", fclose(fp); exit(1); } - writelen = (got_valid_nt_entry) ? 65 : 32; + writelen = (got_valid_nt_entry) ? + ( got_valid_last_change_time ? strlen(ascii_p16) : 65) : 32; if (write(pwfd, ascii_p16, writelen) != writelen) { err = errno; fprintf(stderr, "%s: write fail in file %s.\n", |