summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Lebl <jirka@5z.com>2001-09-27 04:10:06 +0000
committerGeorge Lebl <jirka@src.gnome.org>2001-09-27 04:10:06 +0000
commitfed3c0d16a1bfd742e1ee455986aa7cbfe8f1d10 (patch)
tree87d951e9f98594fe34e7e8335309c1fe6ae38efa
parent7dba418955f0a06edaa1a1e4d48180d5ad610129 (diff)
downloadgdm-fed3c0d16a1bfd742e1ee455986aa7cbfe8f1d10.tar.gz
Add a failsafe question dialog similar in operation to the failsafe error
Wed Sep 26 21:01:38 2001 George Lebl <jirka@5z.com> * daemon/verify.h, daemon/verify-*.c, daemon/slave.c, daemon/errorgui.[ch], daemon/gdm.c: Add a failsafe question dialog similar in operation to the failsafe error box, and use it in the standalone pam conv function. Kill all instances of PAM_SILENT since we can now always converse with the user. * daemon/verify-pam.c: use a global pamh again but this time a bit smarter. Make sure if we use a global one that it has all the right things set. Also set PAM_RHOST to "localhost" or the remote host if not a "console" login. Set PAM_RUSER to "gdm" (or whatever the gdm user is). I'm sure I'm fucking something up again but I can't find enough docs to verify that what I'm doing is 100% correct. Not to mention that there seem to be some braindead modules out there to begin with.
-rw-r--r--ChangeLog17
-rw-r--r--daemon/errorgui.c153
-rw-r--r--daemon/errorgui.h11
-rw-r--r--daemon/gdm.c19
-rw-r--r--daemon/slave.c22
-rw-r--r--daemon/verify-crypt.c12
-rw-r--r--daemon/verify-pam.c295
-rw-r--r--daemon/verify-shadow.c10
-rw-r--r--daemon/verify.h11
9 files changed, 467 insertions, 83 deletions
diff --git a/ChangeLog b/ChangeLog
index 47c473f9..7659744c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+Wed Sep 26 21:01:38 2001 George Lebl <jirka@5z.com>
+
+ * daemon/verify.h, daemon/verify-*.c, daemon/slave.c,
+ daemon/errorgui.[ch], daemon/gdm.c: Add a failsafe question
+ dialog similar in operation to the failsafe error box, and use
+ it in the standalone pam conv function. Kill all instances of
+ PAM_SILENT since we can now always converse with the user.
+
+ * daemon/verify-pam.c: use a global pamh again but this time a bit
+ smarter. Make sure if we use a global one that it has all the
+ right things set. Also set PAM_RHOST to "localhost" or the remote
+ host if not a "console" login. Set PAM_RUSER to "gdm" (or whatever
+ the gdm user is). I'm sure I'm fucking something up again but
+ I can't find enough docs to verify that what I'm doing is 100%
+ correct. Not to mention that there seem to be some braindead
+ modules out there to begin with.
+
Mon Sep 17 07:17:32 2001 George Lebl <jirka@5z.com>
* gui/gdmlogin.c: fix crash when quiver would happen while
diff --git a/daemon/errorgui.c b/daemon/errorgui.c
index a4aeb03f..10ba0f9e 100644
--- a/daemon/errorgui.c
+++ b/daemon/errorgui.c
@@ -172,4 +172,157 @@ gdm_error_box (GdmDisplay *d, const char *dialog_type, const char *error)
}
}
+char *
+gdm_run_failsafe_question (const char *question,
+ gboolean echo,
+ int screenx,
+ int screeny,
+ int screenwidth,
+ int screenheight)
+{
+ GtkWidget *dialog;
+ GtkRequisition req;
+ guint sid;
+ GtkWidget *entry, *label;
+ char *ret;
+ char **argv = g_new0 (char *, 2);
+ argv[0] = "gdm-failsafe-question";
+
+ /* Avoid creating ~gdm/.gnome stuff */
+ gnome_do_not_create_directories = TRUE;
+
+ gnome_init ("gdm-failsafe-question", VERSION, 1, argv);
+
+ sid = gtk_signal_lookup ("event",
+ GTK_TYPE_WIDGET);
+ gtk_signal_add_emission_hook (sid,
+ gdm_event,
+ NULL);
+
+ dialog = gnome_dialog_new (question,
+ GNOME_STOCK_BUTTON_OK,
+ NULL);
+ gnome_dialog_close_hides (GNOME_DIALOG (dialog),
+ TRUE /* just_hide */);
+
+ label = gtk_label_new (question);
+ gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox),
+ label, FALSE, FALSE, 0);
+ entry = gtk_entry_new ();
+ gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox),
+ entry, FALSE, FALSE, 0);
+ if ( ! echo)
+ gtk_entry_set_visibility (GTK_ENTRY (entry),
+ FALSE /* visible */);
+ gnome_dialog_editable_enters (GNOME_DIALOG (dialog),
+ GTK_EDITABLE (entry));
+
+ gtk_widget_show_all (dialog);
+
+ gtk_widget_size_request (dialog, &req);
+
+ if (screenwidth <= 0)
+ screenwidth = gdk_screen_width ();
+ if (screenheight <= 0)
+ screenheight = gdk_screen_height ();
+
+ gtk_widget_set_uposition (dialog,
+ screenx +
+ (screenwidth / 2) -
+ (req.width / 2),
+ screeny +
+ (screenheight / 2) -
+ (req.height / 2));
+
+ gtk_widget_grab_focus (entry);
+
+ gtk_widget_show_now (dialog);
+
+ if (dialog->window != NULL) {
+ gdk_error_trap_push ();
+ XSetInputFocus (GDK_DISPLAY (),
+ GDK_WINDOW_XWINDOW (dialog->window),
+ RevertToPointerRoot,
+ CurrentTime);
+ gdk_flush ();
+ gdk_error_trap_pop ();
+ }
+
+ gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
+
+ ret = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+ gtk_widget_destroy (dialog);
+ return ret;
+}
+
+char *
+gdm_failsafe_question (GdmDisplay *d,
+ const char *question,
+ gboolean echo)
+{
+ pid_t pid;
+ int p[2];
+
+ if (pipe (p) < 0)
+ return NULL;
+
+ gdm_safe_fork (&extra_process);
+ pid = extra_process;
+ if (pid == 0) {
+ char *geom;
+ int i;
+
+ for (i = 0; i < sysconf (_SC_OPEN_MAX); i++) {
+ if (p[1] != i)
+ close(i);
+ }
+
+ /* No error checking here - if it's messed the best response
+ * is to ignore & try to continue */
+ open ("/dev/null", O_RDONLY); /* open stdin - fd 0 */
+ open ("/dev/null", O_RDWR); /* open stdout - fd 1 */
+ open ("/dev/null", O_RDWR); /* open stderr - fd 2 */
+
+ /* The pipe on stdout */
+ dup2 (p[1], 1);
+
+ if (d != NULL)
+ geom = g_strdup_printf ("%d:%d:%d:%d",
+ d->screenx,
+ d->screeny,
+ d->screenwidth,
+ d->screenheight);
+ else
+ geom = "0:0:0:0";
+
+ if (stored_path != NULL)
+ putenv (stored_path);
+ execlp (stored_argv[0],
+ stored_argv[0],
+ "--run-failsafe-question",
+ question,
+ echo ? "TRUE" : "FALSE",
+ geom,
+ NULL);
+ gdm_error (_("gdm_failsafe_question: Failed to execute self"));
+ _exit (1);
+ } else if (pid > 0) {
+ char buf[BUFSIZ];
+ int bytes;
+ close (p[1]);
+ waitpid (pid, 0, 0);
+ extra_process = -1;
+ bytes = read (p[0], buf, BUFSIZ-1);
+ if (bytes > 0) {
+ close (p[0]);
+ buf[bytes] = '\0';
+ return g_strdup (buf);
+ }
+ close (p[0]);
+ } else {
+ gdm_error (_("gdm_failsafe_question: Cannot fork to display error/info box"));
+ }
+ return NULL;
+}
+
/* EOF */
diff --git a/daemon/errorgui.h b/daemon/errorgui.h
index be9af821..fa4e6275 100644
--- a/daemon/errorgui.h
+++ b/daemon/errorgui.h
@@ -33,6 +33,17 @@ void gdm_error_box (GdmDisplay *d,
const char *dialog_type,
const char *error);
+char * gdm_run_failsafe_question(const char *question,
+ gboolean echo,
+ int screenx,
+ int screeny,
+ int screenwidth,
+ int screenheight);
+/* this spawns self with the argument to run the above */
+char * gdm_failsafe_question (GdmDisplay *d,
+ const char *question,
+ gboolean echo);
+
#endif /* GDM_ERRORGUI_H */
/* EOF */
diff --git a/daemon/gdm.c b/daemon/gdm.c
index 677c9aa3..73ca9939 100644
--- a/daemon/gdm.c
+++ b/daemon/gdm.c
@@ -1231,6 +1231,25 @@ main (int argc, char *argv[])
gdm_run_errorgui (argv[2], argv[3], x, y, width, height);
_exit (0);
}
+ /* This is another utter hack. Same as above but for questions */
+ if (argc == 5 &&
+ strcmp (argv[1], "--run-failsafe-question") == 0) {
+ int x = 0, y = 0, width = 0, height = 0;
+ gboolean echo;
+ char *ret;
+ sscanf (argv[4], "%d:%d:%d:%d", &x, &y, &width, &height);
+ if (strcmp (argv[3], "FALSE") == 0)
+ echo = FALSE;
+ else
+ echo = TRUE;
+ ret = gdm_run_failsafe_question (argv[2], echo, x, y, width, height);
+ if (ret != NULL) {
+ g_print (ret);
+ fflush (stdout);
+ }
+ _exit (0);
+ }
+
/* XDM compliant error message */
if (getuid() != 0) {
diff --git a/daemon/slave.c b/daemon/slave.c
index 6bcee30b..be386390 100644
--- a/daemon/slave.c
+++ b/daemon/slave.c
@@ -268,7 +268,7 @@ setup_automatic_session (GdmDisplay *display, const char *name)
greet = FALSE;
gdm_debug ("setup_automatic_session: Automatic login: %s", login);
- gdm_verify_setup_user (login, display->name);
+ gdm_verify_setup_user (display, login, display->name);
/* Run the init script. gdmslave suspends until script
* has terminated */
@@ -679,7 +679,8 @@ gdm_slave_wait_for_login (void)
setegid (0);
gdm_debug ("gdm_slave_wait_for_login: In loop");
- login = gdm_verify_user (NULL /* username*/,
+ login = gdm_verify_user (d,
+ NULL /* username*/,
d->name,
d->console);
gdm_debug ("gdm_slave_wait_for_login: end verify for '%s'",
@@ -705,7 +706,8 @@ gdm_slave_wait_for_login (void)
oldAllowRoot = GdmAllowRoot;
GdmAllowRoot = TRUE;
gdm_slave_greeter_ctl_no_ret (GDM_SETLOGIN, "root");
- login = gdm_verify_user ("root",
+ login = gdm_verify_user (d,
+ "root",
d->name,
d->console);
GdmAllowRoot = oldAllowRoot;
@@ -762,7 +764,7 @@ gdm_slave_wait_for_login (void)
* may have sighupped the main gdm server and with it
* wiped us */
- gdm_verify_cleanup ();
+ gdm_verify_cleanup (d);
gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE);
@@ -1953,7 +1955,7 @@ gdm_slave_session_start (void)
/* setup the verify env vars, set credentials and such stuff
* and open the session */
- if ( ! gdm_verify_open_session ())
+ if ( ! gdm_verify_open_session (d))
gdm_child_exit (DISPLAY_REMANAGE,
_("%s: Could not open session for %s. "
"Aborting."),
@@ -2177,7 +2179,7 @@ gdm_slave_session_stop (pid_t sesspid)
if (sesspid > 0)
kill (- (sesspid), SIGTERM);
- gdm_verify_cleanup();
+ gdm_verify_cleanup (d);
pwent = getpwnam (local_login); /* PAM overwrites our pwent */
@@ -2259,7 +2261,7 @@ gdm_slave_term_handler (int sig)
gdm_debug ("gdm_slave_term_handler: Whacking server");
gdm_server_stop (d);
- gdm_verify_cleanup();
+ gdm_verify_cleanup (d);
_exit (DISPLAY_ABORT);
}
@@ -2327,7 +2329,7 @@ gdm_slave_child_handler (int sig)
/* if greet is TRUE, then the greeter died outside of our
* control really, so clean up and die, something is wrong */
gdm_server_stop (d);
- gdm_verify_cleanup ();
+ gdm_verify_cleanup (d);
if (WIFEXITED (status)) {
_exit (WEXITSTATUS (status));
@@ -2395,7 +2397,7 @@ gdm_slave_xioerror_handler (Display *disp)
gdm_error (_("gdm_slave_xioerror_handler: Fatal X error - Restarting %s"), d->name);
gdm_server_stop (d);
- gdm_verify_cleanup ();
+ gdm_verify_cleanup (d);
if (do_xfailed_on_xio_error)
_exit (DISPLAY_XFAILED);
@@ -2463,7 +2465,7 @@ gdm_slave_exit (gint status, const gchar *format, ...)
setegid (0);
gdm_server_stop (d);
- gdm_verify_cleanup ();
+ gdm_verify_cleanup (d);
/* Kill children where applicable */
if (d->greetpid != 0)
diff --git a/daemon/verify-crypt.c b/daemon/verify-crypt.c
index 14cd8f23..450cef49 100644
--- a/daemon/verify-crypt.c
+++ b/daemon/verify-crypt.c
@@ -22,7 +22,7 @@
#include <pwd.h>
#ifdef HAVE_CRYPT
- #include <crypt.h>
+# include <crypt.h>
#endif /* HAVE_CRYPT */
#include <vicious.h>
@@ -54,7 +54,8 @@ extern gboolean GdmAllowRemoteRoot;
*/
gchar *
-gdm_verify_user (const char *username,
+gdm_verify_user (GdmDisplay *d,
+ const char *username,
const gchar *display,
gboolean local)
{
@@ -203,7 +204,8 @@ gdm_verify_user (const char *username,
*/
void
-gdm_verify_setup_user (const gchar *login, const gchar *display)
+gdm_verify_setup_user (GdmDisplay *d,
+ const gchar *login, const gchar *display)
{
}
@@ -215,7 +217,7 @@ gdm_verify_setup_user (const gchar *login, const gchar *display)
*/
void
-gdm_verify_cleanup (void)
+gdm_verify_cleanup (GdmDisplay *d)
{
}
@@ -234,7 +236,7 @@ gdm_verify_check (void)
/* used in pam */
gboolean
-gdm_verify_open_session (void)
+gdm_verify_open_session (GdmDisplay *d)
{
return TRUE;
}
diff --git a/daemon/verify-pam.c b/daemon/verify-pam.c
index 331dae8c..2bfe1b1f 100644
--- a/daemon/verify-pam.c
+++ b/daemon/verify-pam.c
@@ -29,6 +29,7 @@
#include "misc.h"
#include "slave.h"
#include "verify.h"
+#include "errorgui.h"
static const gchar RCSid[]="$Id$";
@@ -38,11 +39,15 @@ extern gboolean GdmVerboseAuth;
extern gboolean GdmAllowRoot;
extern gboolean GdmAllowRemoteRoot;
extern gchar *GdmTimedLogin;
+extern gchar *GdmUser;
extern gboolean GdmAllowRemoteAutoLogin;
/* Evil, but this way these things are passed to the child session */
static char *current_login = NULL;
static char *current_display = NULL;
+static pam_handle_t *pamh = NULL;
+
+static GdmDisplay *cur_gdm_disp = NULL;
/* Internal PAM conversation function. Interfaces between the PAM
@@ -125,8 +130,69 @@ gdm_verify_standalone_pam_conv (int num_msg, const struct pam_message **msg,
struct pam_response **resp,
void *appdata_ptr)
{
- /* FIXME: always error out for now! */
- return PAM_CONV_ERR;
+ int replies = 0;
+ char *s;
+ struct pam_response *reply = NULL;
+
+ reply = malloc (sizeof (struct pam_response) * num_msg);
+
+ if (!reply)
+ return PAM_CONV_ERR;
+
+ memset (reply, 0, sizeof (struct pam_response) * num_msg);
+
+ for (replies = 0; replies < num_msg; replies++) {
+
+ switch (msg[replies]->msg_style) {
+
+ case PAM_PROMPT_ECHO_ON:
+ /* PAM requested textual input with echo on */
+ s = gdm_failsafe_question (cur_gdm_disp,
+ _((gchar *) msg[replies]->msg),
+ TRUE /* echo */);
+ reply[replies].resp_retcode = PAM_SUCCESS;
+ reply[replies].resp = strdup (ve_sure_string (s));
+ g_free (s);
+ break;
+
+ case PAM_PROMPT_ECHO_OFF:
+ /* PAM requested textual input with echo off */
+ s = gdm_failsafe_question (cur_gdm_disp,
+ _((gchar *) msg[replies]->msg),
+ FALSE /* echo */);
+ reply[replies].resp_retcode = PAM_SUCCESS;
+ reply[replies].resp = strdup (ve_sure_string (s));
+ g_free (s);
+ break;
+
+ case PAM_ERROR_MSG:
+ /* PAM sent a message that should displayed to the user */
+ gdm_error_box (cur_gdm_disp,
+ GNOME_MESSAGE_BOX_ERROR,
+ _((gchar *) msg[replies]->msg));
+ reply[replies].resp_retcode = PAM_SUCCESS;
+ reply[replies].resp = NULL;
+ break;
+
+ case PAM_TEXT_INFO:
+ /* PAM sent a message that should displayed to the user */
+ gdm_error_box (cur_gdm_disp,
+ GNOME_MESSAGE_BOX_INFO,
+ _((gchar *) msg[replies]->msg));
+ reply[replies].resp_retcode = PAM_SUCCESS;
+ reply[replies].resp = NULL;
+ break;
+
+ default:
+ /* PAM has been smoking serious crack */
+ free (reply);
+ return PAM_CONV_ERR;
+ }
+
+ }
+
+ *resp = reply;
+ return PAM_SUCCESS;
}
static struct pam_conv standalone_pamc = {
@@ -148,7 +214,8 @@ static struct pam_conv standalone_pamc = {
*/
gchar *
-gdm_verify_user (const char *username,
+gdm_verify_user (GdmDisplay *d,
+ const char *username,
const gchar *display,
gboolean local)
{
@@ -158,7 +225,10 @@ gdm_verify_user (const char *username,
gboolean error_msg_given = FALSE;
gboolean started_timer = FALSE;
gchar *auth_errmsg;
- pam_handle_t *pamh;
+
+ if (pamh != NULL)
+ pam_end (pamh, PAM_SUCCESS);
+ pamh = NULL;
/* start the timer for timed logins */
if (local ||
@@ -180,6 +250,8 @@ gdm_verify_user (const char *username,
} else {
login = g_strdup (username);
}
+
+ cur_gdm_disp = d;
/* Initialize a PAM session for the user */
if ((pamerr = pam_start ("gdm", login, &pamc, &pamh)) != PAM_SUCCESS) {
@@ -199,6 +271,26 @@ gdm_verify_user (const char *username,
goto pamerr;
}
+ /* gdm is requesting the login */
+ if ((pamerr = pam_set_item (pamh, PAM_RUSER, GdmUser)) != PAM_SUCCESS) {
+ if (started_timer)
+ gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
+ if (gdm_slave_should_complain ())
+ gdm_error (_("Can't set PAM_RUSER=%s"), GdmUser);
+ goto pamerr;
+ }
+
+ /* From the host of the display */
+ if ((pamerr = pam_set_item (pamh, PAM_RHOST,
+ d->console ? "localhost" : d->hostname)) != PAM_SUCCESS) {
+ if (started_timer)
+ gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
+ if (gdm_slave_should_complain ())
+ gdm_error (_("Can't set PAM_RHOST=%s"),
+ d->console ? "localhost" : d->hostname);
+ goto pamerr;
+ }
+
/* Start authentication session */
if ((pamerr = pam_authenticate (pamh, 0)) != PAM_SUCCESS) {
if (started_timer)
@@ -262,8 +354,6 @@ gdm_verify_user (const char *username,
goto pamerr;
}
- pam_end (pamh, PAM_SUCCESS);
-
/* Workaround to avoid gdm messages being logged as PAM_pwdb */
closelog ();
openlog ("gdm", LOG_PID, LOG_DAEMON);
@@ -272,6 +362,8 @@ gdm_verify_user (const char *username,
current_login = g_strdup (login);
g_free (current_display);
current_display = g_strdup (display);
+
+ cur_gdm_disp = NULL;
return login;
@@ -298,7 +390,9 @@ gdm_verify_user (const char *username,
gdm_slave_greeter_ctl_no_ret (GDM_MSGERR, _("Please enter your username"));*/
}
- pam_end (pamh, pamerr);
+ if (pamh != NULL)
+ pam_end (pamh, pamerr);
+ pamh = NULL;
/* Workaround to avoid gdm messages being logged as PAM_pwdb */
closelog ();
@@ -311,9 +405,108 @@ gdm_verify_user (const char *username,
g_free (login);
+ cur_gdm_disp = NULL;
+
return NULL;
}
+/* Ensures a pamh existance */
+static gboolean
+ensure_pamh (GdmDisplay *d,
+ const char *login,
+ const char *display,
+ int *pamerr)
+{
+ if (login == NULL ||
+ display == NULL) {
+ gdm_error (_("Cannot setup pam handle with null login "
+ "and/or display"));
+ return FALSE;
+ }
+
+ g_assert (pamerr != NULL);
+
+ if (pamh != NULL) {
+ const char *item;
+
+ /* Make sure this is the right pamh */
+ if (pam_get_item (pamh, PAM_USER, (const void **)&item)
+ != PAM_SUCCESS)
+ goto ensure_create;
+
+ if (item == NULL ||
+ strcmp (item, login) != 0)
+ goto ensure_create;
+
+ if (pam_get_item (pamh, PAM_TTY, (const void **)&item)
+ != PAM_SUCCESS)
+ goto ensure_create;
+
+ if (item == NULL ||
+ strcmp (item, display) != 0)
+ goto ensure_create;
+
+ /* ensure some parameters */
+ if (pam_set_item (pamh, PAM_CONV, &standalone_pamc)
+ != PAM_SUCCESS) {
+ goto ensure_create;
+ }
+ if (pam_set_item (pamh, PAM_RUSER, GdmUser)
+ != PAM_SUCCESS) {
+ goto ensure_create;
+ }
+ if (d->console) {
+ if (pam_set_item (pamh, PAM_RHOST, "localhost")
+ != PAM_SUCCESS) {
+ goto ensure_create;
+ }
+ } else {
+ if (pam_set_item (pamh, PAM_RHOST, d->hostname)
+ != PAM_SUCCESS) {
+ goto ensure_create;
+ }
+ }
+ return TRUE;
+ }
+
+ensure_create:
+ if (pamh != NULL)
+ pam_end (pamh, PAM_SUCCESS);
+ pamh = NULL;
+
+ /* Initialize a PAM session for the user */
+ if ((*pamerr = pam_start ("gdm", login, &standalone_pamc, &pamh)) != PAM_SUCCESS) {
+ if (gdm_slave_should_complain ())
+ gdm_error (_("Can't find /etc/pam.d/gdm!"));
+ return FALSE;
+ }
+
+ /* Inform PAM of the user's tty */
+ if ((*pamerr = pam_set_item (pamh, PAM_TTY, display)) != PAM_SUCCESS) {
+ if (gdm_slave_should_complain ())
+ gdm_error (_("Can't set PAM_TTY=%s"), display);
+ return FALSE;
+ }
+
+ /* gdm is requesting the login */
+ if ((*pamerr = pam_set_item (pamh, PAM_RUSER, GdmUser)) != PAM_SUCCESS) {
+ if (gdm_slave_should_complain ())
+ gdm_error (_("Can't set PAM_RUSER=%s"), GdmUser);
+ return FALSE;
+ }
+
+ /* From the host of the display */
+ if ((*pamerr = pam_set_item (pamh, PAM_RHOST,
+ d->console ? "localhost" : d->hostname)) != PAM_SUCCESS) {
+ if (gdm_slave_should_complain ())
+ gdm_error (_("Can't set PAM_RHOST=%s"),
+ d->console ? "localhost" : d->hostname);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/**
* gdm_verify_setup_user:
* @login: The name of the user
@@ -324,30 +517,23 @@ gdm_verify_user (const char *username,
*/
void
-gdm_verify_setup_user (const gchar *login, const gchar *display)
+gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display)
{
- pam_handle_t *pamh;
gint pamerr;
if (!login)
return;
+ cur_gdm_disp = d;
+
/* Initialize a PAM session for the user */
- if ((pamerr = pam_start ("gdm", login, &standalone_pamc, &pamh)) != PAM_SUCCESS) {
- if (gdm_slave_should_complain ())
- gdm_error (_("Can't find /etc/pam.d/gdm!"));
- goto setup_pamerr;
- }
-
- /* Inform PAM of the user's tty */
- if ((pamerr = pam_set_item (pamh, PAM_TTY, display)) != PAM_SUCCESS) {
- if (gdm_slave_should_complain ())
- gdm_error (_("Can't set PAM_TTY=%s"), display);
+ if ( ! ensure_pamh (d, login, display, &pamerr)) {
goto setup_pamerr;
}
/* If the user's password has expired, ask for a new one */
- /* FIXME: This would require our conversation function to work */
+ /* This is for automatic logins, we shouldn't bother the user
+ * though I'm unsure */
#if 0
pamerr = pam_acct_mgmt (pamh, 0);
@@ -360,8 +546,6 @@ gdm_verify_setup_user (const gchar *login, const gchar *display)
}
#endif
- pam_end (pamh, PAM_SUCCESS);
-
/* Workaround to avoid gdm messages being logged as PAM_pwdb */
closelog ();
openlog ("gdm", LOG_PID, LOG_DAEMON);
@@ -371,11 +555,15 @@ gdm_verify_setup_user (const gchar *login, const gchar *display)
g_free (current_display);
current_display = g_strdup (display);
+ cur_gdm_disp = NULL;
+
return;
setup_pamerr:
- pam_end (pamh, pamerr);
+ if (pamh != NULL)
+ pam_end (pamh, pamerr);
+ pamh = NULL;
/* Workaround to avoid gdm messages being logged as PAM_pwdb */
closelog ();
@@ -385,6 +573,8 @@ gdm_verify_setup_user (const gchar *login, const gchar *display)
current_login = NULL;
g_free (current_display);
current_display = NULL;
+
+ cur_gdm_disp = NULL;
}
@@ -395,38 +585,28 @@ gdm_verify_setup_user (const gchar *login, const gchar *display)
*/
void
-gdm_verify_cleanup (void)
+gdm_verify_cleanup (GdmDisplay *d)
{
- pam_handle_t *pamh;
gint pamerr;
if (current_login == NULL)
return;
+ cur_gdm_disp = d;
+
/* Initialize a PAM session for the user */
- if ((pamerr = pam_start ("gdm", current_login,
- &standalone_pamc, &pamh)) != PAM_SUCCESS) {
- if (gdm_slave_should_complain ())
- gdm_error (_("Can't find /etc/pam.d/gdm!"));
+ if ( ! ensure_pamh (d, current_login, current_display, &pamerr)) {
goto cleanup_pamerr;
}
-
- /* Inform PAM of the user's tty */
- if (current_display != NULL &&
- (pamerr = pam_set_item
- (pamh, PAM_TTY, current_display)) != PAM_SUCCESS) {
- if (gdm_slave_should_complain ())
- gdm_error (_("Can't set PAM_TTY=%s"), current_display);
- goto cleanup_pamerr;
- }
-
/* FIXME: theoretically this closes even sessions that
* don't exist, which I suppose is OK */
- pam_close_session (pamh, PAM_SILENT);
+ pam_close_session (pamh, 0);
cleanup_pamerr:
- pam_end (pamh, pamerr);
+ if (pamh != NULL)
+ pam_end (pamh, pamerr);
+ pamh = NULL;
/* Workaround to avoid gdm messages being logged as PAM_pwdb */
closelog ();
@@ -436,6 +616,8 @@ cleanup_pamerr:
current_login = NULL;
g_free (current_display);
current_display = NULL;
+
+ cur_gdm_disp = NULL;
}
@@ -458,34 +640,23 @@ gdm_verify_check (void)
/* used in pam */
gboolean
-gdm_verify_open_session (void)
+gdm_verify_open_session (GdmDisplay *d)
{
gchar **pamenv;
- pam_handle_t *pamh;
gint pamerr;
if (current_login == NULL)
return FALSE;
+ cur_gdm_disp = d;
+
/* Initialize a PAM session for the user */
- if ((pamerr = pam_start ("gdm", current_login,
- &standalone_pamc, &pamh)) != PAM_SUCCESS) {
- if (gdm_slave_should_complain ())
- gdm_error (_("Can't find /etc/pam.d/gdm!"));
- goto open_pamerr;
- }
-
- /* Inform PAM of the user's tty */
- if (current_display != NULL &&
- (pamerr = pam_set_item
- (pamh, PAM_TTY, current_display)) != PAM_SUCCESS) {
- if (gdm_slave_should_complain ())
- gdm_error (_("Can't set PAM_TTY=%s"), current_display);
+ if ( ! ensure_pamh (d, current_login, current_display, &pamerr)) {
goto open_pamerr;
}
/* Register the session */
- if ((pamerr = pam_open_session (pamh, PAM_SILENT)) != PAM_SUCCESS) {
+ if ((pamerr = pam_open_session (pamh, 0)) != PAM_SUCCESS) {
if (gdm_slave_should_complain ())
gdm_error (_("Couldn't open session for %s"),
current_login);
@@ -493,7 +664,7 @@ gdm_verify_open_session (void)
}
/* Set credentials */
- if ((pamerr = pam_setcred (pamh, PAM_SILENT)) != PAM_SUCCESS) {
+ if ((pamerr = pam_setcred (pamh, 0)) != PAM_SUCCESS) {
if (gdm_slave_should_complain ())
gdm_error (_("Couldn't set credentials for %s"),
current_login);
@@ -511,12 +682,18 @@ gdm_verify_open_session (void)
}
open_pamerr:
- pam_end (pamh, pamerr);
+ if (pamerr != PAM_SUCCESS &&
+ pamh != NULL) {
+ pam_end (pamh, pamerr);
+ pamh = NULL;
+ }
/* Workaround to avoid gdm messages being logged as PAM_pwdb */
closelog ();
openlog ("gdm", LOG_PID, LOG_DAEMON);
+ cur_gdm_disp = NULL;
+
return (pamerr == PAM_SUCCESS);
}
diff --git a/daemon/verify-shadow.c b/daemon/verify-shadow.c
index 0bbe2547..74e468a0 100644
--- a/daemon/verify-shadow.c
+++ b/daemon/verify-shadow.c
@@ -23,7 +23,7 @@
#include <shadow.h>
#ifdef HAVE_CRYPT
- #include <crypt.h>
+# include <crypt.h>
#endif /* HAVE_CRYPT */
#include <vicious.h>
@@ -54,7 +54,7 @@ extern gboolean GdmAllowRemoteRoot;
*/
gchar *
-gdm_verify_user (const char *username, const gchar *display, gboolean local)
+gdm_verify_user (GdmDisplay *d, const char *username, const gchar *display, gboolean local)
{
gchar *login, *passwd, *ppasswd, *auth_errmsg;
struct passwd *pwent;
@@ -211,7 +211,7 @@ gdm_verify_user (const char *username, const gchar *display, gboolean local)
*/
void
-gdm_verify_setup_user (const gchar *login, const gchar *display)
+gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display)
{
}
@@ -222,7 +222,7 @@ gdm_verify_setup_user (const gchar *login, const gchar *display)
* Unregister the user's session */
void
-gdm_verify_cleanup (void)
+gdm_verify_cleanup (GdmDisplay *d)
{
}
@@ -242,7 +242,7 @@ gdm_verify_check (void)
/* used in pam */
gboolean
-gdm_verify_open_session (void)
+gdm_verify_open_session (GdmDisplay *d)
{
return TRUE;
}
diff --git a/daemon/verify.h b/daemon/verify.h
index 22b09c7e..236760e5 100644
--- a/daemon/verify.h
+++ b/daemon/verify.h
@@ -23,14 +23,17 @@
/* If username is NULL, we ask, if local is FALSE, don't start
* the timed login timer */
-gchar *gdm_verify_user (const char *username,
+gchar *gdm_verify_user (GdmDisplay *d,
+ const char *username,
const gchar *display,
gboolean local);
-void gdm_verify_cleanup (void);
+void gdm_verify_cleanup (GdmDisplay *d);
void gdm_verify_check (void);
/* used in pam */
-gboolean gdm_verify_open_session (void);
-void gdm_verify_setup_user (const gchar *login, const gchar *display) ;
+gboolean gdm_verify_open_session (GdmDisplay *d);
+void gdm_verify_setup_user (GdmDisplay *d,
+ const gchar *login,
+ const gchar *display) ;
#endif /* GDM_VERIFY_H */