summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Jon McCann <jmccann@redhat.com>2010-06-30 10:20:43 -0400
committerWilliam Jon McCann <jmccann@redhat.com>2010-06-30 10:20:43 -0400
commit6e4f853c9b23d0e464c571558054b1dfee60a278 (patch)
tree22f2b7c45b38e29787e8951941932ee46ac1cb95
parent9fe7fea40ba743ab3d6f17dba39adfd2629fb0ac (diff)
downloadgdm-6e4f853c9b23d0e464c571558054b1dfee60a278.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.c19
-rw-r--r--common/gdm-common.h3
-rw-r--r--daemon/gdm-chooser-server.c3
-rw-r--r--daemon/gdm-display-access-file.c2
-rw-r--r--daemon/gdm-greeter-server.c3
-rw-r--r--daemon/gdm-server.c4
-rw-r--r--daemon/gdm-session-linux-auditor.c6
-rw-r--r--daemon/gdm-session-solaris-auditor.c4
-rw-r--r--daemon/gdm-session-worker.c14
-rw-r--r--daemon/gdm-slave.c6
-rw-r--r--daemon/gdm-welcome-session.c6
-rw-r--r--daemon/main.c2
-rw-r--r--gui/simple-greeter/gdm-user-manager.c49
13 files changed, 94 insertions, 27 deletions
diff --git a/common/gdm-common.c b/common/gdm-common.c
index b428f5b8..1b344f33 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 (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 191bd70a..ae7469e0 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"
@@ -33,6 +34,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 1b52f153..2fc0c785 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 cecce830..0c67f1e0 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"
@@ -885,7 +886,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 c8291990..feaf6736 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 ea3662af..35a6bfec 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 a3d43fc4..2915da0c 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 9fc67170..39c53d8f 100644
--- a/daemon/gdm-welcome-session.c
+++ b/daemon/gdm-welcome-session.c
@@ -145,7 +145,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");
@@ -412,7 +412,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));
@@ -530,7 +530,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 89b5bef5..ddc4ca35 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -408,7 +408,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 2b6bd47b..b0fd88a4 100644
--- a/gui/simple-greeter/gdm-user-manager.c
+++ b/gui/simple-greeter/gdm-user-manager.c
@@ -998,6 +998,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 (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 (errno != EINTR);
+
+ if (pwentp != NULL) {
+ *pwentp = pwent;
+ }
+
+ return (pwent != NULL);
+}
+
static void
maybe_add_new_session (GdmUserManagerNewSession *new_session)
{
@@ -1009,7 +1045,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));
@@ -1274,8 +1310,7 @@ gdm_user_manager_get_user (GdmUserManager *manager,
if (user == NULL) {
struct passwd *pwent;
- pwent = getpwnam (username);
-
+ get_pwent_for_name (username, &pwent);
if (pwent != NULL) {
user = add_new_user_for_pwent (manager, pwent);
}
@@ -1293,7 +1328,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;
@@ -1689,7 +1724,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;
}
@@ -1703,7 +1739,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;
}