Add wtmpdb support as Y2038 safe wtmp replacement

This commit is contained in:
Thorsten Kukuk
2024-11-19 10:53:28 +01:00
committed by Damien Miller
parent 1d9563a56f
commit 96b64056c8
4 changed files with 119 additions and 5 deletions

View File

@@ -60,6 +60,7 @@ GSSLIBS=@GSSLIBS@
SSHDLIBS=@SSHDLIBS@
LIBEDIT=@LIBEDIT@
LIBFIDO2=@LIBFIDO2@
LIBWTMPDB=@LIBWTMPDB@
AR=@AR@
AWK=@AWK@
RANLIB=@RANLIB@
@@ -234,10 +235,10 @@ sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS)
sshd-session$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_SESSION_OBJS)
$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS)
$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB)
sshd-auth$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_AUTH_OBJS)
$(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS)
$(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB)
scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS)
$(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)

View File

@@ -1772,6 +1772,48 @@ AC_ARG_WITH([libedit],
fi ]
)
# Check whether user wants wtmpdb support
WTMPDB_MSG="no"
AC_ARG_WITH([wtmpdb],
[ --with-wtmpdb[[=PATH]] Enable wtmpdb support for sshd],
[ if test "x$withval" != "xno" ; then
if test "x$withval" = "xyes" ; then
if test "x$PKGCONFIG" != "xno"; then
AC_MSG_CHECKING([if $PKGCONFIG knows about wtmpdb])
if "$PKGCONFIG" libwtmpdb; then
AC_MSG_RESULT([yes])
use_pkgconfig_for_libwtmpdb=yes
else
AC_MSG_RESULT([no])
fi
fi
else
CPPFLAGS="$CPPFLAGS -I${withval}/include"
if test -n "${rpath_opt}"; then
LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}"
else
LDFLAGS="-L${withval}/lib ${LDFLAGS}"
fi
fi
if test "x$use_pkgconfig_for_libwtmpdb" = "xyes"; then
LIBWTMPDB=`$PKGCONFIG --libs libwtmpdb`
CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libwtmpdb`"
else
LIBWTMPDB="-lwtmpdb"
fi
OTHERLIBS=`echo $LIBWTMPDB | sed 's/-lwtmpdb//'`
AC_CHECK_LIB([wtmpdb], [wtmpdb_login],
[ AC_DEFINE([USE_WTMPDB], [1], [Use libwtmpdb for sshd])
WTMPDB_MSG="yes"
AC_SUBST([LIBWTMPDB])
],
[ AC_MSG_ERROR([libwtmpdb not found]) ],
[ $OTHERLIBS ]
)
fi ]
)
AUDIT_MODULE=none
AC_ARG_WITH([audit],
[ --with-audit=module Enable audit support (modules=debug,bsm,linux)],

View File

@@ -166,6 +166,10 @@
# include <util.h>
#endif
#ifdef USE_WTMPDB
# include <wtmpdb.h>
#endif
/**
** prototypes for helper functions in this file
**/
@@ -186,6 +190,9 @@ int wtmp_write_entry(struct logininfo *li);
int wtmpx_write_entry(struct logininfo *li);
int lastlog_write_entry(struct logininfo *li);
int syslogin_write_entry(struct logininfo *li);
#ifdef USE_WTMPDB
int wtmpdb_write_entry(struct logininfo *li);
#endif
int getlast_entry(struct logininfo *li);
int lastlog_get_entry(struct logininfo *li);
@@ -446,6 +453,9 @@ login_write(struct logininfo *li)
#ifdef USE_WTMPX
wtmpx_write_entry(li);
#endif
#ifdef USE_WTMPDB
wtmpdb_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,
@@ -1391,6 +1401,64 @@ wtmpx_get_entry(struct logininfo *li)
}
#endif /* USE_WTMPX */
#ifdef USE_WTMPDB
static int
wtmpdb_perform_login(struct logininfo *li)
{
uint64_t login_time = li->tv_sec * ((uint64_t) 1000000ULL) +
li->tv_usec;
const char *tty;
if (strncmp(li->line, "/dev/", 5) == 0)
tty = &(li->line[5]);
else
tty = li->line;
li->wtmpdb_id = wtmpdb_login(NULL, USER_PROCESS, li->username,
login_time, tty, li->hostname, 0, 0);
if (li->wtmpdb_id < 0)
return (0);
return (1);
}
static int
wtmpdb_perform_logout(struct logininfo *li)
{
uint64_t logout_time = li->tv_sec * ((uint64_t) 1000000ULL) +
li->tv_usec;
if (li->wtmpdb_id == 0) {
const char *tty;
if (strncmp(li->line, "/dev/", 5) == 0)
tty = &(li->line[5]);
else
tty = li->line;
li->wtmpdb_id = wtmpdb_get_id(NULL, tty, NULL);
}
wtmpdb_logout(NULL, li->wtmpdb_id, logout_time, NULL);
return (1);
}
int
wtmpdb_write_entry(struct logininfo *li)
{
switch(li->type) {
case LTYPE_LOGIN:
return (wtmpdb_perform_login(li));
case LTYPE_LOGOUT:
return (wtmpdb_perform_logout(li));
default:
logit("%s: invalid type field", __func__);
return (0);
}
}
#endif
/**
** Low-level libutil login() functions
**/
@@ -1529,10 +1597,10 @@ lastlog_write_entry(struct logininfo *li)
strlcpy(last.ll_host, li->hostname,
MIN_SIZEOF(last.ll_host, li->hostname));
last.ll_time = li->tv_sec;
if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT))
return (0);
/* write the entry */
if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) {
close(fd);
@@ -1540,7 +1608,7 @@ lastlog_write_entry(struct logininfo *li)
LASTLOG_FILE, strerror(errno));
return (0);
}
close(fd);
return (1);
default:

View File

@@ -79,6 +79,9 @@ struct logininfo {
unsigned int tv_sec;
unsigned int tv_usec;
union login_netinfo hostaddr; /* caller's host address(es) */
#ifdef USE_WTMPDB
int64_t wtmpdb_id; /* ID for wtmpdb_logout */
#endif
}; /* struct logininfo */
/*