mirror of
git://anongit.mindrot.org/openssh.git
synced 2024-12-16 07:04:34 +00:00
Added new login recording code
Added test program for login code (make logintest)
This commit is contained in:
parent
e340f73b53
commit
2ff7b5d028
@ -40,7 +40,7 @@ LIBOPENBSD_COMPAT_OBJS=bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-misc.o b
|
||||
|
||||
SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o
|
||||
|
||||
SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-rhosts.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o servconf.o serverloop.o bsd-login.o md5crypt.o session.o
|
||||
SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-rhosts.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o session.o
|
||||
|
||||
TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8
|
||||
CATMAN = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh.0 sshd.0
|
||||
@ -86,11 +86,15 @@ ssh-agent: libopenbsd-compat.a libssh.a ssh-agent.o log-client.o
|
||||
ssh-keygen: libopenbsd-compat.a libssh.a ssh-keygen.o log-client.o
|
||||
$(LD) -o $@ ssh-keygen.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
# test driver for the loginrec code - not built by default
|
||||
logintest: logintest.o libopenbsd-compat.a libssh.a log-client.o loginrec.o
|
||||
$(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh log-client.o $(LIBS)
|
||||
|
||||
$(MANPAGES) $(CONFIGFILES)::
|
||||
$(FIXPATHSCMD) $(srcdir)/$@
|
||||
|
||||
clean:
|
||||
rm -f *.o *.a $(TARGETS) config.cache config.log
|
||||
rm -f *.o *.a $(TARGETS) logintest config.cache config.log
|
||||
rm -f *.out core
|
||||
|
||||
distclean: clean
|
||||
|
44
acconfig.h
44
acconfig.h
@ -52,10 +52,50 @@
|
||||
#undef HAVE_TYPE_IN_UTMP
|
||||
#undef HAVE_TYPE_IN_UTMPX
|
||||
#undef HAVE_TV_IN_UTMP
|
||||
#undef HAVE_TV_IN_UTMPX
|
||||
#undef HAVE_ID_IN_UTMP
|
||||
#undef HAVE_EXIT_IN_UTMP
|
||||
#undef HAVE_TIME_IN_UTMP
|
||||
#undef HAVE_TIME_IN_UTMPX
|
||||
|
||||
/* Define if you want to use utmpx */
|
||||
#undef USE_UTMPX
|
||||
/* Define if you don't want to use your system's login() call */
|
||||
#undef DISABLE_LOGIN
|
||||
|
||||
/* Define if you don't want to use pututline() etc. to write [uw]tmp */
|
||||
#undef DISABLE_PUTUTLINE
|
||||
|
||||
/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */
|
||||
#undef DISABLE_PUTUTXLINE
|
||||
|
||||
/* Define if you don't want to use lastlog */
|
||||
#undef DISABLE_LASTLOG
|
||||
|
||||
/* Define if you don't want to use utmp */
|
||||
#undef DISABLE_UTMP
|
||||
|
||||
/* Define if you don't want to use utmpx */
|
||||
#undef DISABLE_UTMPX
|
||||
|
||||
/* Define if you don't want to use wtmp */
|
||||
#undef DISABLE_WTMP
|
||||
|
||||
/* Define if you don't want to use wtmpx */
|
||||
#undef DISABLE_WTMPX
|
||||
|
||||
/* Define if you want to specify the path to your lastlog file */
|
||||
#undef CONF_LASTLOG_FILE
|
||||
|
||||
/* Define if you want to specify the path to your utmp file */
|
||||
#undef CONF_UTMP_FILE
|
||||
|
||||
/* Define if you want to specify the path to your wtmp file */
|
||||
#undef CONF_WTMP_FILE
|
||||
|
||||
/* Define if you want to specify the path to your utmpx file */
|
||||
#undef CONF_UTMPX_FILE
|
||||
|
||||
/* Define if you want to specify the path to your wtmpx file */
|
||||
#undef CONF_WTMPX_FILE
|
||||
|
||||
/* Define is libutil has login() function */
|
||||
#undef HAVE_LIBUTIL_LOGIN
|
||||
|
195
bsd-login.c
195
bsd-login.c
@ -1,195 +0,0 @@
|
||||
/*
|
||||
* This file has been heavily modified from the original OpenBSD version
|
||||
*/
|
||||
|
||||
/* $OpenBSD: login.c,v 1.5 1998/07/13 02:11:12 millert Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifndef HAVE_LOGIN
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/* from: static char sccsid[] = "@(#)login.c 8.1 (Berkeley) 6/4/93"; */
|
||||
static char *rcsid = "$OpenBSD: login.c,v 1.5 1998/07/13 02:11:12 millert Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
|
||||
# include <utmpx.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTMP_H
|
||||
# include <utmp.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USER_PROCESS
|
||||
/*
|
||||
* find first matching slot in utmp, or "-1" for none
|
||||
*
|
||||
* algorithm: for USER_PROCESS, check tty name
|
||||
* for DEAD_PROCESS, check PID and tty name
|
||||
*
|
||||
*/
|
||||
int find_tty_slot( utp )
|
||||
struct utmp * utp;
|
||||
{
|
||||
int t = 0;
|
||||
struct utmp * u;
|
||||
|
||||
# if defined(HAVE_TYPE_IN_UTMP) || defined(HAVE_TYPE_IN_UTMPX)
|
||||
setutent();
|
||||
|
||||
while((u = getutent()) != NULL) {
|
||||
if (utp->ut_type == USER_PROCESS &&
|
||||
(strncmp(utp->ut_line, u->ut_line, sizeof(utp->ut_line)) == 0)) {
|
||||
endutent();
|
||||
return(t);
|
||||
}
|
||||
|
||||
if ((utp->ut_type == DEAD_PROCESS) && (utp->ut_pid == u->ut_pid) &&
|
||||
(strncmp(utp->ut_line, u->ut_line, sizeof(utp->ut_line)) == 0 )) {
|
||||
endutent();
|
||||
return(t);
|
||||
}
|
||||
t++;
|
||||
}
|
||||
|
||||
endutent();
|
||||
# endif /* defined(HAVE_TYPE_IN_UTMP) || defined(HAVE_TYPE_IN_UTMPX) */
|
||||
return(-1);
|
||||
}
|
||||
#else /* USER_PROCESS */
|
||||
int find_tty_slot(struct utmp *utp)
|
||||
{
|
||||
return(ttyslot());
|
||||
}
|
||||
#endif /* USER_PROCESS */
|
||||
|
||||
#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
|
||||
void login(struct utmpx *utx)
|
||||
#else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
|
||||
void login(struct utmp *utp)
|
||||
#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
|
||||
{
|
||||
/* Use proper API if we have it */
|
||||
#if defined(USE_UTMPX)
|
||||
# if defined(HAVE_PUTUTXLINE)
|
||||
setutxent();
|
||||
pututxline(utx);
|
||||
endutxent();
|
||||
# endif /* defined(HAVE_PUTUTXLINE) */
|
||||
# if defined(HAVE_UPDWTMPX)
|
||||
updwtmpx(_PATH_WTMPX, utx);
|
||||
# endif /* defined(HAVE_UPDWTMPX) */
|
||||
#else /* defined(USE_UTMPX) */
|
||||
# if defined(HAVE_PUTUTLINE)
|
||||
setutent();
|
||||
pututline(utp);
|
||||
endutent();
|
||||
# endif /* defined(HAVE_PUTUTLINE) */
|
||||
# if defined(HAVE_UPDWTMPX)
|
||||
updwtmp(_PATH_WTMP, utp);
|
||||
# endif /* defined(HAVE_UPDWTMP) */
|
||||
#endif /* defined(USE_UTMPX) */
|
||||
|
||||
/* Otherwise DIY */
|
||||
#if (defined(USE_UTMPX) && !defined(HAVE_PUTUTXLINE)) || \
|
||||
(!defined(USE_UTMPX) && !defined(HAVE_PUTUTLINE))
|
||||
int fd;
|
||||
int tty;
|
||||
|
||||
/* can't use ttyslot here, as that will not work for logout
|
||||
* (record_logout() is called from the master sshd, which does
|
||||
* not have the correct tty on stdin/out, so ttyslot will return
|
||||
* "-1" or (worse) a wrong number
|
||||
*/
|
||||
tty = find_tty_slot(utp);
|
||||
|
||||
#ifdef USE_UTMPX
|
||||
/* If no tty was found, append it to utmpx */
|
||||
if (tty == -1) {
|
||||
if ((fd = open(_PATH_UTMPX, O_WRONLY|O_APPEND, 0)) >= 0) {
|
||||
(void)write(fd, utp, sizeof(struct utmp));
|
||||
(void)close(fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Otherwise, tty was found - update at its location */
|
||||
fd = open(_PATH_UTMPX, O_RDWR|O_CREAT, 0644);
|
||||
if (fd == -1) {
|
||||
log("Couldn't open %s: %s", _PATH_UTMPX, strerror(errno));
|
||||
return;
|
||||
}
|
||||
lseek(fd, (off_t)(tty * sizeof(struct utmpx)), SEEK_SET);
|
||||
write(fd, utx, sizeof(struct utmpx));
|
||||
close(fd);
|
||||
if ((fd = open(_PATH_WTMPX, O_WRONLY|O_APPEND, 0)) >= 0) {
|
||||
(void)write(fd, utx, sizeof(struct utmpx));
|
||||
(void)close(fd);
|
||||
}
|
||||
#else /* USE_UTMPX */
|
||||
/* If no tty was found, append it to utmp */
|
||||
if (tty == -1) {
|
||||
if ((fd = open(_PATH_UTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
|
||||
(void)write(fd, utp, sizeof(struct utmp));
|
||||
(void)close(fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Otherwise, tty was found - update at its location */
|
||||
fd = open(_PATH_UTMP, O_RDWR|O_CREAT, 0644);
|
||||
if (fd == -1) {
|
||||
log("Couldn't open %s: %s", _PATH_UTMP, strerror(errno));
|
||||
return;
|
||||
}
|
||||
lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
|
||||
write(fd, utp, sizeof(struct utmp));
|
||||
close(fd);
|
||||
if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
|
||||
(void)write(fd, utp, sizeof(struct utmp));
|
||||
(void)close(fd);
|
||||
}
|
||||
#endif /* USE_UTMPX */
|
||||
#endif /* (defined(USE_UTMPX) && !defined(HAVE_PUTUTXLINE)) || \
|
||||
(!defined(USE_UTMPX) && !defined(HAVE_PUTUTLINE)) */
|
||||
}
|
||||
|
||||
#endif /* HAVE_LOGIN */
|
22
bsd-login.h
22
bsd-login.h
@ -1,22 +0,0 @@
|
||||
#ifndef _BSD_LOGIN_H
|
||||
# define _BSD_LOGIN_H
|
||||
|
||||
# include "config.h"
|
||||
# ifndef HAVE_LOGIN
|
||||
|
||||
# include <utmp.h>
|
||||
|
||||
# if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
|
||||
# include <utmpx.h>
|
||||
|
||||
void login(struct utmp *utp, struct utmpx *utx);
|
||||
|
||||
# else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
|
||||
|
||||
void login(struct utmp *utp);
|
||||
|
||||
# endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
|
||||
|
||||
# endif /* !HAVE_LOGIN */
|
||||
|
||||
#endif /* _BSD_LOGIN_H */
|
268
configure.in
268
configure.in
@ -43,7 +43,6 @@ case "$host" in
|
||||
fi
|
||||
CFLAGS="$CFLAGS -D_HPUX_SOURCE"
|
||||
AC_DEFINE(IPADDR_IN_DISPLAY)
|
||||
AC_DEFINE(USE_UTMPX)
|
||||
AC_MSG_CHECKING(for HPUX trusted system password database)
|
||||
if test -f /tcb/files/auth/system/default; then
|
||||
AC_MSG_RESULT(yes)
|
||||
@ -63,7 +62,6 @@ case "$host" in
|
||||
fi
|
||||
CFLAGS="$CFLAGS -D_HPUX_SOURCE"
|
||||
AC_DEFINE(IPADDR_IN_DISPLAY)
|
||||
AC_DEFINE(USE_UTMPX)
|
||||
AC_MSG_CHECKING(for HPUX trusted system password database)
|
||||
if test -f /tcb/files/auth/system/default; then
|
||||
AC_MSG_RESULT(yes)
|
||||
@ -104,7 +102,8 @@ case "$host" in
|
||||
CFLAGS="$CFLAGS -I/usr/local/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib -L/usr/ucblib -R/usr/ucblib"
|
||||
need_dash_r=1
|
||||
AC_DEFINE(USE_UTMPX)
|
||||
# hardwire lastlog location (can't detect it on some versions)
|
||||
conf_lastlog_location="/var/adm/lastlog"
|
||||
;;
|
||||
*-*-sunos4*)
|
||||
CFLAGS="$CFLAGS -DSUNOS4"
|
||||
@ -113,7 +112,6 @@ case "$host" in
|
||||
*-*-sysv*)
|
||||
CFLAGS="$CFLAGS -I/usr/local/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
AC_DEFINE(USE_UTMPX)
|
||||
MANTYPE='$(CATMAN)'
|
||||
mansubdir=cat
|
||||
LIBS="$LIBS -lgen -lsocket"
|
||||
@ -132,10 +130,20 @@ if test -z "$no_libnsl" ; then
|
||||
fi
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS(bstring.h endian.h lastlog.h login.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h util.h utmp.h utmpx.h)
|
||||
AC_CHECK_HEADERS(bstring.h endian.h lastlog.h login.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h time.h util.h utmp.h utmpx.h)
|
||||
|
||||
# Checks for library functions.
|
||||
AC_CHECK_FUNCS(arc4random atexit b64_ntop bcopy bindresvport_af clock freeaddrinfo gai_strerror getaddrinfo getnameinfo getrusage innetgr md5_crypt memmove mkdtemp on_exit openpty pututline pututxline rresvport_af setenv seteuid setlogin setproctitle setreuid snprintf strlcat strlcpy updwtmp updwtmpx vsnprintf vhangup _getpty __b64_ntop)
|
||||
AC_CHECK_FUNCS(arc4random atexit b64_ntop bcopy bindresvport_af clock freeaddrinfo gai_strerror getaddrinfo getnameinfo getrusage innetgr md5_crypt memmove mkdtemp on_exit openpty rresvport_af setenv seteuid setlogin setproctitle setreuid snprintf strlcat strlcpy vsnprintf vhangup _getpty __b64_ntop)
|
||||
dnl checks for time functions
|
||||
AC_CHECK_FUNCS(gettimeofday time)
|
||||
dnl checks for libutil functions
|
||||
AC_CHECK_FUNCS(login logout updwtmp logwtmp)
|
||||
dnl checks for utmp functions
|
||||
AC_CHECK_FUNCS(entutent getutent getutid getutline pututline setutent)
|
||||
AC_CHECK_FUNCS(utmpname)
|
||||
dnl checks for utmpx functions
|
||||
AC_CHECK_FUNCS(entutxent getutxent getutxid getutxline pututxline )
|
||||
AC_CHECK_FUNCS(setutxent utmpxname)
|
||||
|
||||
AC_CHECK_FUNC(login,
|
||||
[AC_DEFINE(HAVE_LOGIN)],
|
||||
@ -501,6 +509,11 @@ OSSH_CHECK_HEADER_FOR_FIELD(ut_addr, utmp.h, HAVE_ADDR_IN_UTMP)
|
||||
OSSH_CHECK_HEADER_FOR_FIELD(ut_addr, utmpx.h, HAVE_ADDR_IN_UTMPX)
|
||||
OSSH_CHECK_HEADER_FOR_FIELD(ut_addr_v6, utmp.h, HAVE_ADDR_V6_IN_UTMP)
|
||||
OSSH_CHECK_HEADER_FOR_FIELD(ut_addr_v6, utmpx.h, HAVE_ADDR_V6_IN_UTMPX)
|
||||
OSSH_CHECK_HEADER_FOR_FIELD(ut_exit, utmp.h, HAVE_EXIT_IN_UTMP)
|
||||
OSSH_CHECK_HEADER_FOR_FIELD(ut_time, utmp.h, HAVE_TIME_IN_UTMP)
|
||||
OSSH_CHECK_HEADER_FOR_FIELD(ut_time, utmpx.h, HAVE_TIME_IN_UTMPX)
|
||||
OSSH_CHECK_HEADER_FOR_FIELD(ut_tv, utmpx.h, HAVE_TV_IN_UTMPX)
|
||||
|
||||
|
||||
|
||||
AC_CACHE_CHECK([for ss_family field in struct sockaddr_storage],
|
||||
@ -590,48 +603,6 @@ if test ! -z "$MAIL" ; then
|
||||
AC_DEFINE_UNQUOTED(MAIL_DIRECTORY, "$maildir")
|
||||
fi
|
||||
|
||||
# Look for lastlog location
|
||||
AC_ARG_WITH(lastlog,
|
||||
[ --with-lastlog=FILE Location of lastlog file],
|
||||
[
|
||||
if test "x$withval" = "xno" ; then
|
||||
AC_DEFINE(DISABLE_LASTLOG)
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(LASTLOG_LOCATION, "$withval")
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_MSG_CHECKING([location of lastlog file])
|
||||
for lastlog in /var/log/lastlog /var/adm/lastlog /usr/adm/lastlog /etc/security/lastlog ; do
|
||||
if test -f $lastlog ; then
|
||||
gotlastlog="file"
|
||||
break
|
||||
fi
|
||||
if test -d $lastlog ; then
|
||||
gotlastlog="dir"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$gotlastlog" ; then
|
||||
AC_MSG_RESULT(not found)
|
||||
nolastlog=1
|
||||
else
|
||||
if test "x$gotlastlog" = "xdir" ; then
|
||||
AC_MSG_RESULT(${lastlog}/)
|
||||
AC_DEFINE(LASTLOG_IS_DIR)
|
||||
else
|
||||
AC_MSG_RESULT($lastlog)
|
||||
AC_DEFINE_UNQUOTED(LASTLOG_LOCATION, "$lastlog")
|
||||
fi
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
||||
if test ! -z "$nolastlog" ; then
|
||||
AC_MSG_WARN([*** Disabling lastlog support *** ])
|
||||
AC_DEFINE(DISABLE_LASTLOG)
|
||||
fi
|
||||
|
||||
if test -z "$no_dev_ptmx" ; then
|
||||
AC_CHECK_FILE("/dev/ptmx",
|
||||
[
|
||||
@ -838,16 +809,6 @@ AC_ARG_WITH(md5-passwords,
|
||||
]
|
||||
)
|
||||
|
||||
# Check whether to enable utmpx support
|
||||
AC_ARG_WITH(utmpx,
|
||||
[ --with-utmpx Enable utmpx support],
|
||||
[
|
||||
if test "x$withval" != "xno" ; then
|
||||
AC_DEFINE(USE_UTMPX)
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
||||
# Whether to disable shadow password support
|
||||
AC_ARG_WITH(shadow,
|
||||
[ --without-shadow Disable shadow password support],
|
||||
@ -922,6 +883,197 @@ AC_ARG_WITH(pid-dir,
|
||||
AC_DEFINE_UNQUOTED(PIDDIR, "$piddir")
|
||||
AC_SUBST(piddir)
|
||||
|
||||
dnl allow user to disable some login recording features
|
||||
AC_ARG_ENABLE(lastlog,
|
||||
[ --disable-lastlog disable use of lastlog even if detected [no]],
|
||||
[ AC_DEFINE(DISABLE_LASTLOG) ]
|
||||
)
|
||||
AC_ARG_ENABLE(utmp,
|
||||
[ --disable-utmp disable use of utmp even if detected [no]],
|
||||
[ AC_DEFINE(DISABLE_UTMP) ]
|
||||
)
|
||||
AC_ARG_ENABLE(utmpx,
|
||||
[ --disable-utmpx disable use of utmpx even if detected [no]],
|
||||
[ AC_DEFINE(DISABLE_UTMPX) ]
|
||||
)
|
||||
AC_ARG_ENABLE(wtmp,
|
||||
[ --disable-wtmp disable use of wtmp even if detected [no]],
|
||||
[ AC_DEFINE(DISABLE_WTMP) ]
|
||||
)
|
||||
AC_ARG_ENABLE(wtmpx,
|
||||
[ --disable-wtmpx disable use of wtmpx even if detected [no]],
|
||||
[ AC_DEFINE(DISABLE_WTMPX) ]
|
||||
)
|
||||
AC_ARG_ENABLE(libutil,
|
||||
[ --disable-libutil disable use of libutil (login() etc.) [no]],
|
||||
[ AC_DEFINE(DISABLE_LOGIN) ]
|
||||
)
|
||||
AC_ARG_ENABLE(pututline,
|
||||
[ --disable-pututline disable use of pututline() etc. ([uw]tmp) [no]],
|
||||
[ AC_DEFINE(DISABLE_PUTUTLINE) ]
|
||||
)
|
||||
AC_ARG_ENABLE(pututxline,
|
||||
[ --disable-pututxline disable use of pututxline() etc. ([uw]tmpx) [no]],
|
||||
[ AC_DEFINE(DISABLE_PUTUTXLINE) ]
|
||||
)
|
||||
AC_ARG_WITH(lastlog,
|
||||
[ --with-lastlog=FILE|DIR specify lastlog location [common locations]],
|
||||
[ conf_lastlog_location="$withval"; ],)
|
||||
|
||||
dnl lastlog, [uw]tmpx? detection
|
||||
dnl NOTE: set the paths in the platform section to avoid the
|
||||
dnl need for command-line parameters
|
||||
dnl lastlog and [uw]tmp are subject to a file search if all else fails
|
||||
|
||||
dnl lastlog detection
|
||||
dnl NOTE: the code itself will detect if lastlog is a directory
|
||||
AC_MSG_CHECKING([if your system defines LASTLOG_FILE])
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <utmp.h>
|
||||
#ifdef HAVE_LASTLOG_H
|
||||
# include <lastlog.h>
|
||||
#endif
|
||||
#ifdef PATHS_H
|
||||
# include <paths.h>
|
||||
#endif
|
||||
],
|
||||
[ char *lastlog = LASTLOG_FILE; ],
|
||||
[ AC_MSG_RESULT(yes) ],
|
||||
[ AC_MSG_RESULT(no)
|
||||
system_lastlog_path=no ]
|
||||
)
|
||||
if test -z "$conf_lastlog_location"; then
|
||||
if test x"$system_lastlog_path" = x"no" ; then
|
||||
for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do
|
||||
if test -e $f ; then
|
||||
conf_lastlog_location=$f
|
||||
fi
|
||||
done
|
||||
if test -z "$conf_lastlog_location"; then
|
||||
AC_MSG_WARN([** Cannot find lastlog - disabling feature **])
|
||||
AC_DEFINE(DISABLE_LASTLOG)
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$conf_lastlog_location"; then
|
||||
AC_DEFINE_UNQUOTED(CONF_LASTLOG_FILE, "$conf_lastlog_location")
|
||||
fi
|
||||
|
||||
dnl utmp detection
|
||||
AC_MSG_CHECKING([if your system defines UTMP_FILE])
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <utmp.h>
|
||||
#ifdef PATHS_H
|
||||
# include <paths.h>
|
||||
#endif
|
||||
],
|
||||
[ char *utmp = UTMP_FILE; ],
|
||||
[ AC_MSG_RESULT(yes) ],
|
||||
[ AC_MSG_RESULT(no)
|
||||
system_utmp_path=no ]
|
||||
)
|
||||
if test -z "$conf_utmp_location"; then
|
||||
if test x"$system_utmp_path" = x"no" ; then
|
||||
for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do
|
||||
if test -f $f ; then
|
||||
conf_utmp_location=$f
|
||||
fi
|
||||
done
|
||||
if test -z "$conf_utmp_location"; then
|
||||
AC_DEFINE(DISABLE_UTMP)
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test -n "$conf_utmp_location"; then
|
||||
AC_DEFINE_UNQUOTED(CONF_UTMP_FILE, "$conf_utmp_location")
|
||||
fi
|
||||
|
||||
dnl wtmp detection
|
||||
AC_MSG_CHECKING([if your system defines WTMP_FILE])
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <utmp.h>
|
||||
#ifdef PATHS_H
|
||||
# include <paths.h>
|
||||
#endif
|
||||
],
|
||||
[ char *wtmp = WTMP_FILE; ],
|
||||
[ AC_MSG_RESULT(yes) ],
|
||||
[ AC_MSG_RESULT(no)
|
||||
system_wtmp_path=no ]
|
||||
)
|
||||
if test -z "$conf_wtmp_location"; then
|
||||
if test x"$system_wtmp_path" = x"no" ; then
|
||||
for f in /usr/adm/wtmp /var/log/wtmp; do
|
||||
if test -f $f ; then
|
||||
conf_wtmp_location=$f
|
||||
fi
|
||||
done
|
||||
if test -z "$conf_wtmp_location"; then
|
||||
AC_DEFINE(DISABLE_WTMP)
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test -n "$conf_wtmp_location"; then
|
||||
AC_DEFINE_UNQUOTED(CONF_WTMP_FILE, "$conf_wtmp_location")
|
||||
fi
|
||||
|
||||
|
||||
dnl utmpx detection - I don't know any system so perverse as to require
|
||||
dnl utmpx, but not define UTMPX_FILE (ditto wtmpx.) No doubt it's out
|
||||
dnl there, though.
|
||||
AC_MSG_CHECKING([if your system defines UTMPX_FILE])
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <utmp.h>
|
||||
#ifdef HAVE_UTMPX_H
|
||||
#include <utmpx.h>
|
||||
#endif
|
||||
#ifdef PATHS_H
|
||||
# include <paths.h>
|
||||
#endif
|
||||
],
|
||||
[ char *utmpx = UTMPX_FILE; ],
|
||||
[ AC_MSG_RESULT(yes) ],
|
||||
[ AC_MSG_RESULT(no)
|
||||
system_utmpx_path=no ]
|
||||
)
|
||||
if test -z "$conf_utmpx_location"; then
|
||||
if test x"$system_utmpx_path" = x"no" ; then
|
||||
AC_DEFINE(DISABLE_UTMPX)
|
||||
fi
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(CONF_UTMPX_FILE, "$conf_utmpx_location")
|
||||
fi
|
||||
|
||||
dnl wtmpx detection
|
||||
AC_MSG_CHECKING([if your system defines WTMPX_FILE])
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <utmp.h>
|
||||
#ifdef HAVE_UTMPX_H
|
||||
#include <utmpx.h>
|
||||
#endif
|
||||
#ifdef PATHS_H
|
||||
# include <paths.h>
|
||||
#endif
|
||||
],
|
||||
[ char *wtmpx = WTMPX_FILE; ],
|
||||
[ AC_MSG_RESULT(yes) ],
|
||||
[ AC_MSG_RESULT(no)
|
||||
system_wtmpx_path=no ]
|
||||
)
|
||||
if test -z "$conf_wtmpx_location"; then
|
||||
if test x"$system_wtmpx_path" = x"no" ; then
|
||||
AC_DEFINE(DISABLE_WTMPX)
|
||||
fi
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(CONF_WTMPX_FILE, "$conf_wtmpx_location")
|
||||
fi
|
||||
|
||||
|
||||
# Change default command timeout for builtin PRNG
|
||||
entropy_timeout=100
|
||||
|
125
defines.h
125
defines.h
@ -19,14 +19,6 @@
|
||||
# include <paths.h> /* For _PATH_XXX */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UTMP_H
|
||||
# include <utmp.h> /* For _PATH_XXX */
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
|
||||
# include <utmpx.h> /* For _PATH_XXX */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h> /* For timersub */
|
||||
#endif
|
||||
@ -161,47 +153,6 @@ typedef int ssize_t;
|
||||
|
||||
/* Paths */
|
||||
|
||||
/* If _PATH_LASTLOG is not defined by system headers, set it to the */
|
||||
/* lastlog file detected by autoconf */
|
||||
#ifndef _PATH_LASTLOG
|
||||
# ifdef LASTLOG_LOCATION
|
||||
# define _PATH_LASTLOG LASTLOG_LOCATION
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_UTMP
|
||||
# ifdef UTMP_FILE
|
||||
# define _PATH_UTMP UTMP_FILE
|
||||
# else
|
||||
# define _PATH_UTMP "/var/adm/utmp"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_WTMP
|
||||
# ifdef WTMP_FILE
|
||||
# define _PATH_WTMP WTMP_FILE
|
||||
# else
|
||||
# define _PATH_WTMP "/var/adm/wtmp"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
|
||||
# ifndef _PATH_UTMPX
|
||||
# ifdef UTMPX_FILE
|
||||
# define _PATH_UTMPX UTMPX_FILE
|
||||
# else
|
||||
# define _PATH_UTMPX "/var/adm/utmpx"
|
||||
# endif
|
||||
# endif
|
||||
# ifndef _PATH_WTMPX
|
||||
# ifdef WTMPX_FILE
|
||||
# define _PATH_WTMPX WTMPX_FILE
|
||||
# else
|
||||
# define _PATH_WTMPX "/var/adm/wtmp"
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_BSHELL
|
||||
# define _PATH_BSHELL "/bin/sh"
|
||||
#endif
|
||||
@ -297,4 +248,80 @@ typedef int ssize_t;
|
||||
# define atexit(a) on_exit(a)
|
||||
#endif /* !defined(HAVE_ATEXIT) && defined(HAVE_ON_EXIT) */
|
||||
|
||||
/**
|
||||
** login recorder definitions
|
||||
**/
|
||||
|
||||
/* preprocess */
|
||||
|
||||
#ifdef HAVE_UTMP_H
|
||||
# ifdef HAVE_TIME_IN_UTMP
|
||||
# include <time.h>
|
||||
# endif
|
||||
# include <utmp.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTMPX_H
|
||||
# ifdef HAVE_TV_IN_UTMPX
|
||||
# include <sys/time.h>
|
||||
# endif
|
||||
# include <utmpx.h>
|
||||
#endif
|
||||
#ifdef HAVE_LASTLOG_H
|
||||
# include <lastlog.h>
|
||||
#endif
|
||||
#ifdef HAVE_PATHS_H
|
||||
# include <paths.h>
|
||||
#endif
|
||||
|
||||
/* FIXME: put default paths back in */
|
||||
#if !defined(UTMP_FILE) && defined(_PATH_UTMP)
|
||||
# define UTMP_FILE _PATH_UTMP
|
||||
#endif
|
||||
#if !defined(WTMP_FILE) && defined(_PATH_WTMP)
|
||||
# define WTMP_FILE _PATH_WTMP
|
||||
#endif
|
||||
/* pick up the user's location for lastlog if given */
|
||||
#ifdef CONF_LASTLOG_FILE
|
||||
# define LASTLOG_FILE CONF_LASTLOG_FILE
|
||||
#endif
|
||||
#if !defined(LASTLOG_FILE) && defined(_PATH_LASTLOG)
|
||||
# define LASTLOG_FILE _PATH_LASTLOG
|
||||
#endif
|
||||
|
||||
|
||||
/* The login() library function in libutil is first choice */
|
||||
#if defined(HAVE_LOGIN) && !defined(DISABLE_LOGIN)
|
||||
# define USE_LOGIN
|
||||
|
||||
#else
|
||||
/* Simply select your favourite login types. */
|
||||
/* Can't do if-else because some systems use several... <sigh> */
|
||||
# if defined(UTMPX_FILE) && !defined(DISABLE_UTMPX)
|
||||
# define USE_UTMPX
|
||||
# endif
|
||||
# if defined(UTMP_FILE) && !defined(DISABLE_UTMP)
|
||||
# define USE_UTMP
|
||||
# endif
|
||||
# if defined(WTMPX_FILE) && !defined(DISABLE_WTMPX)
|
||||
# define USE_WTMPX
|
||||
# endif
|
||||
# if defined(WTMP_FILE) && !defined(DISABLE_WTMP)
|
||||
# define USE_WTMP
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/* I hope that the presence of LASTLOG_FILE is enough to detect this */
|
||||
#if defined(LASTLOG_FILE) && !defined(DISABLE_LASTLOG)
|
||||
# define USE_LASTLOG
|
||||
#endif
|
||||
|
||||
/* which type of time to use? (api.c) */
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# define USE_TIMEVAL
|
||||
#endif
|
||||
|
||||
/** end of login recorder definitions */
|
||||
|
||||
|
||||
#endif /* _DEFINES_H */
|
||||
|
277
login.c
277
login.c
@ -18,30 +18,9 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: login.c,v 1.30 2000/05/31 03:57:19 damien Exp $");
|
||||
RCSID("$Id: login.c,v 1.31 2000/06/03 14:57:40 andre Exp $");
|
||||
|
||||
#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
|
||||
# include <utmpx.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTMP_H
|
||||
# include <utmp.h>
|
||||
#endif
|
||||
#include "ssh.h"
|
||||
|
||||
#ifdef HAVE_UTIL_H
|
||||
# include <util.h>
|
||||
#endif
|
||||
#ifdef HAVE_LASTLOG_H
|
||||
# include <lastlog.h>
|
||||
#endif
|
||||
#ifdef HAVE_LOGIN_H
|
||||
# include <login.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
/* This is done in do_authentication */
|
||||
# define DISABLE_LASTLOG
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
#include "loginrec.h"
|
||||
|
||||
/*
|
||||
* Returns the time when the user last logged in. Returns 0 if the
|
||||
@ -49,248 +28,32 @@ RCSID("$Id: login.c,v 1.30 2000/05/31 03:57:19 damien Exp $");
|
||||
* The host the user logged in from will be returned in buf.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Returns the time when the user last logged in (or 0 if no previous login
|
||||
* is found). The name of the host used last time is returned in buf.
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
get_last_login_time(uid_t uid, const char *logname,
|
||||
char *buf, unsigned int bufsize)
|
||||
{
|
||||
#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
|
||||
struct lastlog ll;
|
||||
int fd;
|
||||
# ifdef LASTLOG_IS_DIR
|
||||
char lbuf[1024];
|
||||
struct logininfo li;
|
||||
|
||||
snprintf(lbuf, sizeof(buf), "%s/%s", _PATH_LASTLOG, logname);
|
||||
if ((fd = open(lbuf, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
# else /* LASTLOG_IS_DIR */
|
||||
buf[0] = '\0';
|
||||
|
||||
if ((fd = open(_PATH_LASTLOG, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
|
||||
lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
|
||||
# endif /* LASTLOG_IS_DIR */
|
||||
if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
if (bufsize > sizeof(ll.ll_host) + 1)
|
||||
bufsize = sizeof(ll.ll_host) + 1;
|
||||
strncpy(buf, ll.ll_host, bufsize - 1);
|
||||
buf[bufsize - 1] = 0;
|
||||
|
||||
return ll.ll_time;
|
||||
#else /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
|
||||
# ifdef HAVE_TYPE_IN_UTMP
|
||||
/* Look in wtmp for the last login */
|
||||
struct utmp wt;
|
||||
int fd1;
|
||||
unsigned long t = 0;
|
||||
|
||||
if ((fd1 = open(_PATH_WTMP, O_RDONLY)) < 0) {
|
||||
error("Couldn't open %.100s to find last login time.", _PATH_WTMP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* seek to last record of file */
|
||||
lseek(fd1, (off_t)(0 - sizeof(struct utmp)), SEEK_END);
|
||||
|
||||
/* loop through wtmp for our last user login record */
|
||||
do {
|
||||
if (read(fd1, &wt, sizeof(wt)) != sizeof(wt)) {
|
||||
close(fd1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (wt.ut_type == USER_PROCESS) {
|
||||
if (!strncmp(logname, wt.ut_user, 8)) {
|
||||
t = (unsigned long)wt.ut_time;
|
||||
# ifdef HAVE_HOST_IN_UTMP
|
||||
if (bufsize > sizeof(wt.ut_host) + 1)
|
||||
bufsize = sizeof(wt.ut_host) + 1;
|
||||
strncpy(buf, wt.ut_host, bufsize - 1);
|
||||
buf[bufsize - 1] = 0;
|
||||
# else /* HAVE_HOST_IN_UTMP */
|
||||
buf[0] = 0;
|
||||
# endif /* HAVE_HOST_IN_UTMP */
|
||||
}
|
||||
}
|
||||
|
||||
if (lseek(fd1, (off_t)(0 - (2 * sizeof(struct utmp))), SEEK_CUR) < 0)
|
||||
break;
|
||||
} while (t == 0);
|
||||
|
||||
return t;
|
||||
# else /* HAVE_TYPE_IN_UTMP */
|
||||
return 0;
|
||||
# endif /* HAVE_TYPE_IN_UTMP */
|
||||
#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
|
||||
login_getlastentry_uid(&li, uid);
|
||||
strncpy(buf, li.hostname, bufsize);
|
||||
return li.tv_sec;
|
||||
}
|
||||
|
||||
/*
|
||||
* Records that the user has logged in. I wish these parts of operating
|
||||
* systems were more standardized.
|
||||
* Records that the user has logged in. I these parts of operating systems
|
||||
* were more standardized.
|
||||
*/
|
||||
|
||||
void
|
||||
record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
|
||||
const char *host, struct sockaddr * addr)
|
||||
{
|
||||
#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
|
||||
struct lastlog ll;
|
||||
# ifdef LASTLOG_IS_DIR
|
||||
char buf[1024];
|
||||
# endif /* LASTLOG_IS_DIR */
|
||||
#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
|
||||
struct utmp u;
|
||||
#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
|
||||
struct utmpx utx;
|
||||
#endif
|
||||
struct logininfo *li;
|
||||
|
||||
/* Construct an utmp/wtmp entry. */
|
||||
memset(&u, 0, sizeof(u));
|
||||
strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line));
|
||||
|
||||
#if defined(HAVE_ID_IN_UTMP)
|
||||
# ifdef _AIX
|
||||
strncpy(u.ut_id, ttyname + 5, sizeof(u.ut_id));
|
||||
# else /* !AIX */
|
||||
strncpy(u.ut_id, ttyname + 8, sizeof(u.ut_id));
|
||||
# endif
|
||||
#endif /* defined(HAVE_ID_IN_UTMP) */
|
||||
|
||||
strncpy(u.ut_name, user, sizeof(u.ut_name));
|
||||
|
||||
#if defined(HAVE_TV_IN_UTMP)
|
||||
(void)gettimeofday(&u.ut_tv, NULL);
|
||||
#else /* defined(HAVE_TV_IN_UTMP) */
|
||||
u.ut_time = time(NULL);
|
||||
#endif /* defined(HAVE_TV_IN_UTMP) */
|
||||
|
||||
#if defined(HAVE_PID_IN_UTMP)
|
||||
u.ut_pid = (pid_t)pid;
|
||||
#endif /* HAVE_PID_IN_UTMP */
|
||||
|
||||
#if defined(HAVE_TYPE_IN_UTMP)
|
||||
u.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS;
|
||||
#endif /* HAVE_TYPE_IN_UTMP */
|
||||
|
||||
#if defined(HAVE_HOST_IN_UTMP)
|
||||
strncpy(u.ut_host, host, sizeof(u.ut_host));
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ADDR_IN_UTMP)
|
||||
if (addr) {
|
||||
switch (addr->sa_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *in = (struct sockaddr_in*)addr;
|
||||
memcpy(&(u.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr)));
|
||||
break;
|
||||
}
|
||||
# if defined(HAVE_ADDR_V6_IN_UTMP)
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
|
||||
memcpy(u.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr)));
|
||||
break;
|
||||
}
|
||||
# endif /* defined(HAVE_ADDR_V6_IN_UTMP) */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* defined(HAVE_ADDR_IN_UTMP) */
|
||||
|
||||
#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
|
||||
memset(&utx, 0, sizeof(utx));
|
||||
|
||||
strncpy(utx.ut_user, user, sizeof(utx.ut_name));
|
||||
strncpy(utx.ut_line, ttyname + 5, sizeof(utx.ut_line));
|
||||
strncpy(utx.ut_id, ttyname + 8, sizeof(utx.ut_id));
|
||||
|
||||
utx.ut_pid = (pid_t)pid;
|
||||
(void)gettimeofday(&utx.ut_tv, NULL);
|
||||
|
||||
utx.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS;
|
||||
# ifdef HAVE_HOST_IN_UTMPX
|
||||
# ifdef HAVE_SYSLEN_IN_UTMPX
|
||||
utx.ut_syslen = strlen(host);
|
||||
if (utx.ut_syslen + 1 > sizeof(utx.ut_host))
|
||||
utx.ut_syslen = sizeof(utx.ut_host);
|
||||
strncpy(utx.ut_host, host, utx.ut_syslen);
|
||||
# else
|
||||
strncpy(utx.ut_host, host, sizeof(utx.ut_host));
|
||||
# endif /* HAVE_SYSLEN_IN_UTMPX */
|
||||
utx.ut_host[sizeof(utx.ut_host)-1] = '\0';
|
||||
# endif
|
||||
|
||||
# if defined(HAVE_ADDR_IN_UTMPX)
|
||||
if (addr) {
|
||||
switch (addr->sa_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *in = (struct sockaddr_in*)addr;
|
||||
memcpy(&(utx.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr)));
|
||||
break;
|
||||
}
|
||||
# if defined(HAVE_ADDR_V6_IN_UTMPX)
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
|
||||
memcpy(utx.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr)));
|
||||
break;
|
||||
}
|
||||
# endif /* defined(HAVE_ADDR_V6_IN_UTMPX) */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
# endif /* defined(HAVE_ADDR_IN_UTMPX) */
|
||||
#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
|
||||
|
||||
#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
|
||||
login(&utx);
|
||||
#else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
|
||||
login(&u);
|
||||
#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
|
||||
|
||||
#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
|
||||
/* Update lastlog unless actually recording a logout. */
|
||||
if (strcmp(user, "") != 0) {
|
||||
int fd;
|
||||
/*
|
||||
* It is safer to bzero the lastlog structure first because
|
||||
* some systems might have some extra fields in it (e.g. SGI)
|
||||
*/
|
||||
memset(&ll, 0, sizeof(ll));
|
||||
|
||||
/* Update lastlog. */
|
||||
ll.ll_time = time(NULL);
|
||||
strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line));
|
||||
strncpy(ll.ll_host, host, sizeof(ll.ll_host));
|
||||
# ifdef LASTLOG_IS_DIR
|
||||
snprintf(buf, sizeof(buf), "%s/%s", _PATH_LASTLOG, user);
|
||||
if ((fd = open(buf, O_RDWR)) >= 0) {
|
||||
if (write(fd, &ll, sizeof(ll)) != sizeof(ll))
|
||||
log("Could not write %.100s: %.100s", buf, strerror(errno));
|
||||
close(fd);
|
||||
}
|
||||
# else /* LASTLOG_IS_DIR */
|
||||
if ((fd = open(_PATH_LASTLOG, O_RDWR)) >= 0) {
|
||||
lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
|
||||
if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) {
|
||||
log("Could not write %.100s: %.100s", _PATH_LASTLOG,
|
||||
strerror(errno));
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
# endif /* LASTLOG_IS_DIR */
|
||||
}
|
||||
#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
|
||||
li = login_alloc_entry(pid, user, host, ttyname);
|
||||
login_set_ip4(li, (struct sockaddr_in *)addr);
|
||||
login_login(li);
|
||||
login_free_entry(li);
|
||||
}
|
||||
|
||||
/* Records that the user has logged out. */
|
||||
@ -298,11 +61,9 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
|
||||
void
|
||||
record_logout(pid_t pid, const char *ttyname)
|
||||
{
|
||||
#ifdef HAVE_LIBUTIL_LOGIN
|
||||
const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */
|
||||
if (logout(line))
|
||||
logwtmp(line, "", "");
|
||||
#else /* HAVE_LIBUTIL_LOGIN */
|
||||
record_login(pid, ttyname, "", -1, "", NULL);
|
||||
#endif /* HAVE_LIBUTIL_LOGIN */
|
||||
struct logininfo *li;
|
||||
|
||||
li = login_alloc_entry(pid, NULL, NULL, ttyname);
|
||||
login_logout(li);
|
||||
login_free_entry(li);
|
||||
}
|
||||
|
1385
loginrec.c
Normal file
1385
loginrec.c
Normal file
File diff suppressed because it is too large
Load Diff
167
loginrec.h
Normal file
167
loginrec.h
Normal file
@ -0,0 +1,167 @@
|
||||
#ifndef _HAVE_LOGINREC_H_
|
||||
#define _HAVE_LOGINREC_H_
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Andre Lucas. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 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
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
** loginrec.h: platform-independent login recording and lastlog retrieval
|
||||
**/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* RCSID("$Id: loginrec.h,v 1.1 2000/06/03 14:57:40 andre Exp $"); */
|
||||
|
||||
/**
|
||||
** you should use the login_* calls to work around platform dependencies
|
||||
**/
|
||||
|
||||
/* check if we have IP6 on this system */
|
||||
#if defined(AF_INET6) || defined(INET6_ADDRSTRLEN)
|
||||
# define LOGIN_HAVE_IP6
|
||||
#endif
|
||||
|
||||
/*
|
||||
* login_netinfo structure
|
||||
*/
|
||||
|
||||
struct login_netinfo {
|
||||
struct sockaddr_in sa_in4;
|
||||
#ifdef LOGIN_HAVE_IP6
|
||||
struct sockaddr_in6 sa_in6;
|
||||
#endif
|
||||
|
||||
}; /* struct login_netinfo */
|
||||
|
||||
|
||||
/*
|
||||
* * logininfo structure *
|
||||
*/
|
||||
|
||||
/* types - different to utmp.h 'type' macros */
|
||||
/* (though set to the same value as linux, openbsd and others...) */
|
||||
#define LTYPE_LOGIN 7
|
||||
#define LTYPE_LOGOUT 8
|
||||
|
||||
/* string lengths - set very long */
|
||||
#define LINFO_PROGSIZE 64
|
||||
#define LINFO_LINESIZE 64
|
||||
#define LINFO_NAMESIZE 64
|
||||
#define LINFO_HOSTSIZE 256
|
||||
|
||||
struct logininfo {
|
||||
|
||||
char progname[LINFO_PROGSIZE]; /* name of program (for PAM) */
|
||||
int progname_null;
|
||||
|
||||
short int type; /* type of login (LTYPE_*) */
|
||||
|
||||
int pid; /* PID of login process */
|
||||
int uid; /* UID of this user */
|
||||
char line[LINFO_LINESIZE]; /* tty/pty name */
|
||||
char username[LINFO_NAMESIZE]; /* login username */
|
||||
char hostname[LINFO_HOSTSIZE]; /* remote hostname */
|
||||
|
||||
/* 'exit_status' structure components */
|
||||
int exit; /* process exit status */
|
||||
int termination; /* process termination status */
|
||||
|
||||
/* struct timeval (sys/time.h) isn't always available, if it isn't we'll
|
||||
* use time_t's value as tv_sec and set tv_usec to 0
|
||||
*/
|
||||
unsigned int tv_sec;
|
||||
unsigned int tv_usec;
|
||||
|
||||
struct login_netinfo hostaddr; /* caller's host address(es) */
|
||||
|
||||
}; /* struct logininfo */
|
||||
|
||||
|
||||
/*
|
||||
* login recording functions
|
||||
*/
|
||||
/* construct a new login entry */
|
||||
struct logininfo *login_alloc_entry(int pid,
|
||||
const char *username,
|
||||
const char *hostname, const char *line);
|
||||
void login_free_entry(struct logininfo *li);
|
||||
int login_init_entry(struct logininfo *li,
|
||||
int pid, const char *username,
|
||||
const char *hostname, const char *line);
|
||||
void login_set_progname(struct logininfo *li,
|
||||
const char *progname);
|
||||
/* set the type field (skip if using ...login or ...logout) */
|
||||
void login_set_type(struct logininfo *li, int type);
|
||||
void login_set_pid(struct logininfo *li, int pid);
|
||||
void login_set_uid(struct logininfo *li, int uid);
|
||||
void login_set_line(struct logininfo *li, const char *line);
|
||||
void login_set_username(struct logininfo *li, const char *username);
|
||||
void login_set_hostname(struct logininfo *li, const char *hostname);
|
||||
/* set the exit status (used by [uw]tmpx) */
|
||||
void login_set_exitstatus(struct logininfo *li, int exit, int termination);
|
||||
void login_set_time(struct logininfo *li, unsigned int tv_sec,
|
||||
unsigned int tv_usec);
|
||||
void login_set_current_time(struct logininfo *li);
|
||||
/* set the network address based on network address type */
|
||||
void login_set_ip4(struct logininfo *li,
|
||||
const struct sockaddr_in *sa_in4);
|
||||
# ifdef LOGIN_HAVE_IP6
|
||||
void login_set_ip6(struct logininfo *li,
|
||||
const struct sockaddr_in6 *sa_in6);
|
||||
# endif /* LOGIN_HAVE_IP6 */
|
||||
/* record the entry */
|
||||
int login_write (struct logininfo *li);
|
||||
int login_login (struct logininfo *li);
|
||||
int login_logout(struct logininfo *li);
|
||||
int login_log_entry(struct logininfo *li);
|
||||
|
||||
/*
|
||||
* login record retrieval functions
|
||||
*/
|
||||
/* lastlog *entry* functions fill out a logininfo */
|
||||
struct logininfo *login_getlastentry_name(struct logininfo *li,
|
||||
const char *username);
|
||||
struct logininfo *login_getlastentry_uid(struct logininfo *li,
|
||||
const int pid);
|
||||
/* lastlog *time* functions return time_t equivalent (uint) */
|
||||
unsigned int login_getlasttime_name(const char *username);
|
||||
unsigned int login_getlasttime_uid(const int pid);
|
||||
|
||||
/* produce various forms of the line filename */
|
||||
char *line_fullname(char *dst, const char *src, int dstsize);
|
||||
char *line_stripname(char *dst, const char *src, int dstsize);
|
||||
char *line_abbrevname(char *dst, const char *src, int dstsize);
|
||||
|
||||
|
||||
#endif /* _HAVE_LOGINREC_H_ */
|
||||
|
307
logintest.c
Normal file
307
logintest.c
Normal file
@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Andre Lucas. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 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
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
** logintest.c: simple test driver for platform-independent login recording
|
||||
** and lastlog retrieval
|
||||
**/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
#include <netdb.h>
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#include "loginrec.h"
|
||||
|
||||
RCSID("$Id: logintest.c,v 1.1 2000/06/03 14:57:40 andre Exp $");
|
||||
|
||||
|
||||
int nologtest = 0;
|
||||
int compile_opts_only = 0;
|
||||
int be_verbose = 0;
|
||||
|
||||
|
||||
#define DOTQUAD_MAXSIZE 17
|
||||
void dump_dotquad(char *s, struct in_addr *sin4) {
|
||||
unsigned int addr;
|
||||
|
||||
addr = ntohl(sin4->s_addr);
|
||||
snprintf(s, DOTQUAD_MAXSIZE, "%d.%d.%d.%d",
|
||||
(addr >> 24)& 0xff, (addr >>16) & 0xff,
|
||||
(addr >>8) & 0xff, addr & 0xff );
|
||||
} /* dump_dotquad */
|
||||
|
||||
|
||||
/* Dump a logininfo to stdout. Assumes a tab size of 8 chars. */
|
||||
void dump_logininfo(struct logininfo *li, char *descname) {
|
||||
char a4[DOTQUAD_MAXSIZE];
|
||||
|
||||
dump_dotquad(a4, &(li->hostaddr.sa_in4.sin_addr));
|
||||
|
||||
/* yes I know how nasty this is */
|
||||
printf("struct logininfo %s = {\n\t"
|
||||
"progname\t'%s'\n\ttype\t\t%d\n\t"
|
||||
"pid\t\t%d\n\tuid\t\t%d\n\t"
|
||||
"line\t\t'%s'\n\tusername\t'%s'\n\t"
|
||||
"hostname\t'%s'\n\texit\t\t%d\n\ttermination\t%d\n\t"
|
||||
"tv_sec\t%d\n\ttv_usec\t%d\n\t"
|
||||
"struct login_netinfo hostaddr {\n\t\t"
|
||||
"struct sockaddr_in sa_in4 {\n"
|
||||
"\t\t\tsin_port\t%d\n\t\t\t*sin_addr\t%d(%s)\n\t\t}\n"
|
||||
"\t\t** !!! IP6 stuff not supported yet **\n"
|
||||
"\t}\n"
|
||||
"}\n",
|
||||
descname, li->progname, li->type,
|
||||
li->pid, li->uid, li->line,
|
||||
li->username, li->hostname, li->exit,
|
||||
li->termination, li->tv_sec, li->tv_usec,
|
||||
ntohs(li->hostaddr.sa_in4.sin_port),
|
||||
ntohl(li->hostaddr.sa_in4.sin_addr.s_addr), a4);
|
||||
/* FIXME: (ATL) print sockaddr_in6 stuff */
|
||||
}
|
||||
|
||||
|
||||
int testAPI() {
|
||||
struct logininfo *li1;
|
||||
struct passwd *pw;
|
||||
struct hostent *he;
|
||||
struct sockaddr_in sa_in4;
|
||||
char cmdstring[256], stripline[8];
|
||||
char username[32];
|
||||
#ifdef HAVE_TIME_H
|
||||
time_t t0, t1, t2;
|
||||
char s_t0[64],s_t1[64],s_t2[64]; /* ctime() strings */
|
||||
#endif
|
||||
|
||||
printf("**\n** Testing the API...\n**\n");
|
||||
|
||||
pw = getpwuid(getuid());
|
||||
strlcpy(username, pw->pw_name, sizeof(username));
|
||||
|
||||
/* gethostname(hostname, sizeof(hostname)); */
|
||||
|
||||
printf("login_alloc_entry test (no host info):\n");
|
||||
/* !!! fake tty more effectively */
|
||||
li1 = login_alloc_entry((int)getpid(), username, NULL, ttyname(0));
|
||||
login_set_progname(li1, "testlogin");
|
||||
|
||||
if (be_verbose)
|
||||
dump_logininfo(li1, "li1");
|
||||
|
||||
printf("Setting IPv4 host info for 'localhost' (may call out):\n");
|
||||
if (! (he = gethostbyname("localhost"))) {
|
||||
printf("Couldn't set hostname(lookup failed)\n");
|
||||
} else {
|
||||
/* NOTE: this is messy, but typically a program wouldn't have to set
|
||||
* any of this, a sockaddr_in* would be already prepared */
|
||||
memcpy((void *)&(sa_in4.sin_addr), (void *)&(he->h_addr_list[0][0]),
|
||||
sizeof(struct in_addr));
|
||||
login_set_ip4(li1, &sa_in4);
|
||||
login_set_hostname(li1, "localhost");
|
||||
}
|
||||
if (be_verbose)
|
||||
dump_logininfo(li1, "li1");
|
||||
|
||||
if ((int)geteuid() != 0) {
|
||||
printf("NOT RUNNING LOGIN TESTS - you are not root!\n");
|
||||
return 1; /* this isn't necessarily an error */
|
||||
}
|
||||
|
||||
if (nologtest)
|
||||
return 1;
|
||||
|
||||
line_stripname(stripline, li1->line, sizeof(stripline));
|
||||
|
||||
printf("Performing an invalid login attempt (no type field)\n--\n");
|
||||
login_write(li1);
|
||||
printf("--\n(Should have written an error to stderr)\n");
|
||||
|
||||
#ifdef HAVE_TIME_H
|
||||
(void)time(&t0);
|
||||
strlcpy(s_t0, ctime(&t0), sizeof(s_t0));
|
||||
t1 = login_getlasttime_uid(getuid());
|
||||
strlcpy(s_t1, ctime(&t1), sizeof(s_t1));
|
||||
printf("Before logging in:\n\tcurrent time is %d - %s\t"
|
||||
"lastlog time is %d - %s\n",
|
||||
(int)t0, s_t0, (int)t1, s_t1);
|
||||
#endif
|
||||
|
||||
printf("Performing a login on line %s...\n--\n", stripline);
|
||||
login_login(li1);
|
||||
|
||||
snprintf(cmdstring, sizeof(cmdstring), "who | grep '%s '",
|
||||
stripline);
|
||||
system(cmdstring);
|
||||
|
||||
printf("--\nWaiting for a few seconds...\n");
|
||||
sleep(2);
|
||||
|
||||
printf("Performing a logout (the root login "
|
||||
"shown above should be gone)\n"
|
||||
"If the root login hasn't gone, but another user on the same\n"
|
||||
"pty has, this is OK - we're hacking it here, and there\n"
|
||||
"shouldn't be two users on one pty in reality...\n"
|
||||
"-- ('who' output follows)\n");
|
||||
login_logout(li1);
|
||||
|
||||
system(cmdstring);
|
||||
printf("-- ('who' output ends)\n");
|
||||
|
||||
#ifdef HAVE_TIME_H
|
||||
t2 = login_getlasttime_uid(getuid());
|
||||
strlcpy(s_t2, ctime(&t2), sizeof(s_t2));
|
||||
printf("After logging in, lastlog time is %d - %s\n", (int)t2, s_t2);
|
||||
if (t1 == t2)
|
||||
printf("The lastlog times before and after logging in are the "
|
||||
"same.\nThis indicates that lastlog is ** NOT WORKING "
|
||||
"CORRECTLY **\n");
|
||||
else if (t0 != t2)
|
||||
printf("** The login time and the lastlog time differ.\n"
|
||||
"** This indicates that lastlog is either recording the "
|
||||
"wrong time,\n** or retrieving the wrong entry.\n");
|
||||
else
|
||||
printf("lastlog agrees with the login time. This is a good thing.\n");
|
||||
|
||||
#endif
|
||||
|
||||
printf("--\nThe output of 'last' shown next should have "
|
||||
"an entry for root \n on %s for the time shown above:\n--\n",
|
||||
stripline);
|
||||
snprintf(cmdstring, sizeof(cmdstring), "last | grep '%s ' | head -3",
|
||||
stripline);
|
||||
system(cmdstring);
|
||||
|
||||
printf("--\nEnd of login test.\n");
|
||||
|
||||
login_free_entry(li1);
|
||||
|
||||
return 1;
|
||||
} /* testAPI() */
|
||||
|
||||
|
||||
void testLineName(char *line) {
|
||||
/* have to null-terminate - these functions are designed for
|
||||
* structures with fixed-length char arrays, and don't null-term.*/
|
||||
char full[17], strip[9], abbrev[5];
|
||||
|
||||
memset(full, '\0', sizeof(full));
|
||||
memset(strip, '\0', sizeof(strip));
|
||||
memset(abbrev, '\0', sizeof(abbrev));
|
||||
|
||||
line_fullname(full, line, sizeof(full)-1);
|
||||
line_stripname(strip, full, sizeof(strip)-1);
|
||||
line_abbrevname(abbrev, full, sizeof(abbrev)-1);
|
||||
printf("%s: %s, %s, %s\n", line, full, strip, abbrev);
|
||||
|
||||
} /* testLineName() */
|
||||
|
||||
|
||||
int testOutput() {
|
||||
printf("**\n** Testing linename functions\n**\n");
|
||||
testLineName("/dev/pts/1");
|
||||
testLineName("pts/1");
|
||||
testLineName("pts/999");
|
||||
testLineName("/dev/ttyp00");
|
||||
testLineName("ttyp00");
|
||||
|
||||
return 1;
|
||||
} /* testOutput() */
|
||||
|
||||
|
||||
/* show which options got compiled in */
|
||||
void showOptions(void) {
|
||||
|
||||
printf("**\n** Compile-time options\n**\n");
|
||||
|
||||
printf("login recording methods selected:\n");
|
||||
#ifdef USE_LOGIN
|
||||
printf("\tUSE_LOGIN\n");
|
||||
#endif
|
||||
#ifdef USE_UTMP
|
||||
printf("\tUSE_UTMP (UTMP_FILE=%s)\n", UTMP_FILE);
|
||||
#endif
|
||||
#ifdef USE_UTMPX
|
||||
printf("\tUSE_UTMPX (UTMPX_FILE=%s)\n", UTMPX_FILE);
|
||||
#endif
|
||||
#ifdef USE_WTMP
|
||||
printf("\tUSE_WTMP (WTMP_FILE=%s)\n", WTMP_FILE);
|
||||
#endif
|
||||
#ifdef USE_WTMPX
|
||||
printf("\tUSE_WTMPX (WTMPX_FILE=%s)\n", WTMPX_FILE);
|
||||
#endif
|
||||
#ifdef USE_LASTLOG
|
||||
printf("\tUSE_LASTLOG (LASTLOG_FILE=%s)\n", LASTLOG_FILE);
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("IP6 support: %s\n",
|
||||
#ifdef HAVE_IP6
|
||||
"enabled"
|
||||
#else
|
||||
"disabled"
|
||||
#endif
|
||||
);
|
||||
|
||||
|
||||
} /* showOptions() */
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
printf("Platform-independent login recording test driver");
|
||||
|
||||
if (argc == 2) {
|
||||
if (strncmp(argv[1], "-i", 3) == 0)
|
||||
compile_opts_only = 1;
|
||||
else if (strncmp(argv[1], "-v", 3) == 0)
|
||||
be_verbose=1;
|
||||
}
|
||||
|
||||
if (!compile_opts_only) {
|
||||
if (be_verbose && !testOutput())
|
||||
return 1;
|
||||
|
||||
if (!testAPI())
|
||||
return 1;
|
||||
}
|
||||
|
||||
showOptions();
|
||||
|
||||
return 0;
|
||||
} /* main() */
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "bsd-mktemp.h"
|
||||
#include "bsd-snprintf.h"
|
||||
#include "bsd-daemon.h"
|
||||
#include "bsd-login.h"
|
||||
#include "bsd-base64.h"
|
||||
|
||||
/* rfc2553 socket API replacements */
|
||||
|
Loading…
Reference in New Issue
Block a user