From 55efac6cbcea0d8edda9c6820620ceb390009e7a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 14 Feb 2012 21:33:51 +0100 Subject: [PATCH] login: track login class (i.e. one of "user", "greeter", "lock-screen") for each session This introduces the new PAM environment variable XDG_SESSION_CLASS. If not set, defaults to "user". This is useful for apps that want to distuingish real user logins from "fake" ones which just exist to show a gdm login screen or a lock screen. --- src/login/loginctl.c | 14 +++++++++++++- src/login/logind-dbus.c | 16 +++++++++++++++- src/login/logind-session-dbus.c | 3 +++ src/login/logind-session.c | 25 ++++++++++++++++++++++++- src/login/logind-session.h | 12 ++++++++++++ src/login/pam-module.c | 11 +++++++++-- 6 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 7e0056c5..30e97e35 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -349,6 +349,7 @@ typedef struct SessionStatusInfo { const char *service; pid_t leader; const char *type; + const char *class; bool active; } SessionStatusInfo; @@ -431,10 +432,19 @@ static void print_session_status_info(SessionStatusInfo *i) { if (i->type) printf("; type %s", i->type); + if (i->class) + printf("; class %s", i->class); + printf("\n"); - } else if (i->type) + } else if (i->type) { printf("\t Type: %s\n", i->type); + if (i->class) + printf("; class %s", i->class); + } else if (i->class) + printf("\t Class: %s\n", i->class); + + printf("\t Active: %s\n", yes_no(i->active)); if (i->control_group) { @@ -571,6 +581,8 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess i->service = s; else if (streq(name, "Type")) i->type = s; + else if (streq(name, "Class")) + i->class = s; } break; } diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 7794ab91..d8f4d894 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -62,6 +62,7 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -222,11 +223,12 @@ static int bus_manager_append_idle_hint_since(DBusMessageIter *i, const char *pr static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMessage **_reply) { Session *session = NULL; User *user = NULL; - const char *type, *seat, *tty, *display, *remote_user, *remote_host, *service; + const char *type, *class, *seat, *tty, *display, *remote_user, *remote_host, *service; uint32_t uid, leader, audit_id = 0; dbus_bool_t remote, kill_processes; char **controllers = NULL, **reset_controllers = NULL; SessionType t; + SessionClass c; Seat *s; DBusMessageIter iter; int r; @@ -271,6 +273,17 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) return -EINVAL; + dbus_message_iter_get_basic(&iter, &class); + if (isempty(class)) + c = SESSION_USER; + else + c = session_class_from_string(class); + + if (c < 0 || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + dbus_message_iter_get_basic(&iter, &seat); if (isempty(seat)) @@ -467,6 +480,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess session->leader = leader; session->audit_id = audit_id; session->type = t; + session->class = c; session->remote = remote; session->controllers = controllers; session->reset_controllers = reset_controllers; diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 9767f7d3..102f8ac9 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -57,6 +57,7 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -196,6 +197,7 @@ static int bus_session_append_idle_hint_since(DBusMessageIter *i, const char *pr } static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_type, session_type, SessionType); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_class, session_class, SessionClass); static int get_session_for_path(Manager *m, const char *path, Session **_s) { Session *s; @@ -238,6 +240,7 @@ static const BusProperty bus_login_session_properties[] = { { "Leader", bus_property_append_pid, "u", offsetof(Session, leader) }, { "Audit", bus_property_append_uint32, "u", offsetof(Session, audit_id) }, { "Type", bus_session_append_type, "s", offsetof(Session, type) }, + { "Class", bus_session_append_class, "s", offsetof(Session, class) }, { "Active", bus_session_append_active, "b", 0 }, { "Controllers", bus_property_append_strv, "as", offsetof(Session, controllers), true }, { "ResetControllers", bus_property_append_strv, "as", offsetof(Session, reset_controllers), true }, diff --git a/src/login/logind-session.c b/src/login/logind-session.c index c0d95329..af9c12dc 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -145,6 +145,11 @@ int session_save(Session *s) { "TYPE=%s\n", session_type_to_string(s->type)); + if (s->class >= 0) + fprintf(f, + "CLASS=%s\n", + session_class_to_string(s->class)); + if (s->cgroup_path) fprintf(f, "CGROUP=%s\n", @@ -225,7 +230,8 @@ int session_load(Session *s) { *vtnr = NULL, *leader = NULL, *audit_id = NULL, - *type = NULL; + *type = NULL, + *class = NULL; int k, r; @@ -245,6 +251,7 @@ int session_load(Session *s) { "VTNR", &vtnr, "LEADER", &leader, "TYPE", &type, + "CLASS", &class, NULL); if (r < 0) @@ -297,6 +304,14 @@ int session_load(Session *s) { s->type = t; } + if (class) { + SessionClass c; + + c = session_class_from_string(class); + if (c >= 0) + s->class = c; + } + if (s->fifo_path) { int fd; @@ -947,6 +962,14 @@ static const char* const session_type_table[_SESSION_TYPE_MAX] = { DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType); +static const char* const session_class_table[_SESSION_CLASS_MAX] = { + [SESSION_USER] = "user", + [SESSION_GREETER] = "greeter", + [SESSION_LOCK_SCREEN] = "lock-screen" +}; + +DEFINE_STRING_TABLE_LOOKUP(session_class, SessionClass); + static const char* const kill_who_table[_KILL_WHO_MAX] = { [KILL_LEADER] = "leader", [KILL_ALL] = "all" diff --git a/src/login/logind-session.h b/src/login/logind-session.h index 8e394ac0..d0b8c87f 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -38,6 +38,14 @@ typedef enum SessionType { _SESSION_TYPE_INVALID = -1 } SessionType; +typedef enum SessionClass { + SESSION_USER, + SESSION_GREETER, + SESSION_LOCK_SCREEN, + _SESSION_CLASS_MAX, + _SESSION_CLASS_INVALID = -1 +} SessionClass; + typedef enum KillWho { KILL_LEADER, KILL_ALL, @@ -50,6 +58,7 @@ struct Session { char *id; SessionType type; + SessionClass class; char *state_file; @@ -118,6 +127,9 @@ int session_send_lock(Session *s, bool lock); const char* session_type_to_string(SessionType t); SessionType session_type_from_string(const char *s); +const char* session_class_to_string(SessionClass t); +SessionClass session_class_from_string(const char *s); + const char *kill_who_to_string(KillWho k); KillWho kill_who_from_string(const char *s); diff --git a/src/login/pam-module.c b/src/login/pam-module.c index 46509245..8544413a 100644 --- a/src/login/pam-module.c +++ b/src/login/pam-module.c @@ -321,7 +321,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, *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, *class, *cvtnr = NULL; char **controllers = NULL, **reset_controllers = NULL, **kill_only_users = NULL, **kill_exclude_users = NULL; DBusError error; uint32_t uid, pid; @@ -465,13 +465,20 @@ _public_ PAM_EXTERN int pam_sm_open_session( type = !isempty(display) ? "x11" : !isempty(tty) ? "tty" : "unspecified"; - remote = !isempty(remote_host) && !streq(remote_host, "localhost") && !streq(remote_host, "localhost.localdomain"); + class = pam_getenv(handle, "XDG_SESSION_CLASS"); + if (isempty(class)) + class = "user"; + + remote = !isempty(remote_host) && + !streq(remote_host, "localhost") && + !streq(remote_host, "localhost.localdomain"); if (!dbus_message_append_args(m, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_UINT32, &pid, DBUS_TYPE_STRING, &service, DBUS_TYPE_STRING, &type, + DBUS_TYPE_STRING, &class, DBUS_TYPE_STRING, &seat, DBUS_TYPE_UINT32, &vtnr, DBUS_TYPE_STRING, &tty, -- 2.39.5