summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h1
-rw-r--r--source3/include/smb.h1
-rw-r--r--source3/lib/util.c5
-rw-r--r--source3/nmbd/nmbd.c2
-rw-r--r--source3/passdb/smbpass.c137
-rw-r--r--source3/smbd/ipc.c3
-rw-r--r--source3/utils/smbpasswd.c89
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",