summaryrefslogtreecommitdiff
path: root/source3/utils/smbpasswd.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/utils/smbpasswd.c')
-rw-r--r--source3/utils/smbpasswd.c89
1 files changed, 46 insertions, 43 deletions
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",