version 1.7.2.1, 2004/08/19 22:37:33 |
version 1.8, 2004/06/21 17:36:31 |
|
|
#include <utmp.h> |
#include <utmp.h> |
#include "sshlogin.h" |
#include "sshlogin.h" |
#include "log.h" |
#include "log.h" |
#include "buffer.h" |
|
#include "servconf.h" |
|
|
|
extern Buffer loginmsg; |
|
extern ServerOptions options; |
|
|
|
/* |
/* |
* Returns the time when the user last logged in. Returns 0 if the |
* Returns the time when the user last logged in. Returns 0 if the |
* information is not available. This must be called before record_login. |
* information is not available. This must be called before record_login. |
|
|
struct lastlog ll; |
struct lastlog ll; |
char *lastlog; |
char *lastlog; |
int fd; |
int fd; |
off_t pos, r; |
|
|
|
lastlog = _PATH_LASTLOG; |
lastlog = _PATH_LASTLOG; |
buf[0] = '\0'; |
buf[0] = '\0'; |
|
|
fd = open(lastlog, O_RDONLY); |
fd = open(lastlog, O_RDONLY); |
if (fd < 0) |
if (fd < 0) |
return 0; |
return 0; |
|
lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); |
pos = (long) uid * sizeof(ll); |
|
r = lseek(fd, pos, SEEK_SET); |
|
if (r == -1) { |
|
error("%s: lseek: %s", __func__, strerror(errno)); |
|
return (0); |
|
} |
|
if (r != pos) { |
|
debug("%s: truncated lastlog", __func__); |
|
return (0); |
|
} |
|
if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) { |
if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) { |
close(fd); |
close(fd); |
return 0; |
return 0; |
|
|
if (bufsize > sizeof(ll.ll_host) + 1) |
if (bufsize > sizeof(ll.ll_host) + 1) |
bufsize = sizeof(ll.ll_host) + 1; |
bufsize = sizeof(ll.ll_host) + 1; |
strncpy(buf, ll.ll_host, bufsize - 1); |
strncpy(buf, ll.ll_host, bufsize - 1); |
buf[bufsize - 1] = '\0'; |
buf[bufsize - 1] = 0; |
return ll.ll_time; |
return ll.ll_time; |
} |
} |
|
|
/* |
/* |
* Generate and store last login message. This must be done before |
|
* login_login() is called and lastlog is updated. |
|
*/ |
|
static void |
|
store_lastlog_message(const char *user, uid_t uid) |
|
{ |
|
char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512]; |
|
time_t last_login_time; |
|
|
|
if (!options.print_lastlog) |
|
return; |
|
|
|
last_login_time = get_last_login_time(uid, user, hostname, |
|
sizeof(hostname)); |
|
|
|
if (last_login_time != 0) { |
|
time_string = ctime(&last_login_time); |
|
if (strchr(time_string, '\n')) |
|
*strchr(time_string, '\n') = '\0'; |
|
if (strcmp(hostname, "") == 0) |
|
snprintf(buf, sizeof(buf), "Last login: %s\r\n", |
|
time_string); |
|
else |
|
snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n", |
|
time_string, hostname); |
|
buffer_append(&loginmsg, buf, strlen(buf)); |
|
} |
|
} |
|
|
|
/* |
|
* Records that the user has logged in. I wish these parts of operating |
* Records that the user has logged in. I wish these parts of operating |
* systems were more standardized. |
* systems were more standardized. |
*/ |
*/ |
|
|
struct lastlog ll; |
struct lastlog ll; |
char *lastlog; |
char *lastlog; |
struct utmp u; |
struct utmp u; |
|
|
/* save previous login details before writing new */ |
|
store_lastlog_message(user, uid); |
|
|
|
/* Construct an utmp/wtmp entry. */ |
/* Construct an utmp/wtmp entry. */ |
memset(&u, 0, sizeof(u)); |
memset(&u, 0, sizeof(u)); |