/**
** TODO:
- ** homegrown ttyslot()q
+ ** homegrown ttyslot()
** test, test, test
**
** Platform status:
** ----------------
**
** Known good:
- ** Linux (Redhat 6.2, need more variants)
+ ** Linux (Redhat 6.2, Debian)
+ ** Solaris
** HP-UX 10.20 (gcc only)
** IRIX
+ ** NeXT - M68k/HPPA/Sparc (4.2/3.3)
**
** Testing required: Please send reports!
- ** Solaris
** NetBSD
** HP-UX 11
** AIX
**
** Platforms with known problems:
- ** NeXT
+ ** Some variants of Slackware Linux
**
**/
#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"
+#include "log.h"
+#include "atomicio.h"
RCSID("$Id$");
+#ifdef HAVE_UTIL_H
+# include <util.h>
+#endif
+
+#ifdef HAVE_LIBUTIL_H
+# include <libutil.h>
+#endif
+
/**
** prototypes for helper functions in this file
**/
{
struct passwd *pw;
- memset(li, '\0', sizeof(struct logininfo));
+ memset(li, '\0', sizeof(*li));
li->uid = uid;
/*
{
struct logininfo *newli;
- newli = (struct logininfo *) xmalloc (sizeof(struct logininfo));
+ newli = (struct logininfo *) xmalloc (sizeof(*newli));
(void)login_init_entry(newli, pid, username, hostname, line);
return newli;
}
{
struct passwd *pw;
- memset(li, 0, sizeof(struct logininfo));
+ memset(li, 0, sizeof(*li));
li->pid = pid;
int
login_write (struct logininfo *li)
{
+#ifndef HAVE_CYGWIN
if ((int)geteuid() != 0) {
log("Attempt to write login records by non-root user (aborting)");
return 1;
}
+#endif
/* set the timestamp */
login_set_current_time(li);
line_fullname(char *dst, const char *src, int dstsize)
{
memset(dst, '\0', dstsize);
- if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5)))
+ if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) {
strlcpy(dst, src, dstsize);
- else {
+ } else {
strlcpy(dst, "/dev/", dstsize);
strlcat(dst, src, dstsize);
}
{
memset(dst, '\0', dstsize);
if (strncmp(src, "/dev/", 5) == 0)
- strlcpy(dst, &src[5], dstsize);
+ strlcpy(dst, src + 5, dstsize);
else
strlcpy(dst, src, dstsize);
return dst;
memset(dst, '\0', dstsize);
/* Always skip prefix if present */
+#ifdef sgi
+ if (strncmp(src, "/dev/tty", 8) == 0)
+ src += 8;
+#else
if (strncmp(src, "/dev/", 5) == 0)
src += 5;
+#endif
len = strlen(src);
construct_utmp(struct logininfo *li,
struct utmp *ut)
{
- memset(ut, '\0', sizeof(struct utmp));
+ memset(ut, '\0', sizeof(*ut));
/* First fill out fields used for both logins and logouts */
*/
/* 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
void
construct_utmpx(struct logininfo *li, struct utmpx *utx)
{
- memset(utx, '\0', sizeof(struct utmpx));
+ memset(utx, '\0', sizeof(*utx));
# ifdef HAVE_ID_IN_UTMPX
line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id));
# endif
strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname));
# endif
# ifdef HAVE_ADDR_IN_UTMPX
- /* FIXME: (ATL) not supported yet */
+ /* this is just a 32-bit IP address */
+ if (li->hostaddr.sa.sa_family == AF_INET)
+ utx->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr;
# endif
# ifdef HAVE_SYSLEN_IN_UTMPX
/* ut_syslen is the length of the utx_host string */
int tty;
/* FIXME: (ATL) ttyslot() needs local implementation */
+
+#if defined(HAVE_GETTTYENT)
+ register struct ttyent *ty;
+
+ tty=0;
+
+ setttyent();
+ while ((struct ttyent *)0 != (ty = getttyent())) {
+ tty++;
+ if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line)))
+ break;
+ }
+ endttyent();
+
+ if((struct ttyent *)0 == ty) {
+ log("utmp_write_entry: tty not found");
+ return(1);
+ }
+#else /* FIXME */
+
tty = ttyslot(); /* seems only to work for /dev/ttyp? style names */
+#endif /* HAVE_GETTTYENT */
+
if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) {
(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
/*
}
(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
- if (atomicio(write, fd, ut, sizeof(ut)) != sizeof(ut))
+ if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut))
log("utmp_write_direct: error writing %s: %s",
UTMP_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;
}
/* Seek to the start of the last struct utmp */
- if (lseek(fd, (off_t)(0-sizeof(struct utmp)), SEEK_END) == -1) {
+ if (lseek(fd, (off_t)(0 - sizeof(struct utmp)), SEEK_END) == -1) {
/* Looks like we've got a fresh wtmp file */
close(fd);
return 0;
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;
{
struct utmp *ut;
- if (! (ut = (struct utmp *)malloc(sizeof(struct utmp)))) {
+ if (! (ut = (struct utmp *)malloc(sizeof(*ut)))) {
log("syslogin_perform_login: couldn't malloc()");
return 0;
}
lastlog_construct(struct logininfo *li, struct lastlog *last)
{
/* clear the structure */
- memset(last, '\0', sizeof(struct lastlog));
+ memset(last, '\0', sizeof(*last));
(void)line_stripname(last->ll_line, li->line, sizeof(last->ll_line));
strlcpy(last->ll_host, li->hostname,
return 0;
}
- /* find this uid's offset in the lastlog file */
- offset = (off_t) ( (long)li->uid * sizeof(struct lastlog));
+ if (type == LL_FILE) {
+ /* find this uid's offset in the lastlog file */
+ offset = (off_t) ( (long)li->uid * sizeof(struct lastlog));
- if ( lseek(*fd, offset, SEEK_SET) != offset ) {
- log("lastlog_openseek: %s->lseek(): %s",
- lastlog_file, strerror(errno));
- return 0;
+ if ( lseek(*fd, offset, SEEK_SET) != offset ) {
+ log("lastlog_openseek: %s->lseek(): %s",
+ lastlog_file, strerror(errno));
+ return 0;
+ }
}
+
return 1;
}
/* create our struct lastlog */
lastlog_construct(li, &last);
+ if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT))
+ return(0);
+
/* write the entry */
- 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;
- }
- return 1;
- } else {
+ if (atomicio(write, fd, &last, sizeof(last)) != sizeof(last)) {
+ close(fd);
+ log("lastlog_write_filemode: Error writing to %s: %s",
+ LASTLOG_FILE, strerror(errno));
return 0;
}
+
+ close(fd);
+ return 1;
}
int