summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Ancell <robert.ancell@canonical.com>2017-12-04 12:14:36 +1300
committerRobert Ancell <robert.ancell@canonical.com>2018-01-19 15:12:12 +1300
commit9c47689700ad2441e3fdcdecbdea223e5e0cf3ec (patch)
tree266f83c470ca0bc7ea7379aabfa9899d1ed40c30
parente7fdf1899cfeb5fbd512f2ea48ad18623f6a7732 (diff)
downloadgdm-wip/rancell/guest.tar.gz
Add guest supportwip/rancell/guest
-rw-r--r--daemon/gdm-session-worker.c83
-rw-r--r--daemon/gdm-session.c87
-rw-r--r--daemon/gdm-session.h3
-rw-r--r--daemon/gdm-session.xml3
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>