[gdm/wip/rancell/guest] Add guest support



commit a7bdf3447b7b2c0577c8347a08b2294cd06d04ce
Author: Robert Ancell <robert ancell canonical com>
Date:   Mon Dec 4 12:14:36 2017 +1300

    Add guest support

 daemon/gdm-session-worker.c |   83 ++++++++++++++++++++++++++++++++++++++++++
 daemon/gdm-session.c        |   85 +++++++++++++++++++++++++++++++++++++++++--
 daemon/gdm-session.h        |    3 ++
 daemon/gdm-session.xml      |    4 ++
 4 files changed, 171 insertions(+), 4 deletions(-)
---
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index 34b3bf7..c39d084 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -148,6 +148,7 @@ struct GdmSessionWorkerPrivate
         char             *display_device;
         char             *display_seat_id;
         char             *hostname;
+        gboolean          guest;
         char             *username;
         char             *log_file;
         char             *session_id;
@@ -1779,6 +1780,31 @@ run_script (GdmSessionWorker *worker,
 }
 
 static void
+cleanup_account (GdmSessionWorker *worker)
+{
+        g_autoptr(GDBusConnection) connection = NULL;
+        g_autoptr(GVariant) reply = NULL;
+
+        if (!worker->priv->guest)
+                return;
+
+        connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
+        if (connection == NULL)
+                return;
+
+        reply = g_dbus_connection_call_sync (connection,
+                                             "org.freedesktop.Accounts",
+                                             "/org/freedesktop/Accounts",
+                                             "org.freedesktop.Accounts",
+                                             "DeleteGuest",
+                                             g_variant_new ("(x)", worker->priv->uid),
+                                             G_VARIANT_TYPE ("(o)"),
+                                             G_DBUS_CALL_FLAGS_NONE,
+                                             -1,
+                                             NULL, NULL);
+}
+
+static void
 session_worker_child_watch (GPid              pid,
                             int               status,
                             GdmSessionWorker *worker)
@@ -1792,6 +1818,7 @@ session_worker_child_watch (GPid              pid,
                  : WIFSIGNALED (status) ? WTERMSIG (status)
                  : -1);
 
+        cleanup_account (worker);
 
         gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS);
 
@@ -2573,6 +2600,56 @@ on_saved_session_name_read (GdmSessionWorker *worker)
         g_free (session_name);
 }
 
