summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Ancell <robert.ancell@canonical.com>2011-10-06 11:36:41 +1100
committerRobert Ancell <robert.ancell@canonical.com>2011-10-06 11:36:41 +1100
commit94233c9965a89c526599e628abe5e5af002bc93b (patch)
tree825b805a1518135193d0dd65b2b3c7590dd1d337
parent6262762b98c556a1cd9138b61e45e075f40e443f (diff)
downloadlightdm-94233c9965a89c526599e628abe5e5af002bc93b.tar.gz
Merge in changes from stable branch
-rw-r--r--liblightdm-gobject/user.c38
-rw-r--r--src/accounts.c137
-rw-r--r--src/accounts.h4
-rw-r--r--src/display.c41
-rw-r--r--src/greeter.c2
-rw-r--r--src/session.c118
-rw-r--r--src/session.h2
7 files changed, 173 insertions, 169 deletions
diff --git a/liblightdm-gobject/user.c b/liblightdm-gobject/user.c
index d43760dc..a6779fbc 100644
--- a/liblightdm-gobject/user.c
+++ b/liblightdm-gobject/user.c
@@ -19,13 +19,15 @@
#include "lightdm/user.h"
-enum {
+enum
+{
LIST_PROP_0,
LIST_PROP_NUM_USERS,
LIST_PROP_USERS,
};
-enum {
+enum
+{
USER_PROP_0,
USER_PROP_NAME,
USER_PROP_REAL_NAME,
@@ -38,7 +40,8 @@ enum {
USER_PROP_LOGGED_IN
};
-enum {
+enum
+{
USER_ADDED,
USER_CHANGED,
USER_REMOVED,
@@ -46,7 +49,8 @@ enum {
};
static guint list_signals[LAST_LIST_SIGNAL] = { 0 };
-enum {
+enum
+{
CHANGED,
LAST_USER_SIGNAL
};
@@ -900,7 +904,8 @@ lightdm_user_list_get_property (GObject *object,
self = LIGHTDM_USER_LIST (object);
- switch (prop_id) {
+ switch (prop_id)
+ {
case LIST_PROP_NUM_USERS:
g_value_set_int (value, lightdm_user_list_get_length (self));
break;
@@ -1102,7 +1107,15 @@ load_dmrc (LightDMUser *user)
if (priv->session)
g_free (priv->session);
+ /* The Language field is actually a locale, strip the codeset off it to get the language */
priv->language = g_key_file_get_string (priv->dmrc_file, "Desktop", "Language", NULL);
+ if (priv->language)
+ {
+ gchar *codeset = strchr (priv->language, '.');
+ if (codeset)
+ *codeset = '\0';
+ }
+
priv->layout = g_key_file_get_string (priv->dmrc_file, "Desktop", "Layout", NULL);
priv->session = g_key_file_get_string (priv->dmrc_file, "Desktop", "Session", NULL);
}
@@ -1118,12 +1131,14 @@ get_string_property (GDBusProxy *proxy, const gchar *property)
answer = g_dbus_proxy_get_cached_property (proxy, property);
- if (!answer) {
+ if (!answer)
+ {
g_warning ("Could not get accounts property %s", property);
return NULL;
}
- if (!g_variant_is_of_type (answer, G_VARIANT_TYPE ("s"))) {
+ if (!g_variant_is_of_type (answer, G_VARIANT_TYPE ("s")))
+ {
g_warning ("Unexpected accounts property type for %s: %s",
property, g_variant_get_type_string (answer));
g_variant_unref (answer);
@@ -1145,8 +1160,10 @@ load_accounts_service (LightDMUser *user)
/* First, find AccountObject proxy */
UserAccountObject *account = NULL;
GList *iter;
- for (iter = list_priv->user_account_objects; iter; iter = iter->next) {
- if (((UserAccountObject *)iter->data)->user == user) {
+ for (iter = list_priv->user_account_objects; iter; iter = iter->next)
+ {
+ if (((UserAccountObject *)iter->data)->user == user)
+ {
account = (UserAccountObject *)iter->data;
break;
}
@@ -1281,7 +1298,8 @@ lightdm_user_get_property (GObject *object,
self = LIGHTDM_USER (object);
- switch (prop_id) {
+ switch (prop_id)
+ {
case USER_PROP_NAME:
g_value_set_string (value, lightdm_user_get_name (self));
break;
diff --git a/src/accounts.c b/src/accounts.c
index fcd24bbe..f092acb5 100644
--- a/src/accounts.c
+++ b/src/accounts.c
@@ -44,14 +44,18 @@ struct UserPrivate
/* Language */
gchar *language;
+ /* Locale */
+ gchar *locale;
+
/* X session */
gchar *xsession;
};
G_DEFINE_TYPE (User, user, G_TYPE_OBJECT);
-static GDBusProxy *accounts_proxy = NULL;
-static gboolean have_accounts_proxy = FALSE;
+/* Connection to AccountsService */
+static GDBusProxy *accounts_service_proxy = NULL;
+static gboolean have_accounts_service_proxy = FALSE;
static gboolean
call_method (GDBusProxy *proxy, const gchar *method, GVariant *args,
@@ -99,17 +103,16 @@ get_property (GDBusProxy *proxy, const gchar *property,
{
GVariant *answer;
- if (!proxy)
- return FALSE;
-
answer = g_dbus_proxy_get_cached_property (proxy, property);
- if (!answer) {
+ if (!answer)
+ {
g_warning ("Could not get accounts property %s", property);
return FALSE;
}
- if (!g_variant_is_of_type (answer, G_VARIANT_TYPE (expected))) {
+ if (!g_variant_is_of_type (answer, G_VARIANT_TYPE (expected)))
+ {
g_warning ("Unexpected accounts property type for %s: %s",
property, g_variant_get_type_string (answer));
g_variant_unref (answer);
@@ -151,47 +154,58 @@ get_string_from_dmrc (const gchar *username, const gchar *group,
}
static GDBusProxy *
-get_accounts_proxy_for_user (const gchar *user)
+get_accounts_service_proxy ()
{
GError *error = NULL;
- GVariant *result;
- gboolean success;
- GDBusProxy *proxy;
- gchar *user_path = NULL;
- g_return_val_if_fail (user != NULL, NULL);
+ if (have_accounts_service_proxy)
+ return accounts_service_proxy;
+
+ have_accounts_service_proxy = TRUE;
+ accounts_service_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "org.freedesktop.Accounts",
+ "/org/freedesktop/Accounts",
+ "org.freedesktop.Accounts",
+ NULL, &error);
+ if (error)
+ g_warning ("Could not get accounts proxy: %s", error->message);
+ g_clear_error (&error);
- if (!have_accounts_proxy)
+ if (accounts_service_proxy)
{
gchar *name;
-
- accounts_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- "org.freedesktop.Accounts",
- "/org/freedesktop/Accounts",
- "org.freedesktop.Accounts",
- NULL, &error);
- if (error)
- g_warning ("Could not get accounts proxy: %s", error->message);
- g_clear_error (&error);
-
- name = g_dbus_proxy_get_name_owner (accounts_proxy);
+ name = g_dbus_proxy_get_name_owner (accounts_service_proxy);
if (!name)
{
g_debug ("org.freedesktop.Accounts does not exist, falling back to passwd file");
- g_object_unref (accounts_proxy);
- accounts_proxy = NULL;
+ g_object_unref (accounts_service_proxy);
+ accounts_service_proxy = NULL;
}
g_free (name);
+ }
- have_accounts_proxy = TRUE;
- }
+ return accounts_service_proxy;
+}
- if (!accounts_proxy)
+static GDBusProxy *
+get_accounts_proxy_for_user (const gchar *user)
+{
+ GDBusProxy *proxy;
+ GError *error = NULL;
+ GVariant *result;
+ gboolean success;
+ gchar *user_path = NULL;
+
+ g_return_val_if_fail (user != NULL, NULL);
+
+ proxy = get_accounts_service_proxy ();
+ if (!proxy)
return NULL;
- success = call_method (accounts_proxy, "FindUserByName", g_variant_new ("(s)", user), "(o)", &result);
+ success = call_method (proxy, "FindUserByName", g_variant_new ("(s)", user), "(o)", &result);
+ g_object_unref (proxy);
if (!success)
return NULL;
@@ -319,39 +333,33 @@ user_get_shell (User *user)
return user->priv->shell;
}
-void
-user_set_language (User *user, const gchar *language)
-{
- g_return_if_fail (user != NULL);
-
- call_method (user->priv->proxy, "SetLanguage", g_variant_new ("(s)", language), "()", NULL);
- save_string_to_dmrc (user->priv->name, "Desktop", "Language", language);
-}
-
const gchar *
-user_get_language (User *user)
+user_get_locale (User *user)
{
- GVariant *result;
-
g_return_val_if_fail (user != NULL, NULL);
- g_free (user->priv->language);
-
- if (get_property (user->priv->proxy, "Language", "s", &result))
- {
- g_variant_get (result, "s", &user->priv->language);
- g_variant_unref (result);
- }
+ g_free (user->priv->locale);
+ if (user->priv->proxy)
+ user->priv->locale = NULL;
else
- user->priv->language = get_string_from_dmrc (user->priv->name, "Desktop", "Language");
+ user->priv->locale = get_string_from_dmrc (user->priv->name, "Desktop", "Language");
- if (g_strcmp0 (user->priv->language, "") == 0)
+ /* Treat a blank locale as unset */
+ if (g_strcmp0 (user->priv->locale, "") == 0)
{
- g_free (user->priv->language);
- user->priv->language = NULL;
+ g_free (user->priv->locale);
+ user->priv->locale = NULL;
}
- return user->priv->language;
+ return user->priv->locale;
+}
+
+void
+user_set_locale (User *user, const gchar *locale)
+{
+ g_return_if_fail (user != NULL);
+ if (!user->priv->proxy)
+ save_string_to_dmrc (user->priv->name, "Desktop", "Language", locale);
}
void
@@ -371,11 +379,15 @@ user_get_xsession (User *user)
g_return_val_if_fail (user != NULL, NULL);
g_free (user->priv->xsession);
-
- if (get_property (user->priv->proxy, "XSession", "s", &result))
+ if (user->priv->proxy)
{
- g_variant_get (result, "s", &user->priv->xsession);
- g_variant_unref (result);
+ if (get_property (user->priv->proxy, "XSession", "s", &result))
+ {
+ g_variant_get (result, "s", &user->priv->xsession);
+ g_variant_unref (result);
+ }
+ else
+ user->priv->xsession = NULL;
}
else
user->priv->xsession = get_string_from_dmrc (user->priv->name, "Desktop", "Session");
@@ -402,7 +414,8 @@ user_dispose (GObject *object)
self = USER (object);
- if (self->priv->proxy) {
+ if (self->priv->proxy)
+ {
g_object_unref (self->priv->proxy);
self->priv->proxy = NULL;
}
diff --git a/src/accounts.h b/src/accounts.h
index 5e1264f2..03165b71 100644
--- a/src/accounts.h
+++ b/src/accounts.h
@@ -58,9 +58,9 @@ const gchar *user_get_xsession (User *user);
void user_set_xsession (User *user, const gchar *session);
-const gchar *user_get_language (User *user);
+const gchar *user_get_locale (User *user);
-void user_set_language (User *user, const gchar *language);
+void user_set_locale (User *user, const gchar *language);
G_END_DECLS
diff --git a/src/display.c b/src/display.c
index 5ebf4d6b..e2da4b2d 100644
--- a/src/display.c
+++ b/src/display.c
@@ -384,7 +384,7 @@ user_session_stopped_cb (Session *session, Display *display)
}
static Session *
-create_session (Display *display, PAMSession *authentication, const gchar *session_name, gboolean is_greeter, const gchar *log_filename)
+create_session (Display *display, PAMSession *authentication, const gchar *session_name, gboolean is_greeter)
{
gchar *sessions_dir, *filename, *path, *command = NULL;
GKeyFile *session_desktop_file;
@@ -392,7 +392,7 @@ create_session (Display *display, PAMSession *authentication, const gchar *sessi
gboolean result;
GError *error = NULL;
- g_debug ("Starting session %s as user %s logging to %s", session_name, pam_session_get_username (authentication), log_filename);
+ g_debug ("Starting session %s as user %s", session_name, pam_session_get_username (authentication));
// FIXME: This is X specific, move into xsession.c
if (is_greeter)
@@ -456,8 +456,6 @@ create_session (Display *display, PAMSession *authentication, const gchar *sessi
session_set_env (session, "DESKTOP_SESSION", session_name); // FIXME: Apparently deprecated?
session_set_env (session, "GDMSESSION", session_name); // FIXME: Not cross-desktop
- session_set_log_file (session, log_filename);
-
/* Connect using the session bus */
if (getuid () != 0)
{
@@ -589,25 +587,28 @@ start_greeter_session (Display *display)
}
display->priv->in_user_session = FALSE;
- log_dir = config_get_string (config_get_instance (), "LightDM", "log-directory");
- filename = g_strdup_printf ("%s-greeter.log", display_server_get_name (display->priv->display_server));
- log_filename = g_build_filename (log_dir, filename, NULL);
- g_free (log_dir);
- g_free (filename);
-
/* Authenticate as the requested user */
authentication = pam_session_new (display->priv->pam_autologin_service, user_get_name (user));
pam_session_set_interactive (authentication, FALSE);
g_signal_connect (G_OBJECT (authentication), "authentication-result", G_CALLBACK (greeter_authentication_result_cb), display);
g_object_unref (user);
- display->priv->session = create_session (display, authentication, display->priv->greeter_session, TRUE, log_filename);
+ display->priv->session = create_session (display, authentication, display->priv->greeter_session, TRUE);
g_object_unref (authentication);
- g_free (log_filename);
-
+
if (!display->priv->session)
return FALSE;
+ log_dir = config_get_string (config_get_instance (), "LightDM", "log-directory");
+ filename = g_strdup_printf ("%s-greeter.log", display_server_get_name (display->priv->display_server));
+ log_filename = g_build_filename (log_dir, filename, NULL);
+ g_free (log_dir);
+ g_free (filename);
+
+ g_debug ("Logging to %s", log_filename);
+ session_set_log_file (display->priv->session, log_filename, FALSE);
+ g_free (log_filename);
+
display->priv->greeter = greeter_new (display->priv->session);
g_signal_connect (G_OBJECT (display->priv->greeter), "connected", G_CALLBACK (greeter_connected_cb), display);
g_signal_connect (G_OBJECT (display->priv->greeter), "start-authentication", G_CALLBACK (greeter_start_authentication_cb), display);
@@ -675,16 +676,22 @@ start_user_session (Display *display, PAMSession *authentication)
/* Update user's xsession setting */
user_set_xsession (user, display->priv->user_session);
+
+ display->priv->session = create_session (display, authentication, display->priv->user_session, FALSE);
+
+ if (!display->priv->session)
+ return FALSE;
// FIXME: Copy old error file
log_filename = g_build_filename (user_get_home_directory (user), ".xsession-errors", NULL);
+
+ /* Delete existing log file if it exists - a bug in 1.0.0 would cause this file to be written as root */
+ unlink (log_filename);
- display->priv->session = create_session (display, authentication, display->priv->user_session, FALSE, log_filename);
+ g_debug ("Logging to %s", log_filename);
+ session_set_log_file (display->priv->session, log_filename, TRUE);
g_free (log_filename);
- if (!display->priv->session)
- return FALSE;
-
g_signal_emit (display, signals[START_SESSION], 0, &result);
return !result;
diff --git a/src/greeter.c b/src/greeter.c
index bcfb2c42..f6fa2e8b 100644
--- a/src/greeter.c
+++ b/src/greeter.c
@@ -442,7 +442,7 @@ handle_set_language (Greeter *greeter, const gchar *language)
g_debug ("Greeter sets language %s", language);
user = pam_session_get_user (greeter->priv->authentication);
- user_set_language (user, language);
+ user_set_locale (user, language);
}
static guint32
diff --git a/src/session.c b/src/session.c
index 93d65608..226bc2c6 100644
--- a/src/session.c
+++ b/src/session.c
@@ -26,6 +26,9 @@ struct SessionPrivate
/* File to log to */
gchar *log_file;
+ /* TRUE if the log file should be owned by the user */
+ gboolean log_file_as_user;
+
/* Authentication for this session */
PAMSession *authentication;
@@ -45,11 +48,12 @@ struct SessionPrivate
G_DEFINE_TYPE (Session, session, PROCESS_TYPE);
void
-session_set_log_file (Session *session, const gchar *filename)
+session_set_log_file (Session *session, const gchar *filename, gboolean as_user)
{
g_return_if_fail (session != NULL);
g_free (session->priv->log_file);
session->priv->log_file = g_strdup (filename);
+ session->priv->log_file_as_user = as_user;
}
const gchar *
@@ -192,69 +196,23 @@ session_get_console_kit_cookie (Session *session)
return session->priv->console_kit_cookie;
}
-/* Set the LANG variable based on the chosen language. This is not a great
- * solution, as it will override the language set in PAM (which is where it
- * should be set). It's also overly simplistic to set all the locale
- * settings based on one language. In the case of Ubuntu these will be
- * overridden by setting these variables in ~/.profile */
+/* Set the LANG variable based on the chosen locale. This is not a great
+ * solution, as it will override the locale set in PAM (which is where it
+ * should be set). In the case of Ubuntu these will be overridden by setting
+ * these variables in ~/.profile */
static void
-set_language (Session *session)
+set_locale (Session *session)
{
User *user;
- const gchar *language;
- gchar *language_dot;
- gboolean result;
- gchar *stdout_text = NULL;
- int exit_status;
- gboolean found_code = FALSE;
- GError *error = NULL;
+ const gchar *locale;
user = pam_session_get_user (session->priv->authentication);
- language = user_get_language (user);
- if (!language)
- return;
-
- language_dot = g_strdup_printf ("%s.", language);
-
- /* Find a locale that matches the language code */
- result = g_spawn_command_line_sync ("locale -a", &stdout_text, NULL, &exit_status, &error);
- if (error)
+ locale = user_get_locale (user);
+ if (locale)
{
- g_warning ("Failed to run 'locale -a': %s", error->message);
- g_clear_error (&error);
+ g_debug ("Using locale %s", locale);
+ session_set_env (session, "LANG", locale);
}
- else if (exit_status != 0)
- g_warning ("Failed to get languages, locale -a returned %d", exit_status);
- else if (result)
- {
- gchar **tokens;
- int i;
-
- tokens = g_strsplit_set (stdout_text, "\n\r", -1);
- for (i = 0; tokens[i]; i++)
- {
- gchar *code;
-
- code = g_strchug (tokens[i]);
- if (code[0] == '\0')
- continue;
-
- if (strcmp (code, language) == 0 || g_str_has_prefix (code, language_dot))
- {
- g_debug ("Using locale %s for language %s", code, language);
- found_code = TRUE;
- session_set_env (session, "LANG", code);
- break;
- }
- }
-
- g_strfreev (tokens);
- }
- g_free (language_dot);
- g_free (stdout_text);
-
- if (!found_code)
- g_debug ("Failed to find locale for language %s", language);
}
/* Insert our own utility directory to PATH
@@ -395,6 +353,26 @@ session_cleanup (Session *session)
}
static void
+setup_log_file (Session *session)
+{
+ int fd;
+
+ /* Redirect output to logfile */
+ if (!session->priv->log_file)
+ return;
+
+ fd = g_open (session->priv->log_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ if (fd < 0)
+ g_warning ("Failed to open log file %s: %s", session->priv->log_file, g_strerror (errno));
+ else
+ {
+ dup2 (fd, STDOUT_FILENO);
+ dup2 (fd, STDERR_FILENO);
+ close (fd);
+ }
+}
+
+static void
session_run (Process *process)
{
Session *session = SESSION (process);
@@ -406,15 +384,15 @@ session_run (Process *process)
dup2 (fd, STDIN_FILENO);
close (fd);
+ /* Redirect output to logfile */
+ if (!session->priv->log_file_as_user)
+ setup_log_file (session);
+
/* Make this process its own session */
if (setsid () < 0)
g_warning ("Failed to make process a new session: %s", strerror (errno));
user = pam_session_get_user (session->priv->authentication);
-
- /* Delete existing log file if it exists - a bug in 1.0.0 would cause this file to be written as root */
- if (session->priv->log_file)
- unlink (session->priv->log_file);
/* Change working directory */
if (chdir (user_get_home_directory (user)) != 0)
@@ -446,25 +424,13 @@ session_run (Process *process)
}
/* Redirect output to logfile */
- if (session->priv->log_file)
- {
- int fd;
-
- fd = g_open (session->priv->log_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
- if (fd < 0)
- g_warning ("Failed to open log file %s: %s", session->priv->log_file, g_strerror (errno));
- else
- {
- dup2 (fd, STDOUT_FILENO);
- dup2 (fd, STDERR_FILENO);
- close (fd);
- }
- }
+ if (session->priv->log_file_as_user)
+ setup_log_file (session);
/* Do PAM actions requiring session process */
pam_session_setup (session->priv->authentication);
set_env_from_authentication (session, session->priv->authentication);
- set_language (session);
+ set_locale (session);
insert_utility_path (session);
PROCESS_CLASS (session_parent_class)->run (process);
diff --git a/src/session.h b/src/session.h
index cdddf462..41cd1f73 100644
--- a/src/session.h
+++ b/src/session.h
@@ -42,7 +42,7 @@ typedef struct
GType session_get_type (void);
-void session_set_log_file (Session *session, const gchar *filename);
+void session_set_log_file (Session *session, const gchar *filename, gboolean as_user);
const gchar *session_get_log_file (Session *session);