chiark / gitweb /
man: introduce new "Desktop" property for sessions
authorLennart Poettering <lennart@poettering.net>
Wed, 5 Feb 2014 19:34:11 +0000 (20:34 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 5 Feb 2014 19:44:49 +0000 (20:44 +0100)
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
src/login/loginctl.c
src/login/logind-dbus.c
src/login/logind-session-dbus.c
src/login/logind-session.c
src/login/logind-session.h
src/login/pam-module.c

index f312ef2b99ab4926d193a5f49feab57c4d45d1d2..66d40fca451d6088f92ebe9ae00df3292c81b69d 100644 (file)
                                 operating system
                                 provides.</para></listitem>
                         </varlistentry>
+
+                </variablelist>
+
+                <para>The following environment variables are read by
+                the module and may be used by the PAM service to pass
+                meta data to the module:</para>
+
+                <variablelist class='environment-variables'>
+                        <varlistentry>
+                                <term><varname>$XDG_SESSION_TYPE</varname></term>
+
+                                <listitem><para>The session type. This
+                                may be used instead of
+                                <option>session=</option> on the
+                                module parameter line, and is usually
+                                preferred.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$XDG_SESSION_CLASS</varname></term>
+
+                                <listitem><para>The session class. This
+                                may be used instead of
+                                <option>class=</option> on the
+                                module parameter line, and is usually
+                                preferred.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$XDG_SESSION_DESKTOP</varname></term>
+
+                                <listitem><para>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:
+                                <literal>gnome</literal>, or
+                                <literal>kde</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$XDG_SEAT</varname></term>
+
+                                <listitem><para>The seat name the session
+                                shall be registered for, if
+                                any.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$XDG_VTNR</varname></term>
+
+                                <listitem><para>The VT number the
+                                session shall be registered for, if
+                                any. (Only applies to seats with a VT
+                                available, such as
+                                <literal>seat0</literal>)</para></listitem>
+                        </varlistentry>
+
                 </variablelist>
         </refsect1>
 
index 6900253b0d47a9a1ace0be8254f2e8ba4f46277d..ebe9c1f16ce55be5cb62433cb7da8ecce67f99fa 100644 (file)
@@ -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);
 
index 2c86b9fa264d6ab7069b3e88ec4de9aedfb4811b..47459617733da9f6295729173bc442c384e31f66 100644 (file)
@@ -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),
index 54ad827feb27a6711f4cf5d0fea5cfa28c57c769..7ee49562cf1539193483f021c58be8eb80bd21e9 100644 (file)
@@ -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),
index 4f3259ca7cd6f3edf7cfa69ab08f1cef4fd59e0d..ca2e48570c74c1a12b47565521f032a693e23801 100644 (file)
@@ -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,
index 202d28752f0ca6bea96af189fa173eebc34bc4f2..7bf19320323817694ea994223845055186ab5c1b 100644 (file)
@@ -87,6 +87,7 @@ struct Session {
         char *remote_user;
         char *remote_host;
         char *service;
+        char *desktop;
 
         char *scope;
         char *scope_job;
index 9f0f7d186657f52f200c4cea736c6b3a06b8515c..3b2966b30cf833fa37d78f13922c19ee3cedeb8c 100644 (file)
@@ -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));