X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flogin%2Fpam-module.c;h=e6764a197affbb34cf1cc03eb9eb140f943400d0;hb=23406ce58aa7142e8df3c5c9e5ac34a01e90e3e0;hp=0d387918c7eac328a63fa6d932ca6c82728f399f;hpb=8e7705e52a5f84489d3037c09fa5f9397185560d;p=elogind.git diff --git a/src/login/pam-module.c b/src/login/pam-module.c index 0d387918c..e6764a197 100644 --- a/src/login/pam-module.c +++ b/src/login/pam-module.c @@ -322,7 +322,7 @@ _public_ PAM_EXTERN int pam_sm_open_session( struct passwd *pw; bool kill_processes = false, debug = false; - const char *username, *id, *object_path, *runtime_path, *service = NULL, *tty = NULL, *display = NULL, *remote_user = NULL, *remote_host = NULL, *seat = NULL, *type, *class, *cvtnr = NULL; + const char *username, *id, *object_path, *runtime_path, *service = NULL, *tty = NULL, *display = NULL, *remote_user = NULL, *remote_host = NULL, *seat = NULL, *type = NULL, *class, *cvtnr = NULL; char **controllers = NULL, **reset_controllers = NULL, **kill_only_users = NULL, **kill_exclude_users = NULL; DBusError error; uint32_t uid, pid; @@ -331,7 +331,7 @@ _public_ PAM_EXTERN int pam_sm_open_session( int session_fd = -1; DBusConnection *bus = NULL; DBusMessage *m = NULL, *reply = NULL; - dbus_bool_t remote; + dbus_bool_t remote, existing; int r; uint32_t vtnr = 0; @@ -428,8 +428,14 @@ _public_ PAM_EXTERN int pam_sm_open_session( pam_get_item(handle, PAM_TTY, (const void**) &tty); pam_get_item(handle, PAM_RUSER, (const void**) &remote_user); pam_get_item(handle, PAM_RHOST, (const void**) &remote_host); + seat = pam_getenv(handle, "XDG_SEAT"); + if (isempty(seat)) + seat = getenv("XDG_SEAT"); + cvtnr = pam_getenv(handle, "XDG_VTNR"); + if (isempty(cvtnr)) + cvtnr = getenv("XDG_VTNR"); service = strempty(service); tty = strempty(tty); @@ -447,9 +453,17 @@ _public_ PAM_EXTERN int pam_sm_open_session( display = tty; tty = ""; } else if (streq(tty, "cron")) { - /* cron has been setting PAM_TTY to "cron" for a very long time - * and it cannot stop doing that for compatibility reasons. */ + /* cron has been setting PAM_TTY to "cron" for a very + * long time and it probably shouldn't stop doing that + * for compatibility reasons. */ + tty = ""; + type = "unspecified"; + } else if (streq(tty, "ssh")) { + /* ssh has been setting PAM_TTY to "ssh" for a very + * long time and probably shouldn't stop doing that + * for compatibility reasons. */ tty = ""; + type ="tty"; } /* If this fails vtnr will be 0, that's intended */ @@ -463,10 +477,13 @@ _public_ PAM_EXTERN int pam_sm_open_session( get_seat_from_display(display, NULL, &vtnr); } - type = !isempty(display) ? "x11" : - !isempty(tty) ? "tty" : "unspecified"; + if (!type) + type = !isempty(display) ? "x11" : + !isempty(tty) ? "tty" : "unspecified"; class = pam_getenv(handle, "XDG_SESSION_CLASS"); + if (isempty(class)) + class = getenv("XDG_SESSION_CLASS"); if (isempty(class)) class = "user"; @@ -535,6 +552,7 @@ _public_ PAM_EXTERN int pam_sm_open_session( DBUS_TYPE_UNIX_FD, &session_fd, DBUS_TYPE_STRING, &seat, DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_BOOLEAN, &existing, DBUS_TYPE_INVALID)) { pam_syslog(handle, LOG_ERR, "Failed to parse message: %s", bus_error_message(&error)); r = PAM_SESSION_ERR; @@ -578,6 +596,12 @@ _public_ PAM_EXTERN int pam_sm_open_session( } } + r = pam_set_data(handle, "systemd.existing", INT_TO_PTR(!!existing), NULL); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to install existing flag."); + return r; + } + if (session_fd >= 0) { r = pam_set_data(handle, "systemd.session-fd", INT_TO_PTR(session_fd+1), NULL); if (r != PAM_SUCCESS) { @@ -620,7 +644,7 @@ _public_ PAM_EXTERN int pam_sm_close_session( int flags, int argc, const char **argv) { - const void *p = NULL; + const void *p = NULL, *existing = NULL; const char *id; DBusConnection *bus = NULL; DBusMessage *m = NULL, *reply = NULL; @@ -631,8 +655,12 @@ _public_ PAM_EXTERN int pam_sm_close_session( dbus_error_init(&error); + /* Only release session if it wasn't pre-existing when we + * tried to create it */ + pam_get_data(handle, "systemd.existing", &existing); + id = pam_getenv(handle, "XDG_SESSION_ID"); - if (id) { + if (id && !existing) { /* Before we go and close the FIFO we need to tell * logind that this is a clean session shutdown, so