diff options
author | Robert Ancell <robert.ancell@canonical.com> | 2017-12-04 12:14:36 +1300 |
---|---|---|
committer | Robert Ancell <robert.ancell@canonical.com> | 2018-01-19 15:12:12 +1300 |
commit | 9c47689700ad2441e3fdcdecbdea223e5e0cf3ec (patch) | |
tree | 266f83c470ca0bc7ea7379aabfa9899d1ed40c30 | |
parent | e7fdf1899cfeb5fbd512f2ea48ad18623f6a7732 (diff) | |
download | gdm-wip/rancell/guest.tar.gz |
Add guest supportwip/rancell/guest
-rw-r--r-- | daemon/gdm-session-worker.c | 83 | ||||
-rw-r--r-- | daemon/gdm-session.c | 87 | ||||
-rw-r--r-- | daemon/gdm-session.h | 3 | ||||
-rw-r--r-- | daemon/gdm-session.xml | 3 |
4 files changed, 172 insertions, 4 deletions
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c index 34b3bf7f..c39d084b 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 610ebcd0..d5ed6de1 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, @@ -1337,6 +1358,7 @@ gdm_session_handle_client_begin_verification (GdmDBusUserVerifier *user_verif if (conversation != NULL) { conversation->starting_invocation = g_object_ref (invocation); + conversation->starting_guest = FALSE; conversation->starting_username = NULL; } @@ -1356,6 +1378,7 @@ gdm_session_handle_client_begin_verification_for_user (GdmDBusUserVerifier *u if (conversation != NULL) { conversation->starting_invocation = g_object_ref (invocation); + conversation->starting_guest = FALSE; conversation->starting_username = g_strdup (username); } @@ -1363,6 +1386,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, + GdmSession *self) +{ + GdmSessionConversation *conversation; + + conversation = begin_verification_conversation (self, invocation, "gdm-autologin"); + + if (conversation != NULL) { + conversation->starting_invocation = g_object_ref (invocation); + conversation->starting_guest = TRUE; + conversation->starting_username = NULL; + } + + return TRUE; +} + +static gboolean gdm_session_handle_client_answer_query (GdmDBusUserVerifier *user_verifier_interface, GDBusMethodInvocation *invocation, const char *service_name, @@ -1415,6 +1456,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 +1549,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 +1590,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 +2286,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 +2303,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 +2360,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 +2378,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 +2404,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 a22c0954..3ad0a737 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 137be5e2..e1ca91c2 100644 --- a/daemon/gdm-session.xml +++ b/daemon/gdm-session.xml @@ -40,6 +40,8 @@ <arg name="service_name" direction="in" type="s"/> <arg name="username" direction="in" type="s"/> </method> + <method name="BeginVerificationForGuest"> + </method> <method name="AnswerQuery"> <arg name="service_name" direction="in" type="s"/> <arg name="answer" direction="in" type="s"/> @@ -102,6 +104,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> |