From a4cd87e9dce6d38846f23d44df9e21f322f946df Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 5 Feb 2014 20:34:11 +0100 Subject: [PATCH] man: introduce new "Desktop" property for sessions This is initialized from XDG_SESSION_DESKTOP and is useful for GNOME to recognize its own sessions. It's supposed to be set to a short string identifying the session, such as "kde" or "gnome". --- man/pam_systemd.xml | 60 +++++++++++++++++++++++++++++++++ src/login/loginctl.c | 5 +++ src/login/logind-dbus.c | 27 +++++++++++---- src/login/logind-session-dbus.c | 1 + src/login/logind-session.c | 5 +++ src/login/logind-session.h | 1 + src/login/pam-module.c | 32 ++++++++++-------- 7 files changed, 111 insertions(+), 20 deletions(-) diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml index f312ef2b99a..66d40fca451 100644 --- a/man/pam_systemd.xml +++ b/man/pam_systemd.xml @@ -222,6 +222,66 @@ operating system provides. + + + + The following environment variables are read by + the module and may be used by the PAM service to pass + meta data to the module: + + + + $XDG_SESSION_TYPE + + The session type. This + may be used instead of + on the + module parameter line, and is usually + preferred. + + + + $XDG_SESSION_CLASS + + The session class. This + may be used instead of + on the + module parameter line, and is usually + preferred. + + + + $XDG_SESSION_DESKTOP + + The session + deskop. This may be used to indicate + the session desktop used, where this + applies. This should be a short, + lowercase string identifying the + desktop environment used if this + information is available. For example: + gnome, or + kde. + + + + $XDG_SEAT + + The seat name the session + shall be registered for, if + any. + + + + $XDG_VTNR + + The VT number the + session shall be registered for, if + any. (Only applies to seats with a VT + available, such as + seat0) + + diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 6900253b0d4..ebe9c1f16ce 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -271,6 +271,7 @@ typedef struct SessionStatusInfo { const char *class; const char *state; const char *scope; + const char *desktop; } SessionStatusInfo; typedef struct UserStatusInfo { @@ -363,6 +364,7 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li { "RemoteHost", "s", NULL, offsetof(SessionStatusInfo, remote_host) }, { "RemoteUser", "s", NULL, offsetof(SessionStatusInfo, remote_user) }, { "Service", "s", NULL, offsetof(SessionStatusInfo, service) }, + { "Desktop", "s", NULL, offsetof(SessionStatusInfo, desktop) }, { "Type", "s", NULL, offsetof(SessionStatusInfo, type) }, { "Class", "s", NULL, offsetof(SessionStatusInfo, class) }, { "Scope", "s", NULL, offsetof(SessionStatusInfo, scope) }, @@ -462,6 +464,9 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li } else if (i.class) printf("\t Class: %s\n", i.class); + if (!isempty(i.desktop)) + printf("\t Desktop: %s\n", i.desktop); + if (i.state) printf("\t State: %s\n", i.state); diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 2c86b9fa264..47459617733 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -450,7 +450,7 @@ static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *us } static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { - const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host; + const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop; uint32_t uid, leader, audit_id = 0; _cleanup_free_ char *id = NULL; Session *session = NULL; @@ -467,7 +467,7 @@ static int method_create_session(sd_bus *bus, sd_bus_message *message, void *use assert(message); assert(m); - r = sd_bus_message_read(message, "uussssussbss", &uid, &leader, &service, &type, &class, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host); + r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host); if (r < 0) return r; @@ -490,6 +490,13 @@ static int method_create_session(sd_bus *bus, sd_bus_message *message, void *use return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class); } + if (isempty(desktop)) + desktop = NULL; + else { + if (!string_is_safe(desktop)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop); + } + if (isempty(cseat)) seat = NULL; else { @@ -550,10 +557,10 @@ static int method_create_session(sd_bus *bus, sd_bus_message *message, void *use } if (c == _SESSION_CLASS_INVALID) { - if (!isempty(display) || !isempty(tty)) - c = SESSION_USER; - else + if (t == SESSION_UNSPECIFIED) c = SESSION_BACKGROUND; + else + c = SESSION_USER; } if (leader <= 0) { @@ -687,6 +694,14 @@ static int method_create_session(sd_bus *bus, sd_bus_message *message, void *use } } + if (!isempty(desktop)) { + session->desktop = strdup(desktop); + if (!session->desktop) { + r = -ENOMEM; + goto fail; + } + } + if (seat) { r = seat_attach_session(seat, session); if (r < 0) @@ -1864,7 +1879,7 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshusub", method_create_session, 0), + SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0), SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0), SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED), diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 54ad827feb2..7ee49562cf1 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -444,6 +444,7 @@ const sd_bus_vtable session_vtable[] = { SD_BUS_PROPERTY("RemoteHost", "s", NULL, offsetof(Session, remote_host), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RemoteUser", "s", NULL, offsetof(Session, remote_user), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 4f3259ca7cd..ca2e48570c7 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -143,6 +143,7 @@ void session_free(Session *s) { free(s->remote_host); free(s->remote_user); free(s->service); + free(s->desktop); hashmap_remove(s->manager->sessions, s->id); @@ -229,6 +230,9 @@ int session_save(Session *s) { if (s->service) fprintf(f, "SERVICE=%s\n", s->service); + if (s->desktop) + fprintf(f, "DESKTOP=%s\n", s->desktop); + if (s->seat && seat_has_vts(s->seat)) fprintf(f, "VTNR=%u\n", s->vtnr); @@ -294,6 +298,7 @@ int session_load(Session *s) { "REMOTE_HOST", &s->remote_host, "REMOTE_USER", &s->remote_user, "SERVICE", &s->service, + "DESKTOP", &s->desktop, "VTNR", &vtnr, "POS", &pos, "LEADER", &leader, diff --git a/src/login/logind-session.h b/src/login/logind-session.h index 202d28752f0..7bf19320323 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -87,6 +87,7 @@ struct Session { char *remote_user; char *remote_host; char *service; + char *desktop; char *scope; char *scope_job; diff --git a/src/login/pam-module.c b/src/login/pam-module.c index 9f0f7d18665..3b2966b30cf 100644 --- a/src/login/pam-module.c +++ b/src/login/pam-module.c @@ -212,7 +212,7 @@ _public_ PAM_EXTERN int pam_sm_open_session( *remote_user = NULL, *remote_host = NULL, *seat = NULL, *type = NULL, *class = NULL, - *class_pam = NULL, *type_pam = NULL, *cvtnr = NULL; + *class_pam = NULL, *type_pam = NULL, *cvtnr = NULL, *desktop = NULL; _cleanup_bus_unref_ sd_bus *bus = NULL; int session_fd = -1, existing, r; bool debug = false, remote; @@ -303,8 +303,11 @@ _public_ PAM_EXTERN int pam_sm_open_session( if (isempty(class)) class = class_pam; + desktop = pam_getenv(handle, "XDG_SESSION_DESKTOP"); + if (isempty(desktop)) + desktop = getenv("XDG_SESSION_DESKTOP"); + tty = strempty(tty); - display = strempty(display); if (strchr(tty, ':')) { /* A tty with a colon is usually an X11 display, @@ -314,21 +317,21 @@ _public_ PAM_EXTERN int pam_sm_open_session( if (isempty(display)) display = tty; - tty = ""; + tty = NULL; } else if (streq(tty, "cron")) { /* cron has been setting PAM_TTY to "cron" for a very * long time and it probably shouldn't stop doing that * for compatibility reasons. */ type = "unspecified"; class = "background"; - tty = ""; + tty = NULL; } 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. */ type ="tty"; class = "user"; - tty = ""; + tty = NULL; } /* If this fails vtnr will be 0, that's intended */ @@ -368,11 +371,11 @@ _public_ PAM_EXTERN int pam_sm_open_session( if (debug) pam_syslog(handle, LOG_DEBUG, "Asking logind to create session: " - "uid=%u pid=%u service=%s type=%s class=%s seat=%s vtnr=%u tty=%s display=%s remote=%s remote_user=%s remote_host=%s", + "uid=%u pid=%u service=%s type=%s class=%s desktop=%s seat=%s vtnr=%u tty=%s display=%s remote=%s remote_user=%s remote_host=%s", pw->pw_uid, getpid(), strempty(service), - type, class, - strempty(seat), vtnr, tty, strempty(display), + type, class, desktop, + strempty(seat), vtnr, strempty(tty), strempty(display), yes_no(remote), strempty(remote_user), strempty(remote_host)); r = sd_bus_call_method(bus, @@ -382,19 +385,20 @@ _public_ PAM_EXTERN int pam_sm_open_session( "CreateSession", &error, &reply, - "uussssussbssa(sv)", + "uusssssussbssa(sv)", (uint32_t) pw->pw_uid, (uint32_t) getpid(), - strempty(service), + service, type, class, - strempty(seat), + desktop, + seat, vtnr, tty, - strempty(display), + display, remote, - strempty(remote_user), - strempty(remote_host), + remote_user, + remote_host, 0); if (r < 0) { pam_syslog(handle, LOG_ERR, "Failed to create session: %s", bus_error_message(&error, r));