File logind_set_tty.patch of Package openssh
Index: openssh-10.0p1/Makefile.in
===================================================================
--- openssh-10.0p1.orig/Makefile.in
+++ openssh-10.0p1/Makefile.in
@@ -64,6 +64,7 @@ SSHDLIBS=@SSHDLIBS@
LIBEDIT=@LIBEDIT@
LIBFIDO2=@LIBFIDO2@
LIBWTMPDB=@LIBWTMPDB@
+LIBSYSTEMD=@LIBSYSTEMD@
AR=@AR@
AWK=@AWK@
RANLIB=@RANLIB@
@@ -244,7 +245,7 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SS
$(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(GSSLIBS) $(CHANNELLIBS)
sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS)
+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS) $(LIBSYSTEMD)
sshd-session$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_SESSION_OBJS)
$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB)
Index: openssh-10.0p1/configure.ac
===================================================================
--- openssh-10.0p1.orig/configure.ac
+++ openssh-10.0p1/configure.ac
@@ -1872,6 +1872,47 @@ AC_ARG_WITH([wtmpdb],
)
+# Check whether user wants logind/set tty support
+AC_ARG_WITH([logind],
+ [ --with-logind[[=PATH]] Enable logind 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 libsystemd])
+ if "$PKGCONFIG" libsystemd; then
+ AC_MSG_RESULT([yes])
+ use_pkgconfig_for_libsystemd=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_libsystemd" = "xyes"; then
+ LIBSYSTEMD=`$PKGCONFIG --libs libsystemd`
+ CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libsystemd`"
+ else
+ LIBSYSTEMD="-lsystemd"
+ fi
+ OTHERLIBS=`echo $LIBSYSTEMD | sed 's/-lsystemd//'`
+ AC_CHECK_LIB([systemd], [sd_bus_open_system],
+ [ AC_DEFINE([USE_LOGIND], [1], [Use systemd-logind])
+ AC_SUBST([LIBSYSTEMD])
+ ],
+ [ AC_MSG_ERROR([libsystemd not found]) ],
+ [ $OTHERLIBS ]
+ )
+ fi ]
+)
+
+
AUDIT_MODULE=none
AC_ARG_WITH([audit],
[ --with-audit=module Enable audit support (modules=debug,bsm,linux)],
Index: openssh-10.0p1/loginrec.c
===================================================================
--- openssh-10.0p1.orig/loginrec.c
+++ openssh-10.0p1/loginrec.c
@@ -170,6 +170,10 @@
# include <wtmpdb.h>
#endif
+#ifdef USE_LOGIND
+# include <systemd/sd-bus.h>
+#endif
+
/**
** prototypes for helper functions in this file
**/
@@ -193,6 +197,9 @@ int syslogin_write_entry(struct logininf
#ifdef USE_WTMPDB
int wtmpdb_write_entry(struct logininfo *li);
#endif
+#ifdef USE_LOGIND
+int logind_set_tty(struct logininfo *li);
+#endif
int getlast_entry(struct logininfo *li);
int lastlog_get_entry(struct logininfo *li);
@@ -456,6 +463,9 @@ login_write(struct logininfo *li)
#ifdef USE_WTMPDB
wtmpdb_write_entry(li);
#endif
+#ifdef USE_LOGIND
+ logind_set_tty(li);
+#endif
#ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN
if (li->type == LTYPE_LOGIN &&
!sys_auth_record_login(li->username,li->hostname,li->line,
@@ -1459,6 +1469,100 @@ wtmpdb_write_entry(struct logininfo *li)
default:
logit("%s: invalid type field", __func__);
return (0);
+ }
+}
+#endif
+
+#ifdef USE_LOGIND
+#define DBUS_DESTINATION "org.freedesktop.login1"
+#define DBUS_PATH_ID "/org/freedesktop/login1/session/auto"
+#define DBUS_INTERFACE "org.freedesktop.login1.Session"
+#define DBUS_PATH "/org/freedesktop/login1/session/%s"
+
+static int
+logind_perform_login(struct logininfo *li)
+{
+ sd_bus *bus = NULL;
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ char *session_id = NULL;
+ char *dbus_path;
+ const char *tty;
+ char buf[PATH_MAX];
+ int r;
+ int fd;
+
+ if (sd_bus_open_system(&bus) < 0)
+ {
+ logit("logind: canot open dbus");
+ return (0);
+ }
+
+ if (sd_bus_get_property_string(bus, DBUS_DESTINATION,
+ DBUS_PATH_ID, DBUS_INTERFACE,
+ "Id", &error, &session_id) < 0)
+ {
+ logit("logind: cannot get session ID");
+ sd_bus_unref(bus);
+ return (0);
+ }
+
+ if (strncmp(li->line, "/dev/", 5) != 0)
+ snprintf (buf, sizeof(buf), "/dev/%s", li->line);
+ else
+ tty = li->line;
+
+ fd = open(tty, O_RDWR|O_CLOEXEC|O_NOCTTY);
+
+ if (asprintf (&dbus_path, DBUS_PATH, session_id) < 0)
+ {
+ sd_bus_unref(bus);
+ return (0);
+ }
+
+ if (sd_bus_call_method(bus, DBUS_DESTINATION, dbus_path,
+ DBUS_INTERFACE, "TakeControl", &error, NULL,
+ "b", 1) < 0) {
+ logit("logind: cannot take control");
+ free(dbus_path);
+ sd_bus_unref(bus);
+ return (0);
+ }
+
+ if ((r = sd_bus_call_method(bus, DBUS_DESTINATION, dbus_path,
+ DBUS_INTERFACE, "SetTTY", &error, NULL,
+ "h", fd)) < 0) {
+ if (r != -EBADR) /* logind does not support "SetTTY" */
+ logit("logind: cannot set TTY(%s, %s): %s", session_id, tty, strerror(-r));
+ else
+ logit("logind: logind does not support SetTTY (%s, %s): %s", session_id, tty, strerror(-r));
+ free(dbus_path);
+ sd_bus_unref(bus);
+ return (0);
+ }
+
+ free(dbus_path);
+
+ if (r = sd_bus_flush(bus) < 0) {
+ logit("logind: bus flush failed: %s", strerror(-r));
+ sd_bus_unref(bus);
+ return (0);
+ }
+
+ sd_bus_unref(bus);
+ return (1);
+}
+
+int
+logind_set_tty(struct logininfo *li)
+{
+ switch(li->type) {
+ case LTYPE_LOGIN:
+ return (logind_perform_login(li));
+ case LTYPE_LOGOUT:
+ return (1);
+ default:
+ logit("%s: invalid type field", __func__);
+ return (0);
}
}
#endif