diff options
author | William Jon McCann <jmccann@redhat.com> | 2010-06-30 10:20:43 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2010-08-17 13:45:20 -0400 |
commit | 9310418c63258dfd70cef46e2682cd9adc6c8f21 (patch) | |
tree | 3931193258559e6570482801acebc46b3aed3d1f | |
parent | 36e72382eb19c31ee9e59b72f27cb8537ef960dd (diff) | |
download | gdm-9310418c63258dfd70cef46e2682cd9adc6c8f21.tar.gz |
Wrap getpw* calls to retry in EINTR
if getpwnam(username) returns NULL, errno needs to be
checked for EINTR. This indicates that a signal was received while waiting for
the blocking call to return, and getpwnam() should be retried.
-rw-r--r-- | common/gdm-common.c | 19 | ||||
-rw-r--r-- | common/gdm-common.h | 3 | ||||
-rw-r--r-- | daemon/gdm-chooser-server.c | 3 | ||||
-rw-r--r-- | daemon/gdm-display-access-file.c | 2 | ||||
-rw-r--r-- | daemon/gdm-greeter-server.c | 3 | ||||
-rw-r--r-- | daemon/gdm-server.c | 4 | ||||
-rw-r--r-- | daemon/gdm-session-linux-auditor.c | 6 | ||||
-rw-r--r-- | daemon/gdm-session-solaris-auditor.c | 4 | ||||
-rw-r--r-- | daemon/gdm-session-worker.c | 14 | ||||
-rw-r--r-- | daemon/gdm-slave.c | 6 | ||||
-rw-r--r-- | daemon/gdm-welcome-session.c | 6 | ||||
-rw-r--r-- | daemon/main.c | 2 | ||||
-rw-r--r-- | gui/simple-greeter/gdm-user-manager.c | 48 |
13 files changed, 94 insertions, 26 deletions
diff --git a/common/gdm-common.c b/common/gdm-common.c index 8435161e..de807000 100644 --- a/common/gdm-common.c +++ b/common/gdm-common.c @@ -26,6 +26,7 @@ #include <locale.h> #include <fcntl.h> #include <sys/wait.h> +#include <pwd.h> #include <glib.h> #include <glib/gi18n.h> @@ -73,6 +74,24 @@ gdm_set_fatal_warnings_if_unstable (void) } } +gboolean +gdm_get_pwent_for_name (const char *name, + struct passwd **pwentp) +{ + struct passwd *pwent; + + do { + errno = 0; + pwent = getpwnam (name); + } while (pwent == NULL && errno == EINTR); + + if (pwentp != NULL) { + *pwentp = pwent; + } + + return (pwent != NULL); +} + int gdm_wait_on_pid (int pid) { diff --git a/common/gdm-common.h b/common/gdm-common.h index 1983cffe..8faeda5c 100644 --- a/common/gdm-common.h +++ b/common/gdm-common.h @@ -22,6 +22,7 @@ #define _GDM_COMMON_H #include <glib.h> +#include <pwd.h> #include "gdm-common-unknown-origin.h" @@ -35,6 +36,8 @@ void gdm_set_fatal_warnings_if_unstable (void); int gdm_wait_on_pid (int pid); int gdm_signal_pid (int pid, int signal); +gboolean gdm_get_pwent_for_name (const char *name, + struct passwd **pwentp); const char * gdm_make_temp_dir (char *template); diff --git a/daemon/gdm-chooser-server.c b/daemon/gdm-chooser-server.c index 2268838d..fc9fd3c3 100644 --- a/daemon/gdm-chooser-server.c +++ b/daemon/gdm-chooser-server.c @@ -43,6 +43,7 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> +#include "gdm-common.h" #include "gdm-chooser-server.h" #define GDM_CHOOSER_SERVER_DBUS_PATH "/org/gnome/DisplayManager/ChooserServer" @@ -325,7 +326,7 @@ allow_user_function (DBusConnection *connection, return FALSE; } - pwent = getpwnam (chooser_server->priv->user_name); + gdm_get_pwent_for_name (chooser_server->priv->user_name, &pwent); if (pwent == NULL) { return FALSE; } diff --git a/daemon/gdm-display-access-file.c b/daemon/gdm-display-access-file.c index ee42a215..6497e3e3 100644 --- a/daemon/gdm-display-access-file.c +++ b/daemon/gdm-display-access-file.c @@ -209,7 +209,7 @@ _get_uid_and_gid_for_user (const char *username, g_assert (gid != NULL); errno = 0; - passwd_entry = getpwnam (username); + gdm_get_pwent_for_name (username, &passwd_entry); if (passwd_entry == NULL) { return FALSE; diff --git a/daemon/gdm-greeter-server.c b/daemon/gdm-greeter-server.c index b9d3b2e3..1ab01e47 100644 --- a/daemon/gdm-greeter-server.c +++ b/daemon/gdm-greeter-server.c @@ -43,6 +43,7 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> +#include "gdm-common.h" #include "gdm-greeter-server.h" #define GDM_GREETER_SERVER_DBUS_PATH "/org/gnome/DisplayManager/GreeterServer" @@ -894,7 +895,7 @@ allow_user_function (DBusConnection *connection, return FALSE; } - pwent = getpwnam (greeter_server->priv->user_name); + gdm_get_pwent_for_name (greeter_server->priv->user_name, &pwent); if (pwent == NULL) { return FALSE; } diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c index dfb526e1..339f3ccc 100644 --- a/daemon/gdm-server.c +++ b/daemon/gdm-server.c @@ -360,7 +360,7 @@ change_user (GdmServer *server) return; } - pwent = getpwnam (server->priv->user_name); + gdm_get_pwent_for_name (server->priv->user_name, &pwent); if (pwent == NULL) { g_warning (_("Server was to be spawned by user %s but that user doesn't exist"), server->priv->user_name); @@ -531,7 +531,7 @@ get_server_environment (GdmServer *server) if (server->priv->user_name != NULL) { struct passwd *pwent; - pwent = getpwnam (server->priv->user_name); + gdm_get_pwent_for_name (server->priv->user_name, &pwent); if (pwent->pw_dir != NULL && g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS)) { diff --git a/daemon/gdm-session-linux-auditor.c b/daemon/gdm-session-linux-auditor.c index 15425636..6c581f71 100644 --- a/daemon/gdm-session-linux-auditor.c +++ b/daemon/gdm-session-linux-auditor.c @@ -1,4 +1,4 @@ -/* gdm-session-linux-auditor.c - Object for Linux auditing of session login/logout +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004, 2008 Sun Microsystems, Inc. * Copyright (C) 2005, 2008 Red Hat, Inc. @@ -35,6 +35,8 @@ #include <glib.h> +#include "gdm-common.h" + struct _GdmSessionLinuxAuditorPrivate { int audit_fd; @@ -63,7 +65,7 @@ log_user_message (GdmSessionAuditor *auditor, g_object_get (G_OBJECT (auditor), "display-device", &display_device, NULL); if (username != NULL) { - pw = getpwnam (username); + gdm_get_pwent_for_name (username, &pw); } else { username = g_strdup ("unknown"); pw = NULL; diff --git a/daemon/gdm-session-solaris-auditor.c b/daemon/gdm-session-solaris-auditor.c index badbdbba..aa7c5c94 100644 --- a/daemon/gdm-session-solaris-auditor.c +++ b/daemon/gdm-session-solaris-auditor.c @@ -1,4 +1,4 @@ -/* gdm-session-solaris-auditor.c - Object for Solaris auditing of session login/logout +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004, 2008 Sun Microsystems, Inc. * Copyright (C) 2005, 2008 Red Hat, Inc. @@ -326,7 +326,7 @@ on_username_set (GdmSessionSolarisAuditor *auditor) g_object_get (G_OBJECT (auditor), "username", &username, NULL); - passwd_entry = getpwnam (username); + gdm_get_pwent_for_name (username, &passwd_entry); if (passwd_entry != NULL) { auditor->priv->uid = passwd_entry->pw_uid; diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c index d7cd4f8a..3715396c 100644 --- a/daemon/gdm-session-worker.c +++ b/daemon/gdm-session-worker.c @@ -52,6 +52,7 @@ #include "ck-connector.h" +#include "gdm-common.h" #include "gdm-session-worker.h" #include "gdm-marshal.h" @@ -210,7 +211,7 @@ open_ck_session (GdmSessionWorker *worker) is_local = FALSE; } - pwent = getpwnam (worker->priv->username); + gdm_get_pwent_for_name (worker->priv->username, &pwent); if (pwent == NULL) { goto out; } @@ -1095,7 +1096,7 @@ gdm_session_worker_cache_userfiles (GdmSessionWorker *worker) char *userfile; gboolean res; - passwd_entry = getpwnam (worker->priv->username); + gdm_get_pwent_for_name (worker->priv->username, &passwd_entry); if (passwd_entry == NULL) return; @@ -1603,6 +1604,7 @@ _lookup_passwd_info (const char *username, * passwd_entry doesn't potentially get stomped on * by a PAM module */ + again: passwd_entry = NULL; #ifdef HAVE_POSIX_GETPWNAM_R errno = getpwnam_r (username, @@ -1617,8 +1619,10 @@ _lookup_passwd_info (const char *username, (size_t) aux_buffer_size); errno = 0; #endif /* !HAVE_POSIX_GETPWNAM_R */ - - if (errno != 0) { + if (errno == EINTR) { + g_debug ("%s", g_strerror (errno)); + goto again; + } else if (errno != 0) { g_warning ("%s", g_strerror (errno)); goto out; } @@ -1982,7 +1986,7 @@ gdm_session_worker_start_user_session (GdmSessionWorker *worker, register_ck_session (worker); - passwd_entry = getpwnam (worker->priv->username); + gdm_get_pwent_for_name (worker->priv->username, &passwd_entry); #ifdef HAVE_LOGINDEVPERM /* diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c index c0c40381..f0e93d52 100644 --- a/daemon/gdm-slave.c +++ b/daemon/gdm-slave.c @@ -201,7 +201,7 @@ get_script_environment (GdmSlave *slave, g_hash_table_insert (hash, g_strdup ("USERNAME"), g_strdup (username)); - pwent = getpwnam (username); + gdm_get_pwent_for_name (username, &pwent); if (pwent != NULL) { if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') { g_hash_table_insert (hash, g_strdup ("HOME"), @@ -1018,7 +1018,7 @@ gdm_slave_get_timed_login_details (GdmSlave *slave, g_free (username); if (usernamep != NULL && *usernamep != NULL) { - pwent = getpwnam (*usernamep); + gdm_get_pwent_for_name (*usernamep, &pwent); if (pwent == NULL) { g_debug ("Invalid username %s for auto/timed login", *usernamep); @@ -1052,7 +1052,7 @@ _get_uid_and_gid_for_user (const char *username, g_assert (username != NULL); errno = 0; - passwd_entry = getpwnam (username); + gdm_get_pwent_for_name (username, &passwd_entry); if (passwd_entry == NULL) { return FALSE; diff --git a/daemon/gdm-welcome-session.c b/daemon/gdm-welcome-session.c index 8275d99b..ac16a73f 100644 --- a/daemon/gdm-welcome-session.c +++ b/daemon/gdm-welcome-session.c @@ -147,7 +147,7 @@ open_welcome_session (GdmWelcomeSession *welcome_session) session_type = "LoginWindow"; - pwent = getpwnam (welcome_session->priv->user_name); + gdm_get_pwent_for_name (welcome_session->priv->user_name, &pwent); if (pwent == NULL) { /* FIXME: */ g_warning ("Couldn't look up uid"); @@ -415,7 +415,7 @@ get_welcome_environment (GdmWelcomeSession *welcome_session, g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup ("/")); g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup ("/bin/sh")); - pwent = getpwnam (welcome_session->priv->user_name); + gdm_get_pwent_for_name (welcome_session->priv->user_name, &pwent); if (pwent != NULL) { if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') { g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup (pwent->pw_dir)); @@ -543,7 +543,7 @@ spawn_child_setup (SpawnChildData *data) return; } - pwent = getpwnam (data->user_name); + gdm_get_pwent_for_name (data->user_name, &pwent); if (pwent == NULL) { g_warning (_("User %s doesn't exist"), data->user_name); diff --git a/daemon/main.c b/daemon/main.c index cfbc6c48..19bdf302 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -402,7 +402,7 @@ gdm_daemon_change_user (uid_t *uidp, g_debug ("Changing user:group to %s:%s", username, groupname); /* Lookup user and groupid for the GDM user */ - pwent = getpwnam (username); + gdm_get_pwent_for_name (username, &pwent); /* Set uid and gid */ if G_UNLIKELY (pwent == NULL) { diff --git a/gui/simple-greeter/gdm-user-manager.c b/gui/simple-greeter/gdm-user-manager.c index 31b5f0f4..92a0421e 100644 --- a/gui/simple-greeter/gdm-user-manager.c +++ b/gui/simple-greeter/gdm-user-manager.c @@ -1166,6 +1166,42 @@ failed: unload_new_session (new_session); } +static gboolean +get_pwent_for_name (const char *name, + struct passwd **pwentp) +{ + struct passwd *pwent; + + do { + errno = 0; + pwent = getpwnam (name); + } while (pwent == NULL && errno == EINTR); + + if (pwentp != NULL) { + *pwentp = pwent; + } + + return (pwent != NULL); +} + +static gboolean +get_pwent_for_uid (uid_t uid, + struct passwd **pwentp) +{ + struct passwd *pwent; + + do { + errno = 0; + pwent = getpwuid (uid); + } while (pwent == NULL && errno == EINTR); + + if (pwentp != NULL) { + *pwentp = pwent; + } + + return (pwent != NULL); +} + static void maybe_add_new_session (GdmUserManagerNewSession *new_session) { @@ -1176,7 +1212,7 @@ maybe_add_new_session (GdmUserManagerNewSession *new_session) manager = GDM_USER_MANAGER (new_session->manager); errno = 0; - pwent = getpwuid (new_session->uid); + get_pwent_for_uid (new_session->uid, &pwent); if (pwent == NULL) { g_warning ("Unable to lookup user ID %d: %s", (int) new_session->uid, g_strerror (errno)); @@ -1493,7 +1529,7 @@ gdm_user_manager_get_user (GdmUserManager *manager, } } else { struct passwd *pwent; - pwent = getpwnam (username); + get_pwent_for_name (username, &pwent); if (pwent != NULL) { user = add_new_user_for_pwent (manager, pwent); } @@ -1511,7 +1547,7 @@ gdm_user_manager_get_user_by_uid (GdmUserManager *manager, g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL); - pwent = getpwuid (uid); + get_pwent_for_uid (uid, &pwent); if (pwent == NULL) { g_warning ("GdmUserManager: unable to lookup uid %d", (int)uid); return NULL; @@ -1900,7 +1936,8 @@ reload_passwd_file (GHashTable *valid_shells, g_hash_table_iter_init (&iter, current_users_by_name); while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) { struct passwd *pwent; - pwent = getpwnam (name); + + get_pwent_for_name (name, &pwent); if (pwent == NULL) { continue; } @@ -1914,7 +1951,8 @@ reload_passwd_file (GHashTable *valid_shells, GSList *l; for (l = include_users; l != NULL; l = l->next) { struct passwd *pwent; - pwent = getpwnam (l->data); + + get_pwent_for_name (l->data, &pwent); if (pwent == NULL) { continue; } |