#include "console-kit.h"
#include "login1.h"
#include "guest-account.h"
+#include "shared-data-manager.h"
enum {
GOT_MESSAGES,
struct SessionPrivate
{
- /* Session type */
- gchar *session_type;
+ /* Configuration for this session */
+ SessionConfig *config;
/* Display server running on */
DisplayServer *display_server;
/* File to log to */
gchar *log_filename;
-
- /* Seat class */
- gchar *class;
+ LogMode log_mode;
/* tty this session is running on */
gchar *tty;
/* Console kit cookie */
gchar *console_kit_cookie;
- /* login1 session */
- gchar *login1_session;
+ /* login1 session ID */
+ gchar *login1_session_id;
/* Environment to set in child */
GList *env;
}
void
-session_set_session_type (Session *session, const gchar *session_type)
+session_set_config (Session *session, SessionConfig *config)
{
g_return_if_fail (session != NULL);
- g_free (session->priv->session_type);
- session->priv->session_type = g_strdup (session_type);
+
+ g_clear_object (&session->priv->config);
+ session->priv->config = g_object_ref (config);
+}
+
+SessionConfig *
+session_get_config (Session *session)
+{
+ g_return_val_if_fail (session != NULL, NULL);
+ return session->priv->config;
}
const gchar *
session_get_session_type (Session *session)
{
g_return_val_if_fail (session != NULL, NULL);
- return session->priv->session_type;
+ return session_config_get_session_type (session_get_config (session));
}
void
}
void
-session_set_log_file (Session *session, const gchar *filename)
+session_set_log_file (Session *session, const gchar *filename, LogMode log_mode)
{
g_return_if_fail (session != NULL);
g_free (session->priv->log_filename);
session->priv->log_filename = g_strdup (filename);
-}
-
-void
-session_set_class (Session *session, const gchar *class)
-{
- g_return_if_fail (session != NULL);
- g_free (session->priv->class);
- session->priv->class = g_strdup (class);
+ session->priv->log_mode = log_mode;
}
void
{
g_return_if_fail (session != NULL);
g_return_if_fail (display_server != NULL);
+
+ if (session->priv->display_server == display_server)
+ return;
+
if (session->priv->display_server)
{
display_server_disconnect_session (session->priv->display_server, session);
session_set_x_authority (Session *session, XAuthority *authority, gboolean use_system_location)
{
g_return_if_fail (session != NULL);
- if (session->priv->x_authority)
- {
- g_object_unref (session->priv->x_authority);
- session->priv->x_authority = NULL;
- }
+ g_clear_object (&session->priv->x_authority);
if (authority)
session->priv->x_authority = g_object_ref (authority);
session->priv->x_authority_use_system_location = use_system_location;
link = find_env_entry (session, name);
if (!link)
return NULL;
-
+
entry = link->data;
return entry + strlen (name) + 1;
GList *link;
g_return_if_fail (session != NULL);
-
+
link = find_env_entry (session, name);
if (!link)
return;
g_free (link->data);
- session->priv->env = g_list_remove_link (session->priv->env, link);
+ session->priv->env = g_list_delete_link (session->priv->env, link);
}
void
{
Session *session = data;
+ session->priv->child_watch = 0;
+
if (WIFEXITED (status))
l_debug (session, "Exited with return value %d", WEXITSTATUS (status));
else if (WIFSIGNALED (status))
{
g_free (session->priv->username);
session->priv->username = username;
- if (session->priv->user)
- g_object_unref (session->priv->user);
- session->priv->user = NULL;
+ g_clear_object (&session->priv->user);
}
else
g_free (username);
int version;
int to_child_pipe[2], from_child_pipe[2];
int to_child_output, from_child_input;
+ gchar *arg0, *arg1;
g_return_val_if_fail (session->priv->pid == 0, FALSE);
}
/* Run the child */
+ arg0 = g_strdup_printf ("%d", to_child_output);
+ arg1 = g_strdup_printf ("%d", from_child_input);
session->priv->pid = fork ();
- if (session->priv->pid < 0)
- {
- g_debug ("Failed to fork session child process: %s", strerror (errno));
- return FALSE;
- }
-
if (session->priv->pid == 0)
{
/* Run us again in session child mode */
execlp ("lightdm",
"lightdm",
"--session-child",
- g_strdup_printf ("%d", to_child_output),
- g_strdup_printf ("%d", from_child_input),
- NULL);
+ arg0, arg1, NULL);
_exit (EXIT_FAILURE);
}
+ g_free (arg0);
+ g_free (arg1);
+
+ if (session->priv->pid < 0)
+ {
+ g_debug ("Failed to fork session child process: %s", strerror (errno));
+ return FALSE;
+ }
/* Hold a reference on this object until the child process terminates so we
* can handle the watch callback even if it is no longer used. Otherwise a
close (from_child_input);
/* Indicate what version of the protocol we are using */
- version = 1;
+ version = 3;
write_data (session, &version, sizeof (version));
/* Send configuration */
write_string (session, session->priv->username);
write_data (session, &session->priv->do_authenticate, sizeof (session->priv->do_authenticate));
write_data (session, &session->priv->is_interactive, sizeof (session->priv->is_interactive));
- write_string (session, session->priv->class);
+ write_string (session, NULL); /* Used to be class, now we just use the environment variable */
write_string (session, session->priv->tty);
write_string (session, session->priv->remote_host_name);
write_string (session, session->priv->xdisplay);
return session->priv->username;
}
+const gchar *
+session_get_login1_session_id (Session *session)
+{
+ g_return_val_if_fail (session != NULL, NULL);
+ return session->priv->login1_session_id;
+}
+
const gchar *
session_get_console_kit_cookie (Session *session)
{
else
x_authority_filename = g_build_filename (user_get_home_directory (session_get_user (session)), ".Xauthority", NULL);
+ /* Make sure shared user directory for this user exists */
+ if (!session->priv->remote_host_name)
+ {
+ gchar *data_dir = shared_data_manager_ensure_user_dir (shared_data_manager_get_instance (), session->priv->username);
+ if (data_dir)
+ {
+ session_set_env (session, "XDG_GREETER_DATA_DIR", data_dir);
+ g_free (data_dir);
+ }
+ }
+
if (session->priv->log_filename)
l_debug (session, "Logging to %s", session->priv->log_filename);
write_string (session, session->priv->log_filename);
+ write_data (session, &session->priv->log_mode, sizeof (session->priv->log_mode));
write_string (session, session->priv->tty);
write_string (session, x_authority_filename);
g_free (x_authority_filename);
for (i = 0; i < argc; i++)
write_string (session, session->priv->argv[i]);
- if (login1_is_running ())
- session->priv->login1_session = read_string_from_child (session);
- if (!session->priv->login1_session)
- session->priv->console_kit_cookie = read_string_from_child (session);
+ session->priv->login1_session_id = read_string_from_child (session);
+ session->priv->console_kit_cookie = read_string_from_child (session);
}
void
g_return_if_fail (session != NULL);
if (getuid () == 0)
{
- if (session->priv->login1_session)
- login1_lock_session (session->priv->login1_session);
+ if (session->priv->login1_session_id)
+ login1_service_lock_session (login1_service_get_instance (), session->priv->login1_session_id);
else if (session->priv->console_kit_cookie)
ck_lock_session (session->priv->console_kit_cookie);
}
g_return_if_fail (session != NULL);
if (getuid () == 0)
{
- if (session->priv->login1_session)
- login1_unlock_session (session->priv->login1_session);
+ if (session->priv->login1_session_id)
+ login1_service_unlock_session (login1_service_get_instance (), session->priv->login1_session_id);
else if (session->priv->console_kit_cookie)
ck_unlock_session (session->priv->console_kit_cookie);
}
}
+void
+session_activate (Session *session)
+{
+ g_return_if_fail (session != NULL);
+ if (getuid () == 0)
+ {
+ if (session->priv->login1_session_id)
+ login1_service_activate_session (login1_service_get_instance (), session->priv->login1_session_id);
+ else if (session->priv->console_kit_cookie)
+ ck_activate_session (session->priv->console_kit_cookie);
+ }
+}
+
void
session_stop (Session *session)
{
g_return_if_fail (session != NULL);
+ /* If can cleanly stop then do that */
+ if (session_get_is_authenticated (session) && !session->priv->command_run)
+ {
+ gsize n = 0;
+ LogMode log_mode = LOG_MODE_INVALID;
+
+ session->priv->command_run = TRUE;
+ write_string (session, NULL); // log filename
+ write_data (session, &log_mode, sizeof (log_mode)); // log mode
+ write_string (session, NULL); // tty
+ write_string (session, NULL); // xauth filename
+ write_string (session, NULL); // xdisplay
+ write_xauth (session, NULL); // xauth
+ write_data (session, &n, sizeof (n)); // environment
+ write_data (session, &n, sizeof (n)); // command
+ return;
+ }
+
if (session->priv->stopping)
return;
session->priv->stopping = TRUE;
{
session->priv = G_TYPE_INSTANCE_GET_PRIVATE (session, SESSION_TYPE, SessionPrivate);
session->priv->log_filename = g_strdup (".xsession-errors");
+ session->priv->log_mode = LOG_MODE_BACKUP_AND_TRUNCATE;
+ session->priv->to_child_input = -1;
+ session->priv->from_child_output = -1;
}
static void
Session *self = SESSION (object);
int i;
- g_free (self->priv->session_type);
- if (self->priv->display_server)
- g_object_unref (self->priv->display_server);
+ g_clear_object (&self->priv->config);
+ g_clear_object (&self->priv->display_server);
if (self->priv->pid)
kill (self->priv->pid, SIGKILL);
+ close (self->priv->to_child_input);
+ close (self->priv->from_child_output);
if (self->priv->from_child_channel)
g_io_channel_unref (self->priv->from_child_channel);
if (self->priv->from_child_watch)
if (self->priv->child_watch)
g_source_remove (self->priv->child_watch);
g_free (self->priv->username);
- if (self->priv->user)
- g_object_unref (self->priv->user);
+ g_clear_object (&self->priv->user);
g_free (self->priv->pam_service);
for (i = 0; i < self->priv->messages_length; i++)
g_free ((char *) self->priv->messages[i].msg);
g_free (self->priv->messages);
g_free (self->priv->authentication_result_string);
g_free (self->priv->log_filename);
- g_free (self->priv->class);
g_free (self->priv->tty);
g_free (self->priv->xdisplay);
- if (self->priv->x_authority)
- g_object_unref (self->priv->x_authority);
+ g_clear_object (&self->priv->x_authority);
g_free (self->priv->remote_host_name);
- g_free (self->priv->login1_session);
+ g_free (self->priv->login1_session_id);
g_free (self->priv->console_kit_cookie);
g_list_free_full (self->priv->env, g_free);
g_strfreev (self->priv->argv);
g_type_class_add_private (klass, sizeof (SessionPrivate));
signals[GOT_MESSAGES] =
- g_signal_new ("got-messages",
+ g_signal_new (SESSION_SIGNAL_GOT_MESSAGES,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (SessionClass, got_messages),
G_TYPE_NONE, 0);
signals[AUTHENTICATION_COMPLETE] =
- g_signal_new ("authentication-complete",
+ g_signal_new (SESSION_SIGNAL_AUTHENTICATION_COMPLETE,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (SessionClass, authentication_complete),
G_TYPE_NONE, 0);
signals[STOPPED] =
- g_signal_new ("stopped",
+ g_signal_new (SESSION_SIGNAL_STOPPED,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (SessionClass, stopped),