X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fpasswd-pam.c;h=d463bc2de068da1e0129e4f012ed53ce2b08ba60;hb=4361b69d3178d7fc98d0388f9a223af6c2651aba;hp=334d12b913c83d8d42d7822099d47b727853a86c;hpb=6b1c86cf395f59389e4ece4ea8f4bea2c332745b;p=xscreensaver diff --git a/driver/passwd-pam.c b/driver/passwd-pam.c index 334d12b9..d463bc2d 100644 --- a/driver/passwd-pam.c +++ b/driver/passwd-pam.c @@ -1,7 +1,7 @@ /* passwd-pam.c --- verifying typed passwords with PAM * (Pluggable Authentication Modules.) * written by Bill Nottingham (and jwz) for - * xscreensaver, Copyright (c) 1993-2008 Jamie Zawinski + * xscreensaver, Copyright (c) 1993-2017 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -77,9 +77,12 @@ extern void unblock_sigchld (void); /* Some time between Red Hat 4.2 and 7.0, the words were transposed in the various PAM_x_CRED macro names. Yay! */ -#ifndef PAM_REFRESH_CRED +#if !defined(PAM_REFRESH_CRED) && defined(PAM_CRED_REFRESH) # define PAM_REFRESH_CRED PAM_CRED_REFRESH #endif +#if !defined(PAM_REINITIALIZE_CRED) && defined(PAM_CRED_REINITIALIZE) +# define PAM_REINITIALIZE_CRED PAM_CRED_REINITIALIZE +#endif static int pam_conversation (int nmsgs, const struct pam_message **msg, @@ -181,8 +184,10 @@ pam_try_unlock(saver_info *si, Bool verbose_p, pam_handle_t *pamh = 0; int status = -1; struct pam_conv pc; +# ifdef HAVE_SIGTIMEDWAIT sigset_t set; struct timespec timeout; +# endif /* HAVE_SIGTIMEDWAIT */ pc.conv = &pam_conversation; pc.appdata_ptr = (void *) si; @@ -240,9 +245,12 @@ pam_try_unlock(saver_info *si, Bool verbose_p, if (verbose_p) fprintf (stderr, "%s: pam_authenticate (...) ...\n", blurb()); +# ifdef HAVE_SIGTIMEDWAIT timeout.tv_sec = 0; timeout.tv_nsec = 1; - set = block_sigchld(); + set = +# endif /* HAVE_SIGTIMEDWAIT */ + block_sigchld(); status = pam_authenticate (pamh, 0); # ifdef HAVE_SIGTIMEDWAIT sigtimedwait (&set, NULL, &timeout); @@ -258,9 +266,22 @@ pam_try_unlock(saver_info *si, Bool verbose_p, { int status2; - /* We don't actually care if the account modules fail or succeed, - * but we need to run them anyway because certain pam modules - * depend on side effects of the account modules getting run. + /* On most systems, it doesn't matter whether the account modules + are run, or whether they fail or succeed. + + On some systems, the account modules fail, because they were + never configured properly, but it's necessary to run them anyway + because certain PAM modules depend on side effects of the account + modules having been run. + + And on still other systems, the account modules are actually + used, and failures in them should be considered to be true! + + So: + - We run the account modules on all systems. + - Whether we ignore them is a configure option. + + It's all kind of a mess. */ status2 = pam_acct_mgmt (pamh, 0); @@ -282,16 +303,28 @@ pam_try_unlock(saver_info *si, Bool verbose_p, blurb(), status2, PAM_STRERROR(pamh, status2)); } + /* If 'configure' requested that we believe the results of PAM + account module failures, then obey that status code. + Otherwise ignore it. + */ +#ifdef PAM_CHECK_ACCOUNT_TYPE + status = status2; +#endif + /* Each time we successfully authenticate, refresh credentials, for Kerberos/AFS/DCE/etc. If this fails, just ignore that failure and blunder along; it shouldn't matter. - - Note: this used to be PAM_REFRESH_CRED instead of - PAM_REINITIALIZE_CRED, but Jason Heiss - says that the Linux PAM library ignores that one, and only refreshes - credentials when using PAM_REINITIALIZE_CRED. */ + +#if defined(__linux__) + /* Apparently the Linux PAM library ignores PAM_REFRESH_CRED and only + refreshes credentials when using PAM_REINITIALIZE_CRED. */ status2 = pam_setcred (pamh, PAM_REINITIALIZE_CRED); +#else + /* But Solaris requires PAM_REFRESH_CRED or extra prompts appear. */ + status2 = pam_setcred (pamh, PAM_REFRESH_CRED); +#endif + if (verbose_p) fprintf (stderr, "%s: pam_setcred (...) ==> %d (%s)\n", blurb(), status2, PAM_STRERROR(pamh, status2)); @@ -452,6 +485,14 @@ pam_conversation (int nmsgs, ret = si->unlock_cb(nmsgs, messages, &authresp, si); + /* #### If the user times out, or hits ESC or Cancel, we return PAM_CONV_ERR, + and PAM logs this as an authentication failure. It would be nice if + there was some way to indicate that this was a "cancel" rather than + a "fail", so that it wouldn't show up in syslog, but I think the + only options are PAM_SUCCESS and PAM_CONV_ERR. (I think that + PAM_ABORT means "internal error", not "cancel".) Bleh. + */ + if (ret == 0) { for (i = 0; i < nmsgs; ++i)