diff options
Diffstat (limited to 'daemon/gdm-welcome-session.c')
-rw-r--r-- | daemon/gdm-welcome-session.c | 483 |
1 files changed, 165 insertions, 318 deletions
diff --git a/daemon/gdm-welcome-session.c b/daemon/gdm-welcome-session.c index 04b3d077..63000f1c 100644 --- a/daemon/gdm-welcome-session.c +++ b/daemon/gdm-welcome-session.c @@ -44,6 +44,8 @@ #include "gdm-common.h" #include "ck-connector.h" +#include "gdm-session.h" +#include "gdm-session-direct.h" #include "gdm-welcome-session.h" #define DBUS_LAUNCH_COMMAND BINDIR "/dbus-launch" @@ -56,10 +58,8 @@ extern char **environ; struct GdmWelcomeSessionPrivate { + GdmSession *session; char *command; - GPid pid; - - CkConnector *ckc; char *user_name; char *group_name; @@ -72,8 +72,6 @@ struct GdmWelcomeSessionPrivate char *x11_authority_file; gboolean x11_display_is_local; - guint child_watch_id; - GPid dbus_pid; char *dbus_bus_address; char *server_dbus_path; @@ -130,116 +128,6 @@ listify_hash (const char *key, g_ptr_array_add (env, str); } -static gboolean -open_welcome_session (GdmWelcomeSession *welcome_session) -{ - struct passwd *pwent; - const char *session_type; - const char *hostname; - const char *x11_display_device; - int res; - gboolean ret; - DBusError error; - - ret = FALSE; - - g_debug ("GdmWelcomeSession: Registering session with ConsoleKit"); - - session_type = "LoginWindow"; - - gdm_get_pwent_for_name (welcome_session->priv->user_name, &pwent); - if (pwent == NULL) { - /* FIXME: */ - g_warning ("Couldn't look up uid"); - goto out; - } - - welcome_session->priv->ckc = ck_connector_new (); - if (welcome_session->priv->ckc == NULL) { - g_warning ("Couldn't create new ConsoleKit connector"); - goto out; - } - - if (welcome_session->priv->x11_display_hostname != NULL) { - hostname = welcome_session->priv->x11_display_hostname; - } else { - hostname = ""; - } - - if (welcome_session->priv->x11_display_device != NULL) { - x11_display_device = welcome_session->priv->x11_display_device; - } else { - x11_display_device = ""; - } - - g_debug ("GdmWelcomeSession: Opening ConsoleKit session for user:%d x11-display:'%s' x11-display-device:'%s' remote-host-name:'%s' is-local:%d", - pwent->pw_uid, - welcome_session->priv->x11_display_name, - x11_display_device, - hostname, - welcome_session->priv->x11_display_is_local); - - dbus_error_init (&error); - res = ck_connector_open_session_with_parameters (welcome_session->priv->ckc, - &error, - "unix-user", &pwent->pw_uid, - "session-type", &session_type, - "x11-display", &welcome_session->priv->x11_display_name, - "x11-display-device", &x11_display_device, - "remote-host-name", &hostname, - "is-local", &welcome_session->priv->x11_display_is_local, - NULL); - if (! res) { - if (dbus_error_is_set (&error)) { - g_warning ("%s\n", error.message); - dbus_error_free (&error); - } else { - g_warning ("cannot open CK session: OOM, D-Bus system bus not available,\n" - "ConsoleKit not available or insufficient privileges.\n"); - } - goto out; - } - - ret = TRUE; - - out: - return ret; -} - -static gboolean -close_welcome_session (GdmWelcomeSession *welcome_session) -{ - int res; - gboolean ret; - DBusError error; - - ret = FALSE; - - if (welcome_session->priv->ckc == NULL) { - return FALSE; - } - - g_debug ("GdmWelcomeSession: De-registering session from ConsoleKit"); - - dbus_error_init (&error); - res = ck_connector_close_session (welcome_session->priv->ckc, &error); - if (! res) { - if (dbus_error_is_set (&error)) { - g_warning ("%s\n", error.message); - dbus_error_free (&error); - } else { - g_warning ("cannot open CK session: OOM, D-Bus system bus not available,\n" - "ConsoleKit not available or insufficient privileges.\n"); - } - goto out; - } - - ret = TRUE; - out: - - return ret; -} - static void load_lang_config_file (const char *config_file, const char **str_array) @@ -343,11 +231,10 @@ next_line: g_free (contents); } -static GPtrArray * -get_welcome_environment (GdmWelcomeSession *welcome_session, - gboolean start_session) +static GHashTable * +build_welcome_environment (GdmWelcomeSession *welcome_session, + gboolean start_session) { - GPtrArray *env; GHashTable *hash; struct passwd *pwent; static const char * const optional_environment[] = { @@ -362,7 +249,6 @@ get_welcome_environment (GdmWelcomeSession *welcome_session, load_lang_config_file (LANG_CONFIG_FILE, (const char **) optional_environment); - env = g_ptr_array_new (); /* create a hash table of current environment, then update keys has necessary */ hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); @@ -400,14 +286,6 @@ get_welcome_environment (GdmWelcomeSession *welcome_session, g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (welcome_session->priv->x11_authority_file)); g_hash_table_insert (hash, g_strdup ("DISPLAY"), g_strdup (welcome_session->priv->x11_display_name)); - if (welcome_session->priv->ckc != NULL) { - const char *cookie; - cookie = ck_connector_get_cookie (welcome_session->priv->ckc); - if (cookie != NULL) { - g_hash_table_insert (hash, g_strdup ("XDG_SESSION_COOKIE"), g_strdup (cookie)); - } - } - g_hash_table_insert (hash, g_strdup ("LOGNAME"), g_strdup (welcome_session->priv->user_name)); g_hash_table_insert (hash, g_strdup ("USER"), g_strdup (welcome_session->priv->user_name)); g_hash_table_insert (hash, g_strdup ("USERNAME"), g_strdup (welcome_session->priv->user_name)); @@ -445,6 +323,19 @@ get_welcome_environment (GdmWelcomeSession *welcome_session, g_hash_table_insert (hash, g_strdup ("GVFS_DISABLE_FUSE"), g_strdup ("1")); g_hash_table_insert (hash, g_strdup ("DCONF_PROFILE"), g_strdup ("gdm")); + return hash; +} + +static GPtrArray * +get_welcome_environment (GdmWelcomeSession *welcome_session, + gboolean start_session) +{ + GHashTable *hash; + GPtrArray *env; + + hash = build_welcome_environment (welcome_session, start_session); + + env = g_ptr_array_new (); g_hash_table_foreach (hash, (GHFunc)listify_hash, env); g_hash_table_destroy (hash); @@ -453,7 +344,6 @@ get_welcome_environment (GdmWelcomeSession *welcome_session, return env; } - static gboolean stop_dbus_daemon (GdmWelcomeSession *welcome_session) { @@ -472,37 +362,6 @@ stop_dbus_daemon (GdmWelcomeSession *welcome_session) } static void -welcome_session_child_watch (GPid pid, - int status, - GdmWelcomeSession *session) -{ - g_debug ("GdmWelcomeSession: child (pid:%d) done (%s:%d)", - (int) pid, - WIFEXITED (status) ? "status" - : WIFSIGNALED (status) ? "signal" - : "unknown", - WIFEXITED (status) ? WEXITSTATUS (status) - : WIFSIGNALED (status) ? WTERMSIG (status) - : -1); - - if (WIFEXITED (status)) { - int code = WEXITSTATUS (status); - g_signal_emit (session, signals [EXITED], 0, code); - } else if (WIFSIGNALED (status)) { - int num = WTERMSIG (status); - g_signal_emit (session, signals [DIED], 0, num); - } - - g_spawn_close_pid (session->priv->pid); - session->priv->pid = -1; - - if (session->priv->ckc != NULL) { - close_welcome_session (session); - } - stop_dbus_daemon (session); -} - -static void rotate_logs (const char *path, guint n_copies) { @@ -712,62 +571,6 @@ spawn_command_line_sync_as_user (const char *command_line, } static gboolean -spawn_command_line_async_as_user (const char *command_line, - const char *user_name, - const char *group_name, - const char *seat_id, - const char *runtime_dir, - const char *log_file, - char **env, - GPid *child_pid, - GError **error) -{ - char **argv; - GError *local_error; - gboolean ret; - gboolean res; - SpawnChildData data; - - ret = FALSE; - - argv = NULL; - local_error = NULL; - if (! g_shell_parse_argv (command_line, NULL, &argv, &local_error)) { - g_warning ("Could not parse command: %s", local_error->message); - g_propagate_error (error, local_error); - goto out; - } - - data.user_name = user_name; - data.group_name = group_name; - data.runtime_dir = runtime_dir; - data.log_file = log_file; - data.seat_id = seat_id; - - local_error = NULL; - res = g_spawn_async (NULL, - argv, - env, - G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, - (GSpawnChildSetupFunc)spawn_child_setup, - &data, - child_pid, - &local_error); - - if (! res) { - g_warning ("Could not spawn command: %s", local_error->message); - g_propagate_error (error, local_error); - goto out; - } - - ret = TRUE; - out: - g_strfreev (argv); - - return ret; -} - -static gboolean parse_value_as_integer (const char *value, int *intval) { @@ -895,69 +698,105 @@ start_dbus_daemon (GdmWelcomeSession *welcome_session) return res; } -static gboolean -gdm_welcome_session_spawn (GdmWelcomeSession *welcome_session) +static void +on_session_setup_complete (GdmSession *session, + const char *service_name, + GdmWelcomeSession *welcome_session) { - GError *error; - GPtrArray *env; - gboolean ret; - gboolean res; - char *log_path; - char *log_file; + GHashTable *hash; + GHashTableIter iter; + gpointer key, value; - ret = FALSE; - - g_debug ("GdmWelcomeSession: Running welcome_session process: %s", welcome_session->priv->command); + hash = build_welcome_environment (welcome_session, TRUE); - if (welcome_session->priv->register_ck_session) { - open_welcome_session (welcome_session); + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, &key, &value)) { + gdm_session_set_environment_variable (GDM_SESSION (welcome_session->priv->session), key, value); } + g_hash_table_destroy (hash); - res = start_dbus_daemon (welcome_session); - if (! res) { - /* FIXME: */ - } + gdm_session_select_session_type (GDM_SESSION (welcome_session->priv->session), "LoginWindow"); - env = get_welcome_environment (welcome_session, TRUE); + gdm_session_authenticate (GDM_SESSION (welcome_session->priv->session), service_name); +} - error = NULL; +static void +on_session_authenticated (GdmSession *session, + const char *service_name, + GdmWelcomeSession *welcome_session) +{ + gdm_session_authorize (GDM_SESSION (welcome_session->priv->session), + service_name); +} - log_file = g_strdup_printf ("%s-greeter.log", welcome_session->priv->x11_display_name); - log_path = g_build_filename (LOGDIR, log_file, NULL); - g_free (log_file); +static void +on_session_authorized (GdmSession *session, + const char *service_name, + GdmWelcomeSession *welcome_session) +{ + gdm_session_accredit (GDM_SESSION (welcome_session->priv->session), + service_name, + GDM_SESSION_CRED_ESTABLISH); +} - ret = spawn_command_line_async_as_user (welcome_session->priv->command, - welcome_session->priv->user_name, - welcome_session->priv->group_name, - welcome_session->priv->x11_display_seat_id, - welcome_session->priv->runtime_dir, - log_path, - (char **)env->pdata, - &welcome_session->priv->pid, - &error); +static void +on_session_accredited (GdmSession *session, + const char *service_name, + GdmWelcomeSession *welcome_session) +{ + gdm_session_open_session (GDM_SESSION (welcome_session->priv->session), service_name); +} - g_ptr_array_foreach (env, (GFunc)g_free, NULL); - g_ptr_array_free (env, TRUE); +static void +on_session_opened (GdmSession *session, + const char *service_name, + GdmWelcomeSession *welcome_session) +{ + gdm_session_start_session (GDM_SESSION (welcome_session->priv->session), + service_name); +} - g_free (log_path); +static void +on_session_started (GdmSession *session, + const char *service_name, + int pid, + GdmWelcomeSession *welcome_session) +{ + g_signal_emit (G_OBJECT (welcome_session), signals [STARTED], 0); +} - if (! ret) { - g_warning ("Could not start command '%s': %s", - welcome_session->priv->command, - error->message); - g_error_free (error); - goto out; - } else { - g_debug ("GdmWelcomeSession: WelcomeSession on pid %d", (int)welcome_session->priv->pid); - } +static void +on_session_exited (GdmSession *session, + int exit_code, + GdmWelcomeSession *welcome_session) +{ + g_signal_emit (G_OBJECT (welcome_session), signals [EXITED], 0, exit_code); +} + +static void +on_session_died (GdmSession *session, + int signal_number, + GdmWelcomeSession *welcome_session) +{ + g_signal_emit (G_OBJECT (welcome_session), signals [DIED], 0, signal_number); +} - welcome_session->priv->child_watch_id = g_child_watch_add (welcome_session->priv->pid, - (GChildWatchFunc)welcome_session_child_watch, - welcome_session); +static void +on_conversation_started (GdmSession *session, + const char *service_name, + GdmWelcomeSession *welcome_session) +{ + char *log_path; + char *log_file; - out: + log_file = g_strdup_printf ("%s-greeter.log", welcome_session->priv->x11_display_name); + log_path = g_build_filename (LOGDIR, log_file, NULL); + g_free (log_file); - return ret; + gdm_session_setup_for_program (GDM_SESSION (welcome_session->priv->session), + "gdm-welcome", + log_path); + g_free (log_path); } /** @@ -969,66 +808,76 @@ gdm_welcome_session_spawn (GdmWelcomeSession *welcome_session) gboolean gdm_welcome_session_start (GdmWelcomeSession *welcome_session) { - gboolean res; + gboolean res; g_debug ("GdmWelcomeSession: Starting welcome..."); + res = start_dbus_daemon (welcome_session); - res = gdm_welcome_session_spawn (welcome_session); - - if (res) { - - } - - - return res; -} - -static void -welcome_session_died (GdmWelcomeSession *welcome_session) -{ - int exit_status; - - g_debug ("GdmWelcomeSession: Waiting on process %d", welcome_session->priv->pid); - exit_status = gdm_wait_on_pid (welcome_session->priv->pid); - - if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) { - g_debug ("GdmWelcomeSession: Wait on child process failed"); - } else { - /* exited normally */ + if (!res) { + return FALSE; } - g_spawn_close_pid (welcome_session->priv->pid); - welcome_session->priv->pid = -1; - - g_debug ("GdmWelcomeSession: WelcomeSession died"); + welcome_session->priv->session = GDM_SESSION (gdm_session_direct_new (NULL, + welcome_session->priv->x11_display_name, + welcome_session->priv->x11_display_hostname, + welcome_session->priv->x11_display_device, + welcome_session->priv->x11_authority_file, + welcome_session->priv->x11_display_is_local)); + + g_signal_connect (GDM_SESSION (welcome_session->priv->session), + "conversation-started", + G_CALLBACK (on_conversation_started), + welcome_session); + g_signal_connect (welcome_session->priv->session, + "setup-complete", + G_CALLBACK (on_session_setup_complete), + welcome_session); + g_signal_connect (welcome_session->priv->session, + "authenticated", + G_CALLBACK (on_session_authenticated), + welcome_session); + g_signal_connect (welcome_session->priv->session, + "authorized", + G_CALLBACK (on_session_authorized), + welcome_session); + g_signal_connect (welcome_session->priv->session, + "accredited", + G_CALLBACK (on_session_accredited), + welcome_session); + g_signal_connect (welcome_session->priv->session, + "session-opened", + G_CALLBACK (on_session_opened), + welcome_session); + g_signal_connect (GDM_SESSION (welcome_session->priv->session), + "session-started", + G_CALLBACK (on_session_started), + welcome_session); + g_signal_connect (GDM_SESSION (welcome_session->priv->session), + "session-exited", + G_CALLBACK (on_session_exited), + welcome_session); + g_signal_connect (GDM_SESSION (welcome_session->priv->session), + "session-died", + G_CALLBACK (on_session_died), + welcome_session); + + gdm_session_start_conversation (GDM_SESSION (welcome_session->priv->session), + "gdm-welcome"); + gdm_session_select_program (GDM_SESSION (welcome_session->priv->session), + welcome_session->priv->command); + return TRUE; } gboolean gdm_welcome_session_stop (GdmWelcomeSession *welcome_session) { - int res; - - if (welcome_session->priv->pid <= 1) { - return TRUE; - } - - /* remove watch source before we can wait on child */ - if (welcome_session->priv->child_watch_id > 0) { - g_source_remove (welcome_session->priv->child_watch_id); - welcome_session->priv->child_watch_id = 0; - } + if (welcome_session->priv->session != NULL) { + gdm_session_stop_conversation (GDM_SESSION (welcome_session->priv->session), + "gdm-welcome"); + gdm_session_close (GDM_SESSION (welcome_session->priv->session)); - g_debug ("GdmWelcomeSession: Stopping welcome_session"); - - res = gdm_signal_pid (welcome_session->priv->pid, SIGTERM); - if (res < 0) { - g_warning ("Unable to kill welcome session process"); - } else { - welcome_session_died (welcome_session); - } - - if (welcome_session->priv->ckc != NULL) { - close_welcome_session (welcome_session); + g_object_unref (welcome_session->priv->session); + welcome_session->priv->session = NULL; } stop_dbus_daemon (welcome_session); @@ -1085,7 +934,6 @@ _gdm_welcome_session_set_x11_display_is_local (GdmWelcomeSession *welcome_sessio welcome_session->priv->x11_display_is_local = is_local; } - static void _gdm_welcome_session_set_x11_authority_file (GdmWelcomeSession *welcome_session, const char *file) @@ -1447,9 +1295,8 @@ gdm_welcome_session_init (GdmWelcomeSession *welcome_session) welcome_session->priv = GDM_WELCOME_SESSION_GET_PRIVATE (welcome_session); - welcome_session->priv->pid = -1; - welcome_session->priv->command = NULL; + welcome_session->priv->session = NULL; } static void @@ -1466,8 +1313,8 @@ gdm_welcome_session_finalize (GObject *object) gdm_welcome_session_stop (welcome_session); - if (welcome_session->priv->ckc != NULL) { - ck_connector_unref (welcome_session->priv->ckc); + if (welcome_session->priv->session) { + g_object_unref (welcome_session->priv->session); } g_free (welcome_session->priv->command); |