Hi.
I can confirm that Samoied's patch works for our purpose. We
have various user accounts on a shell machine, and most
users don't care about OTP auth. To avoid confusion upon
mistyped passwords it's preferable to present non-OTP users
with another plain pam_unix password prompt, rather than the
obscure looking "otp-md5 123 wb3412 ext" prompt.
I've attached a slightly modified patch that calls
opieverify() before returning in all cases. According to the
comment above opiechallenge() in libopie this is required to
clean up locks etc, even if opiechallenge() returns failure.
The standard libpam-opie in Debian doesn't do this if the
PAM conversation returns failure.
Cheers,
Matt
--- libpam-opie-0.21/pam_opie.c.orig 2007-02-26 11:26:01.000000000 +0900
+++ libpam-opie-0.21/pam_opie.c 2007-02-26 11:11:21.000000000 +0900
@@ -86,6 +86,15 @@ int pam_sm_authenticate(pam_handle_t *pa
char *tok;
int knownuser;
int retval;
+ int no_fake_prompts;
+ int i;
+
+ no_fake_prompts = 0;
+ for (i=0; i<argc; ++i) {
+ if (!strcmp("no_fake_prompts", argv[i])) {
+ no_fake_prompts = 1;
+ }
+ }
retval = pam_get_user(pamh, &username, "login: ");
if (retval != PAM_SUCCESS)
@@ -99,6 +108,15 @@ int pam_sm_authenticate(pam_handle_t *pa
}
knownuser = (retval == 0) ? 1 : 0;
+ /* If user dont have a opiekey, and no_fake_prompts is set,
+ * return PAM_USER_UNKNOWN
+ */
+ if ((knownuser == 0) && (no_fake_prompts == 1)) {
+ /* Must always call opieverify() */
+ opieverify(&opie, "");
+ return PAM_USER_UNKNOWN;
+ }
+
/* Print challenge & get the response */
strncpy(&challenge[strlen(challenge)], ", Response:",sizeof(challenge) - strlen(challenge));
pmsg[0] = &msg[0];
@@ -106,8 +124,11 @@ int pam_sm_authenticate(pam_handle_t *pa
msg[0].msg = challenge;
resp = NULL;
retval = converse(pamh, 1, pmsg, &resp);
- if (retval != PAM_SUCCESS)
+ if (retval != PAM_SUCCESS) {
+ /* Must always call opieverify */
+ opieverify(&opie, "");
return retval;
+ }
tok = xstrdup(resp[0].resp);
if (resp != NULL) free(resp);
pam_set_item(pamh, PAM_AUTHTOK, tok);