[PATCH] support for wtmpdb (Y2038 safe wtmp replacement)

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

 



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

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux