* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Markus Friedl.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
{
#ifndef HAVE_CYGWIN
if ((int)geteuid() != 0) {
- logit("Attempt to write login records by non-root user (aborting)");
+ log("Attempt to write login records by non-root user (aborting)");
return 1;
}
#endif
#endif
#ifdef USE_WTMPX
wtmpx_write_entry(li);
-#endif
-#ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN
- if (li->type == LTYPE_LOGIN &&
- !sys_auth_record_login(li->username,li->hostname,li->line))
- logit("Writing login record failed for %s", li->username);
#endif
return 0;
}
int
login_utmp_only(struct logininfo *li)
{
- li->type = LTYPE_LOGIN;
+ li->type = LTYPE_LOGIN;
login_set_current_time(li);
# ifdef USE_UTMP
utmp_write_entry(li);
if (strncmp(src, "/dev/", 5) == 0)
src += 5;
-#ifdef WITH_ABBREV_NO_TTY
- if (strncmp(src, "tty", 3) == 0)
- src += 3;
-#endif
-
len = strlen(src);
if (len > 0) {
construct_utmp(struct logininfo *li,
struct utmp *ut)
{
-# ifdef HAVE_ADDR_V6_IN_UTMP
- struct sockaddr_in6 *sa6;
-# endif
memset(ut, '\0', sizeof(*ut));
/* First fill out fields used for both logins and logouts */
switch (li->type) {
case LTYPE_LOGIN:
ut->ut_type = USER_PROCESS;
-#ifdef _UNICOS
+#ifdef _CRAY
cray_set_tmpdir(ut);
#endif
break;
case LTYPE_LOGOUT:
ut->ut_type = DEAD_PROCESS;
-#ifdef _UNICOS
+#ifdef _CRAY
cray_retain_utmp(ut, li->pid);
#endif
break;
if (li->hostaddr.sa.sa_family == AF_INET)
ut->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr;
# endif
-# ifdef HAVE_ADDR_V6_IN_UTMP
- /* this is just a 128-bit IPv6 address */
- if (li->hostaddr.sa.sa_family == AF_INET6) {
- sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa);
- memcpy(ut->ut_addr_v6, sa6->sin6_addr.s6_addr, 16);
- if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) {
- ut->ut_addr_v6[0] = ut->ut_addr_v6[3];
- ut->ut_addr_v6[1] = 0;
- ut->ut_addr_v6[2] = 0;
- ut->ut_addr_v6[3] = 0;
- }
- }
-# endif
}
#endif /* USE_UTMP || USE_WTMP || USE_LOGIN */
void
construct_utmpx(struct logininfo *li, struct utmpx *utx)
{
-# ifdef HAVE_ADDR_V6_IN_UTMP
- struct sockaddr_in6 *sa6;
-# endif
memset(utx, '\0', sizeof(*utx));
# ifdef HAVE_ID_IN_UTMPX
line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id));
line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line));
set_utmpx_time(li, utx);
utx->ut_pid = li->pid;
- /* strncpy(): Don't necessarily want null termination */
- strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username));
if (li->type == LTYPE_LOGOUT)
return;
* for logouts.
*/
+ /* strncpy(): Don't necessarily want null termination */
+ strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username));
# ifdef HAVE_HOST_IN_UTMPX
strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname));
# endif
if (li->hostaddr.sa.sa_family == AF_INET)
utx->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr;
# endif
-# ifdef HAVE_ADDR_V6_IN_UTMP
- /* this is just a 128-bit IPv6 address */
- if (li->hostaddr.sa.sa_family == AF_INET6) {
- sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa);
- memcpy(ut->ut_addr_v6, sa6->sin6_addr.s6_addr, 16);
- if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) {
- ut->ut_addr_v6[0] = ut->ut_addr_v6[3];
- ut->ut_addr_v6[1] = 0;
- ut->ut_addr_v6[2] = 0;
- ut->ut_addr_v6[3] = 0;
- }
- }
-# endif
# ifdef HAVE_SYSLEN_IN_UTMPX
/* ut_syslen is the length of the utx_host string */
utx->ut_syslen = MIN(strlen(li->hostname), sizeof(utx->ut_host));
endttyent();
if((struct ttyent *)0 == ty) {
- logit("%s: tty not found", __func__);
- return (0);
+ log("utmp_write_entry: tty not found");
+ return(1);
}
#else /* FIXME */
#endif /* HAVE_GETTTYENT */
if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) {
- off_t pos, ret;
-
- pos = (off_t)tty * sizeof(struct utmp);
- if ((ret = lseek(fd, pos, SEEK_SET)) == -1) {
- logit("%s: llseek: %s", strerror(errno));
- return (0);
- }
- if (ret != pos) {
- logit("%s: Couldn't seek to tty %s slot in %s", tty,
- UTMP_FILE);
- return (0);
- }
+ (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
/*
* Prevent luser from zero'ing out ut_host.
* If the new ut_line is empty but the old one is not
(void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host));
}
- if ((ret = lseek(fd, pos, SEEK_SET)) == -1) {
- logit("%s: llseek: %s", __func__, strerror(errno));
- return (0);
- }
- if (ret != pos) {
- logit("%s: Couldn't seek to tty %s slot in %s",
- __func__, tty, UTMP_FILE);
- return (0);
- }
- if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut))
- logit("%s: error writing %s: %s", __func__,
+ (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
+ if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut))
+ log("utmp_write_direct: error writing %s: %s",
UTMP_FILE, strerror(errno));
(void)close(fd);
construct_utmp(li, &ut);
# ifdef UTMP_USE_LIBRARY
if (!utmp_write_library(li, &ut)) {
- logit("utmp_perform_login: utmp_write_library() failed");
+ log("utmp_perform_login: utmp_write_library() failed");
return 0;
}
# else
if (!utmp_write_direct(li, &ut)) {
- logit("utmp_perform_login: utmp_write_direct() failed");
+ log("utmp_perform_login: utmp_write_direct() failed");
return 0;
}
# endif
construct_utmp(li, &ut);
# ifdef UTMP_USE_LIBRARY
if (!utmp_write_library(li, &ut)) {
- logit("utmp_perform_logout: utmp_write_library() failed");
+ log("utmp_perform_logout: utmp_write_library() failed");
return 0;
}
# else
if (!utmp_write_direct(li, &ut)) {
- logit("utmp_perform_logout: utmp_write_direct() failed");
+ log("utmp_perform_logout: utmp_write_direct() failed");
return 0;
}
# endif
return utmp_perform_logout(li);
default:
- logit("utmp_write_entry: invalid type field");
+ log("utmp_write_entry: invalid type field");
return 0;
}
}
static int
utmpx_write_direct(struct logininfo *li, struct utmpx *utx)
{
- logit("utmpx_write_direct: not implemented!");
+ log("utmpx_write_direct: not implemented!");
return 0;
}
# endif /* UTMPX_USE_LIBRARY */
construct_utmpx(li, &utx);
# ifdef UTMPX_USE_LIBRARY
if (!utmpx_write_library(li, &utx)) {
- logit("utmpx_perform_login: utmp_write_library() failed");
+ log("utmpx_perform_login: utmp_write_library() failed");
return 0;
}
# else
if (!utmpx_write_direct(li, &ut)) {
- logit("utmpx_perform_login: utmp_write_direct() failed");
+ log("utmpx_perform_login: utmp_write_direct() failed");
return 0;
}
# endif
{
struct utmpx utx;
- construct_utmpx(li, &utx);
+ memset(&utx, '\0', sizeof(utx));
+ set_utmpx_time(li, &utx);
+ line_stripname(utx.ut_line, li->line, sizeof(utx.ut_line));
# ifdef HAVE_ID_IN_UTMPX
line_abbrevname(utx.ut_id, li->line, sizeof(utx.ut_id));
# endif
case LTYPE_LOGOUT:
return utmpx_perform_logout(li);
default:
- logit("utmpx_write_entry: invalid type field");
+ log("utmpx_write_entry: invalid type field");
return 0;
}
}
int fd, ret = 1;
if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) {
- logit("wtmp_write: problem writing %s: %s",
+ log("wtmp_write: problem writing %s: %s",
WTMP_FILE, strerror(errno));
return 0;
}
if (fstat(fd, &buf) == 0)
- if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) {
+ if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) {
ftruncate(fd, buf.st_size);
- logit("wtmp_write: problem writing %s: %s",
+ log("wtmp_write: problem writing %s: %s",
WTMP_FILE, strerror(errno));
ret = 0;
}
case LTYPE_LOGOUT:
return wtmp_perform_logout(li);
default:
- logit("wtmp_write_entry: invalid type field");
+ log("wtmp_write_entry: invalid type field");
return 0;
}
}
li->tv_sec = li->tv_usec = 0;
if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) {
- logit("wtmp_get_entry: problem opening %s: %s",
+ log("wtmp_get_entry: problem opening %s: %s",
WTMP_FILE, strerror(errno));
return 0;
}
if (fstat(fd, &st) != 0) {
- logit("wtmp_get_entry: couldn't stat %s: %s",
+ log("wtmp_get_entry: couldn't stat %s: %s",
WTMP_FILE, strerror(errno));
close(fd);
return 0;
while (!found) {
if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) {
- logit("wtmp_get_entry: read of %s failed: %s",
+ log("wtmp_get_entry: read of %s failed: %s",
WTMP_FILE, strerror(errno));
close (fd);
return 0;
static int
wtmpx_write(struct logininfo *li, struct utmpx *utx)
{
-#ifndef HAVE_UPDWTMPX
struct stat buf;
int fd, ret = 1;
if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) {
- logit("wtmpx_write: problem opening %s: %s",
+ log("wtmpx_write: problem opening %s: %s",
WTMPX_FILE, strerror(errno));
return 0;
}
if (fstat(fd, &buf) == 0)
- if (atomicio(vwrite, fd, utx, sizeof(*utx)) != sizeof(*utx)) {
+ if (atomicio(write, fd, utx, sizeof(*utx)) != sizeof(*utx)) {
ftruncate(fd, buf.st_size);
- logit("wtmpx_write: problem writing %s: %s",
+ log("wtmpx_write: problem writing %s: %s",
WTMPX_FILE, strerror(errno));
ret = 0;
}
(void)close(fd);
return ret;
-#else
- updwtmpx(WTMPX_FILE, utx);
- return 1;
-#endif
}
case LTYPE_LOGOUT:
return wtmpx_perform_logout(li);
default:
- logit("wtmpx_write_entry: invalid type field");
+ log("wtmpx_write_entry: invalid type field");
return 0;
}
}
li->tv_sec = li->tv_usec = 0;
if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) {
- logit("wtmpx_get_entry: problem opening %s: %s",
+ log("wtmpx_get_entry: problem opening %s: %s",
WTMPX_FILE, strerror(errno));
return 0;
}
if (fstat(fd, &st) != 0) {
- logit("wtmpx_get_entry: couldn't stat %s: %s",
- WTMPX_FILE, strerror(errno));
+ log("wtmpx_get_entry: couldn't stat %s: %s",
+ WTMP_FILE, strerror(errno));
close(fd);
return 0;
}
while (!found) {
if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) {
- logit("wtmpx_get_entry: read of %s failed: %s",
+ log("wtmpx_get_entry: read of %s failed: %s",
WTMPX_FILE, strerror(errno));
close (fd);
return 0;
/* Logouts are recorded as a blank username on a particular line.
* So, we just need to find the username in struct utmpx */
if ( wtmpx_islogin(li, &utx) ) {
- found = 1;
# ifdef HAVE_TV_IN_UTMPX
li->tv_sec = utx.ut_tv.tv_sec;
# else
struct utmp *ut;
if (! (ut = (struct utmp *)malloc(sizeof(*ut)))) {
- logit("syslogin_perform_login: couldn't malloc()");
+ log("syslogin_perform_login: couldn't malloc()");
return 0;
}
construct_utmp(li, ut);
login(ut);
- free(ut);
return 1;
}
syslogin_perform_logout(struct logininfo *li)
{
# ifdef HAVE_LOGOUT
- char line[UT_LINESIZE];
+ char line[8];
(void)line_stripname(line, li->line, sizeof(line));
if (!logout(line)) {
- logit("syslogin_perform_logout: logout() returned an error");
+ log("syslogin_perform_logout: logout() returned an error");
# ifdef HAVE_LOGWTMP
} else {
logwtmp(line, "", "");
case LTYPE_LOGOUT:
return syslogin_perform_logout(li);
default:
- logit("syslogin_write_entry: Invalid type field");
+ log("syslogin_write_entry: Invalid type field");
return 0;
}
}
struct stat st;
if (stat(LASTLOG_FILE, &st) != 0) {
- logit("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE,
+ log("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE,
strerror(errno));
return 0;
}
LASTLOG_FILE, li->username);
break;
default:
- logit("lastlog_openseek: %.100s is not a file or directory!",
+ log("lastlog_openseek: %.100s is not a file or directory!",
LASTLOG_FILE);
return 0;
}
- *fd = open(lastlog_file, filemode, 0600);
+ *fd = open(lastlog_file, filemode);
if ( *fd < 0) {
debug("lastlog_openseek: Couldn't open %s: %s",
lastlog_file, strerror(errno));
offset = (off_t) ((long)li->uid * sizeof(struct lastlog));
if ( lseek(*fd, offset, SEEK_SET) != offset ) {
- logit("lastlog_openseek: %s->lseek(): %s",
+ log("lastlog_openseek: %s->lseek(): %s",
lastlog_file, strerror(errno));
return 0;
}
return(0);
/* write the entry */
- if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) {
+ if (atomicio(write, fd, &last, sizeof(last)) != sizeof(last)) {
close(fd);
- logit("lastlog_write_filemode: Error writing to %s: %s",
+ log("lastlog_write_filemode: Error writing to %s: %s",
LASTLOG_FILE, strerror(errno));
return 0;
}
case LTYPE_LOGIN:
return lastlog_perform_login(li);
default:
- logit("lastlog_write_entry: Invalid type field");
+ log("lastlog_write_entry: Invalid type field");
return 0;
}
}
lastlog_get_entry(struct logininfo *li)
{
struct lastlog last;
- int fd, ret;
+ int fd;
if (!lastlog_openseek(li, &fd, O_RDONLY))
- return (0);
-
- ret = atomicio(read, fd, &last, sizeof(last));
- close(fd);
+ return 0;
- switch (ret) {
- case 0:
- memset(&last, '\0', sizeof(last));
- /* FALLTHRU */
- case sizeof(last):
- lastlog_populate_entry(li, &last);
- return (1);
- case -1:
- error("%s: Error reading from %s: %s", __func__,
+ if (atomicio(read, fd, &last, sizeof(last)) != sizeof(last)) {
+ close(fd);
+ log("lastlog_get_entry: Error reading from %s: %s",
LASTLOG_FILE, strerror(errno));
- return (0);
- default:
- error("%s: Error reading from %s: Expecting %d, got %d",
- __func__, LASTLOG_FILE, sizeof(last), ret);
- return (0);
+ return 0;
}
- /* NOTREACHED */
- return (0);
+ close(fd);
+
+ lastlog_populate_entry(li, &last);
+
+ return 1;
}
#endif /* USE_LASTLOG */