From 3f9a326a7ac5d4559f7063a39418900c9c892fc2 Mon Sep 17 00:00:00 2001 From: "Andrey A. Chernov" <ache@FreeBSD.org> Date: Sat, 19 Jan 2002 02:38:43 +0000 Subject: [PATCH] Implement 'pwok', i.e. conditional fallback to unix password as supposed by opieaccessfile() and opiealways() --- lib/libpam/modules/pam_opie/pam_opie.c | 32 ++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/lib/libpam/modules/pam_opie/pam_opie.c b/lib/libpam/modules/pam_opie/pam_opie.c index 52dd07fc26e6..24c2613b31d5 100644 --- a/lib/libpam/modules/pam_opie/pam_opie.c +++ b/lib/libpam/modules/pam_opie/pam_opie.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include <pwd.h> #include <stdio.h> #include <string.h> +#include <time.h> #include <unistd.h> #define PAM_SM_AUTH @@ -66,13 +67,13 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) struct opie opie; struct options options; struct passwd *pwd; - int retval, i; + int retval, i, pwok; char *(promptstr[]) = { "%s\nPassword: ", "%s\nPassword [echo on]: "}; char challenge[OPIE_CHALLENGE_MAX]; char prompt[OPIE_CHALLENGE_MAX+22]; char resp[OPIE_SECRET_MAX]; - const char *user; - const char *response; + const char *user, *response, *rhost; + char *encrypted; pam_std_option(&options, other_options, argc, argv); @@ -96,6 +97,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) retval = pam_get_user(pamh, (const char **)&user, NULL); if (retval != PAM_SUCCESS) PAM_RETURN(retval); + pwd = getpwnam(user); } PAM_LOG("Got user: %s", user); @@ -106,7 +108,15 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) */ opiedisableaeh(); - opiechallenge(&opie, (char *)user, challenge); + pwok = 0; + if (opiechallenge(&opie, (char *)user, challenge) == 0) { + rhost = NULL; + (void) pam_get_item(pamh, PAM_RHOST, (const void **)&rhost); + pwok = (pwd != NULL) && + (rhost != NULL) && (*rhost != '\0') && + opieaccessfile((char *)rhost) && + opiealways(pwd->pw_dir); + } for (i = 0; i < 2; i++) { snprintf(prompt, sizeof prompt, promptstr[i], challenge); retval = pam_get_pass(pamh, &response, prompt, &options); @@ -133,7 +143,19 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) * it expects. Thus we can't log an error and can only check for * success or lack thereof. */ - retval = opieverify(&opie, resp) == 0 ? PAM_SUCCESS : PAM_AUTH_ERR; + if (opieverify(&opie, resp) == 0) + retval = PAM_SUCCESS; + else if (pwok) { + encrypted = crypt(resp, pwd->pw_passwd); + if (resp[0] == '\0' && pwd->pw_passwd[0] != '\0') + encrypted = ":"; + if (strcmp(encrypted, pwd->pw_passwd) != 0 || + (pwd->pw_expire && time(NULL) >= pwd->pw_expire)) + retval = PAM_AUTH_ERR; + else + retval = PAM_SUCCESS; + } else + retval = PAM_AUTH_ERR; PAM_RETURN(retval); }