#include "includes.h"
-#if HAVE_UTMP_H
-# include <utmp.h>
-#endif
-#if HAVE_UTMPX_H
-# include <utmpx.h>
-#endif
-#if HAVE_LASTLOG_H
-# include <lastlog.h>
-#endif
-
#include "ssh.h"
#include "xmalloc.h"
#include "loginrec.h"
struct logininfo *
login_get_lastlog(struct logininfo *li, const int uid)
{
-#ifndef USE_LASTLOG
struct passwd *pw;
-#endif
memset(li, '\0', sizeof(struct logininfo));
li->uid = uid;
-#ifndef USE_LASTLOG
- /* If we don't have a 'real' lastlog, we need the username to
+ /*
+ * If we don't have a 'real' lastlog, we need the username to
* reliably search wtmp(x) for the last login (see
- * wtmp_get_entry().) */
+ * wtmp_get_entry().)
+ */
pw = getpwuid(uid);
if (pw == NULL)
fatal("login_get_lastlog: Cannot find account for uid %i", uid);
/* No MIN_SIZEOF here - we absolutely *must not* truncate the
* username */
strlcpy(li->username, pw->pw_name, sizeof(li->username));
-#endif
if (getlast_entry(li))
return li;
getlast_entry(struct logininfo *li)
{
#ifdef USE_LASTLOG
- if (lastlog_get_entry(li))
- return 1;
- else
- return 0;
+ return(lastlog_get_entry(li));
#else /* !USE_LASTLOG */
#ifdef DISABLE_LASTLOG
memset(dst, '\0', dstsize);
+ /* Always skip prefix if present */
+ if (strncmp(src, "/dev/", 5) == 0)
+ src += 5;
+
len = strlen(src);
- if (len <= 0) {
- src += (len - dstsize);
- strncpy(dst, src, dstsize); /* note: _don't_ change this to strlcpy */
+ if (len > 0) {
+ if (((int)len - dstsize) > 0)
+ src += ((int)len - dstsize);
+
+ /* note: _don't_ change this to strlcpy */
+ strncpy(dst, src, (size_t)dstsize);
}
return dst;
*/
/* Use strncpy because we don't necessarily want null termination */
- strncpy(ut->ut_user, li->username, MIN_SIZEOF(ut->ut_user, li->username));
+ strncpy(ut->ut_name, li->username, MIN_SIZEOF(ut->ut_name, li->username));
# ifdef HAVE_HOST_IN_UTMP
strncpy(ut->ut_host, li->hostname, MIN_SIZEOF(ut->ut_host, li->hostname));
# endif
construct_utmpx(struct logininfo *li, struct utmpx *utx)
{
memset(utx, '\0', sizeof(struct utmpx));
+# ifdef HAVE_ID_IN_UTMPX
line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id));
+# endif
/* this is done here to keep utmp constants out of loginrec.h */
switch (li->type) {
* If the new ut_line is empty but the old one is not
* and ut_line and ut_name match, preserve the old ut_line.
*/
- if ( read(fd, &old_ut, sizeof(struct utmp)) == sizeof(struct utmp)
- && ut->ut_host[0] == '\0'
- && old_ut.ut_host[0] != '\0'
- && strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0
- && strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0 )
+ if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) &&
+ (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') &&
+ (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) &&
+ (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) {
(void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host));
-
+ }
+
(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
- if (write(fd, ut, sizeof(struct utmp))==-1)
+ if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut))
log("utmp_write_direct: error writing %s: %s",
UTMP_FILE, strerror(errno));
(void)close(fd);
return 1;
- } else
+ } else {
return 0;
+ }
}
# endif /* UTMP_USE_LIBRARY */
return 0;
}
if (fstat(fd, &buf) == 0)
- if (write(fd, (char *)ut, sizeof(struct utmp)) !=
- sizeof(struct utmp)) {
+ if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) {
ftruncate(fd, buf.st_size);
log("wtmp_write: problem writing %s: %s",
WTMP_FILE, strerror(errno));
static int
wtmp_islogin(struct logininfo *li, struct utmp *ut)
{
- if (strncmp(li->username, ut->ut_user,
- MIN_SIZEOF(li->username, ut->ut_user)) == 0) {
+ if (strncmp(li->username, ut->ut_name,
+ MIN_SIZEOF(li->username, ut->ut_name)) == 0) {
# ifdef HAVE_TYPE_IN_UTMP
if (ut->ut_type & USER_PROCESS)
return 1;
}
while (!found) {
- if (read(fd, &ut, sizeof(ut)) != sizeof(ut)) {
+ if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) {
log("wtmp_get_entry: read of %s failed: %s",
WTMP_FILE, strerror(errno));
close (fd);
}
if (fstat(fd, &buf) == 0)
- if (write(fd, (char *)utx, sizeof(struct utmpx)) !=
- sizeof(struct utmpx)) {
+ if (atomicio(write, fd, utx, sizeof(*utx)) != sizeof(*utx)) {
ftruncate(fd, buf.st_size);
log("wtmpx_write: problem writing %s: %s",
WTMPX_FILE, strerror(errno));
static int
wtmpx_islogin(struct logininfo *li, struct utmpx *utx)
{
- if ( strncmp(li->username, utx->ut_user,
- MIN_SIZEOF(li->username, utx->ut_user)) == 0 ) {
+ if ( strncmp(li->username, utx->ut_name,
+ MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) {
# ifdef HAVE_TYPE_IN_UTMPX
if (utx->ut_type == USER_PROCESS)
return 1;
}
while (!found) {
- if (read(fd, &utx, sizeof(utx)) != sizeof(utx)) {
+ if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) {
log("wtmpx_get_entry: read of %s failed: %s",
WTMPX_FILE, strerror(errno));
close (fd);
# ifdef HAVE_LOGWTMP
} else {
logwtmp(line, "", "");
- }
# endif
+ }
/* FIXME: (ATL - if the need arises) What to do if we have
* login, but no logout? what if logout but no logwtmp? All
* routines are in libutil so they should all be there,
*fd = open(lastlog_file, filemode);
if ( *fd < 0) {
- log("lastlog_openseek: Couldn't open %s: %s",
+ debug("lastlog_openseek: Couldn't open %s: %s",
lastlog_file, strerror(errno));
return 0;
}
lastlog_construct(li, &last);
/* write the entry */
- if (lastlog_openseek(li, &fd, O_RDWR)) {
- if (write(fd, &last, sizeof(struct lastlog)) !=
- sizeof(struct lastlog)) {
+ if (lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) {
+ if (atomicio(write, fd, &last, sizeof(last)) != sizeof(last)) {
log("lastlog_write_filemode: Error writing to %s: %s",
LASTLOG_FILE, strerror(errno));
return 0;
int fd;
if (lastlog_openseek(li, &fd, O_RDONLY)) {
- if ( read(fd, &last, sizeof(struct lastlog)) !=
- sizeof(struct lastlog) ) {
- log("lastlog_write_filemode: Error reading from %s: %s",
+ if (atomicio(read, fd, &last, sizeof(last)) != sizeof(last)) {
+ log("lastlog_get_entry: Error reading from %s: %s",
LASTLOG_FILE, strerror(errno));
return 0;
} else {