Hi, On Linux, glibc is using a 32bit time_t for wtmp and similar structs even on a 64bit system: https://www.thkukuk.de/blog/Y2038_glibc_utmp_64bit/ https://www.thkukuk.de/blog/Y2038_glibc_wtmp_64bit/ Since the glibc developers stated that they don't plan to solve the problem in glibc, but think that this interfaces are legacy and should be removed from glibc (like musl libc, which does not have them), I implemented with wtmpdb a Y2038 safe alternative to wtmp. https://github.com/thkukuk/wtmpdb Like pam_systemd it in most cases all data with a PAM module "pam_wtmpdb", but sshd is a little bit special here: when it does the authentication, the TTY isn't yet known. For this reason, we cannot use the PAM module with sshd, but need support via the wtmpdb library. Attached is a patch which adds wtmpdb support in the same way as for wtmp and utmp. Comments? Thorsten -- Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, Germany Managing Director: Ivo Totev, Andrew Myers, Andrew McDonald, Martje Boudien Moerman (HRB 36809, AG Nürnberg)
diff -ur openssh-8.9p1.old/configure.ac openssh-8.9p1/configure.ac --- openssh-8.9p1.old/configure.ac 2022-02-23 12:31:11.000000000 +0100 +++ openssh-8.9p1/configure.ac 2023-04-17 14:52:21.499002203 +0200 @@ -1703,6 +1703,49 @@ 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 + AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no]) + 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)], diff -ur openssh-8.9p1.old/loginrec.c openssh-8.9p1/loginrec.c --- openssh-8.9p1.old/loginrec.c 2022-02-23 12:31:11.000000000 +0100 +++ openssh-8.9p1/loginrec.c 2023-04-18 10:05:04.311193333 +0200 @@ -187,6 +187,10 @@ # include <util.h> #endif +#ifdef USE_WTMPDB +# include <wtmpdb.h> +#endif + /** ** prototypes for helper functions in this file **/ @@ -207,6 +211,9 @@ 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); @@ -467,6 +474,9 @@ #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, @@ -1409,6 +1419,64 @@ } #endif /* USE_WTMPX */ +#ifdef USE_WTMPDB +static int +wtmpdb_perform_login(struct logininfo *li) +{ + usec_t login_time = li->tv_sec * USEC_PER_SEC + 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) +{ + usec_t logout_time = li->tv_sec * USEC_PER_SEC + 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 **/ diff -ur openssh-8.9p1.old/loginrec.h openssh-8.9p1/loginrec.h --- openssh-8.9p1.old/loginrec.h 2022-02-23 12:31:11.000000000 +0100 +++ openssh-8.9p1/loginrec.h 2023-04-17 14:58:20.808850750 +0200 @@ -79,6 +79,9 @@ 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 */ /* diff -ur openssh-8.9p1.old/Makefile.in openssh-8.9p1/Makefile.in --- openssh-8.9p1.old/Makefile.in 2022-02-23 12:31:11.000000000 +0100 +++ openssh-8.9p1/Makefile.in 2023-04-17 14:44:32.156538001 +0200 @@ -55,6 +55,7 @@ SSHDLIBS=@SSHDLIBS@ LIBEDIT=@LIBEDIT@ LIBFIDO2=@LIBFIDO2@ +LIBWTMPDB=@LIBWTMPDB@ AR=@AR@ AWK=@AWK@ RANLIB=@RANLIB@ @@ -212,7 +213,7 @@ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(GSSLIBS) sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) - $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(LIBWTMPDB) scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS) $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
_______________________________________________ openssh-unix-dev mailing list openssh-unix-dev@xxxxxxxxxxx https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev