diff options
author | Robert Ancell <robert.ancell@canonical.com> | 2011-10-06 11:36:41 +1100 |
---|---|---|
committer | Robert Ancell <robert.ancell@canonical.com> | 2011-10-06 11:36:41 +1100 |
commit | 94233c9965a89c526599e628abe5e5af002bc93b (patch) | |
tree | 825b805a1518135193d0dd65b2b3c7590dd1d337 | |
parent | 6262762b98c556a1cd9138b61e45e075f40e443f (diff) | |
download | lightdm-94233c9965a89c526599e628abe5e5af002bc93b.tar.gz |
Merge in changes from stable branch
-rw-r--r-- | liblightdm-gobject/user.c | 38 | ||||
-rw-r--r-- | src/accounts.c | 137 | ||||
-rw-r--r-- | src/accounts.h | 4 | ||||
-rw-r--r-- | src/display.c | 41 | ||||
-rw-r--r-- | src/greeter.c | 2 | ||||
-rw-r--r-- | src/session.c | 118 | ||||
-rw-r--r-- | src/session.h | 2 |
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); |