+static gboolean
+setup_account (GdmSessionWorker *worker, GError **error)
+{
+        g_autoptr(GDBusConnection) connection = NULL;
+        g_autoptr(GVariant) reply = NULL;
+        g_autoptr(GVariant) username_reply = NULL;
+        g_autoptr(GVariant) username_value = NULL;
+        const gchar *path;
+
+        if (!worker->priv->guest)
+                return TRUE;
+
+        connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
+        if (connection == NULL)
+                return FALSE;
+
+        reply = g_dbus_connection_call_sync (connection,
+                                             "org.freedesktop.Accounts",
+                                             "/org/freedesktop/Accounts",
+                                             "org.freedesktop.Accounts",
+                                             "CreateGuest",
+                                             NULL, /* parameters */
+                                             G_VARIANT_TYPE ("(o)"),
+                                             G_DBUS_CALL_FLAGS_NONE,
+                                             -1,
+                                             NULL, error);
+        if (reply == NULL)
+                return FALSE;
+
+        g_variant_get (reply, "(&o)", &path);
+        username_reply = g_dbus_connection_call_sync (connection,
+                                                      "org.freedesktop.Accounts",
+                                                      path,
+                                                      "org.freedesktop.DBus.Properties",
+                                                      "Get",
+                                                      g_variant_new ("(ss)", 
"org.freedesktop.Accounts.User", "UserName"),
+                                                      G_VARIANT_TYPE ("(v)"),
+                                                      G_DBUS_CALL_FLAGS_NONE,
+                                                      -1,
+                                                      NULL, error);
+        if (username_reply == NULL)
+                return FALSE;
+
+        g_variant_get (username_reply, "(v)", &username_value);
+        g_free (worker->priv->username);
+        worker->priv->username = g_variant_dup_string (username_value, NULL);
+
+        return TRUE;
+}
+
 static void
 do_setup (GdmSessionWorker *worker)
 {
@@ -2580,6 +2657,10 @@ do_setup (GdmSessionWorker *worker)
         gboolean res;
 
         error = NULL;
+        if (!setup_account (worker, &error)) {
+                g_dbus_method_invocation_take_error (worker->priv->pending_invocation, error);
+        }
+
         res = gdm_session_worker_initialize_pam (worker,
                                                  worker->priv->service,
                                                  (const char **) worker->priv->extensions,
@@ -2995,6 +3076,8 @@ gdm_session_worker_handle_initialize (GdmDBusWorker         *object,
                         worker->priv->service = g_variant_dup_string (value, NULL);
                 } else if (g_strcmp0 (key, "extensions") == 0) {
                         worker->priv->extensions = filter_extensions (g_variant_get_strv (value, NULL));
+                } else if (g_strcmp0 (key, "guest") == 0) {
+                        worker->priv->guest = g_variant_get_boolean (value);
                 } else if (g_strcmp0 (key, "username") == 0) {
                         worker->priv->username = g_variant_dup_string (value, NULL);
                 } else if (g_strcmp0 (key, "is-program-session") == 0) {
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 610ebcd..92ea725 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -69,6 +69,7 @@ typedef struct
         GPid                   worker_pid;
         char                  *service_name;
         GDBusMethodInvocation *starting_invocation;
+        gboolean               starting_guest;
         char                  *starting_username;
         GDBusMethodInvocation *pending_invocation;
         GdmDBusWorkerManager  *worker_manager_interface;
@@ -87,6 +88,7 @@ struct _GdmSessionPrivate
         char                *selected_session;
         char                *saved_session;
         char                *saved_language;
+        gboolean             selected_guest;
         char                *selected_user;
         char                *user_x11_authority_file;
 
@@ -637,6 +639,7 @@ gdm_session_select_user (GdmSession *self,
 
         g_debug ("GdmSession: Setting user: '%s'", text);
 
+        self->priv->selected_guest = FALSE;
         g_free (self->priv->selected_user);
         self->priv->selected_user = g_strdup (text);
 
@@ -647,6 +650,22 @@ gdm_session_select_user (GdmSession *self,
         self->priv->saved_language = NULL;
 }
 
+void
+gdm_session_select_guest (GdmSession *self)
+{
+        g_debug ("GdmSession: Setting guest");
+
+        self->priv->selected_guest = TRUE;
+        g_free (self->priv->selected_user);
+        self->priv->selected_user = NULL;
+
+        g_free (self->priv->saved_session);
+        self->priv->saved_session = NULL;
+
+        g_free (self->priv->saved_language);
+        self->priv->saved_language = NULL;
+}
+
 static void
 cancel_pending_query (GdmSessionConversation *conversation)
 {
@@ -1132,7 +1151,9 @@ register_worker (GdmDBusWorkerManager  *worker_manager_interface,
         }
 
         if (conversation->starting_invocation != NULL) {
-                if (conversation->starting_username != NULL) {
+                if (conversation->starting_guest) {
+                        gdm_session_setup_for_guest (self, conversation->service_name);
+                } else if (conversation->starting_username != NULL) {
                         gdm_session_setup_for_user (self, conversation->service_name, 
conversation->starting_username);
 
                         g_clear_pointer (&conversation->starting_username,
@@ -1363,6 +1384,24 @@ gdm_session_handle_client_begin_verification_for_user (GdmDBusUserVerifier    *u
 }
 
 static gboolean
+gdm_session_handle_client_begin_verification_for_guest (GdmDBusUserVerifier    *user_verifier_interface,
+                                                        GDBusMethodInvocation  *invocation,
+                                                        const char             *service_name,
+                                                        GdmSession             *self)
+{
+        GdmSessionConversation *conversation;
+
+        conversation = begin_verification_conversation (self, invocation, service_name);
+
+        if (conversation != NULL) {
+                conversation->starting_invocation = g_object_ref (invocation);
+                conversation->starting_username = g_strdup ("*guest");
+        }
+
+        return TRUE;
+}
+
+static gboolean
 gdm_session_handle_client_answer_query (GdmDBusUserVerifier    *user_verifier_interface,
                                         GDBusMethodInvocation  *invocation,
                                         const char             *service_name,
@@ -1415,6 +1454,19 @@ gdm_session_handle_client_select_user (GdmDBusGreeter        *greeter_interface,
 }
 
 static gboolean
+gdm_session_handle_client_select_guest (GdmDBusGreeter        *greeter_interface,
+                                        GDBusMethodInvocation *invocation,
+                                        GdmSession            *self)
+{
+        if (self->priv->greeter_interface != NULL) {
+                gdm_dbus_greeter_complete_select_guest (greeter_interface,
+                                                        invocation);
+        }
+        gdm_session_select_guest (self);
+        return TRUE;
+}
+
+static gboolean
 gdm_session_handle_client_start_session_when_ready (GdmDBusGreeter        *greeter_interface,
                                                     GDBusMethodInvocation *invocation,
                                                     const char            *service_name,
@@ -1495,6 +1547,10 @@ export_user_verifier_interface (GdmSession      *self,
                           G_CALLBACK (gdm_session_handle_client_begin_verification_for_user),
                           self);
         g_signal_connect (user_verifier_interface,
+                          "handle-begin-verification-for-guest",
+                          G_CALLBACK (gdm_session_handle_client_begin_verification_for_guest),
+                          self);
+        g_signal_connect (user_verifier_interface,
                           "handle-answer-query",
                           G_CALLBACK (gdm_session_handle_client_answer_query),
                           self);
@@ -1532,6 +1588,10 @@ export_greeter_interface (GdmSession      *self,
                           G_CALLBACK (gdm_session_handle_client_select_user),
                           self);
         g_signal_connect (greeter_interface,
+                          "handle-select-guest",
+                          G_CALLBACK (gdm_session_handle_client_select_guest),
+                          self);
+        g_signal_connect (greeter_interface,
                           "handle-start-session-when-ready",
                           G_CALLBACK (gdm_session_handle_client_start_session_when_ready),
                           self);
@@ -2224,6 +2284,7 @@ on_initialization_complete_cb (GdmDBusWorker *proxy,
 static void
 initialize (GdmSession *self,
             const char *service_name,
+            gboolean    guest,
             const char *username,
             const char *log_file)
 {
@@ -2240,6 +2301,9 @@ initialize (GdmSession *self,
 
         g_variant_builder_add_parsed (&details, "{'extensions', <%^as>}", extensions);
 
+        if (guest)
+                g_variant_builder_add_parsed (&details, "{'guest', <%b>}", guest);
+
         if (username != NULL)
                 g_variant_builder_add_parsed (&details, "{'username', <%s>}", username);
 
@@ -2294,7 +2358,7 @@ gdm_session_setup (GdmSession *self,
 
         update_session_type (self);
 
-        initialize (self, service_name, NULL, NULL);
+        initialize (self, service_name, FALSE, NULL, NULL);
 }
 
 
@@ -2312,7 +2376,20 @@ gdm_session_setup_for_user (GdmSession *self,
         gdm_session_select_user (self, username);
 
         self->priv->is_program_session = FALSE;
-        initialize (self, service_name, self->priv->selected_user, NULL);
+        initialize (self, service_name, FALSE, self->priv->selected_user, NULL);
+}
+
+void
+gdm_session_setup_for_guest (GdmSession *self,
+                             const char *service_name)
+{
+
+        g_return_if_fail (GDM_IS_SESSION (self));
+
+        update_session_type (self);
+
+        self->priv->is_program_session = FALSE;
+        initialize (self, service_name, TRUE, NULL, NULL);
 }
 
 void
@@ -2325,7 +2402,7 @@ gdm_session_setup_for_program (GdmSession *self,
         g_return_if_fail (GDM_IS_SESSION (self));
 
         self->priv->is_program_session = TRUE;
-        initialize (self, service_name, username, log_file);
+        initialize (self, service_name, FALSE, username, log_file);
 }
 
 void
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
index a22c095..3ad0a73 100644
--- a/daemon/gdm-session.h
+++ b/daemon/gdm-session.h
@@ -152,6 +152,8 @@ void              gdm_session_setup                       (GdmSession *session,
 void              gdm_session_setup_for_user              (GdmSession *session,
                                                            const char *service_name,
                                                            const char *username);
+void              gdm_session_setup_for_guest             (GdmSession *session,
+                                                           const char *service_name);
 void              gdm_session_setup_for_program           (GdmSession *session,
                                                            const char *service_name,
                                                            const char *username,
@@ -184,6 +186,7 @@ void              gdm_session_select_session              (GdmSession *session,
                                                            const char *session_name);
 void              gdm_session_select_user                 (GdmSession *session,
                                                            const char *username);
+void              gdm_session_select_guest                (GdmSession *session);
 void              gdm_session_set_timed_login_details     (GdmSession *session,
                                                            const char *username,
                                                            int         delay);
diff --git a/daemon/gdm-session.xml b/daemon/gdm-session.xml
index 137be5e..a77b69c 100644
--- a/daemon/gdm-session.xml
+++ b/daemon/gdm-session.xml
@@ -40,6 +40,9 @@
       <arg name="service_name" direction="in" type="s"/>
       <arg name="username" direction="in" type="s"/>
     </method>
+    <method name="BeginVerificationForGuest">
+      <arg name="service_name" direction="in" type="s"/>
+    </method>
     <method name="AnswerQuery">
       <arg name="service_name" direction="in" type="s"/>
       <arg name="answer" direction="in" type="s"/>
@@ -102,6 +105,7 @@
     <method name="SelectUser">
       <arg name="username" direction="in" type="s"/>
     </method>
+    <method name="SelectGuest" />
     <method name="BeginAutoLogin">
       <arg name="username" direction="in" type="s"/>
     </method>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]