The pam_otpw.so session module version 1.3-2 in Wheezy does not print out the number of passwords reminder as expected. I think this is because the function pam_sm_open_session trying to get the challenge data from the handle provided, but that handle does not contain the challenge (which had been setup during the authentication phase) because we are now running in a different process than the one where the authentication happened. So the challenge data is NULL and the module aborts.
The attached patch for pam_otpw.c (v1.3-2) fixes this and issues correct password reminders on my Wheezy system.
--- otpw-1.3-2.orig/pam_otpw.c 2003-10-06 07:47:33.000000000 -0700 +++ otpw-1.3-2/pam_otpw.c 2012-06-24 14:36:01.000000000 -0700 @@ -328,24 +328,56 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { + const char *username; + struct passwd *pwd; struct challenge *ch = NULL; int retval; int i, debug = 0; + int otpw_flags = 0; /* parse option flags */ for (i = 0; i < argc; i++) { - if (!strcmp(argv[i], "debug")) + if (!strcmp(argv[i], "debug")) { debug = 1; + otpw_flags |= OTPW_DEBUG; + } } D(log_message(LOG_DEBUG, pamh, "pam_sm_open_session called, flags=%d", flags)); - retval = pam_get_data(pamh, MODULE_NAME":ch", (const void **) &ch); - if (retval != PAM_SUCCESS || !ch) { - log_message(LOG_ERR, pamh, "pam_get_data() failed"); - return PAM_SESSION_ERR; + /* get user name */ + retval = pam_get_user(pamh, &username, "login: "); + if (retval == PAM_CONV_AGAIN) + return PAM_INCOMPLETE; + else if (retval != PAM_SUCCESS) { + log_message(LOG_NOTICE, pamh, "no username provided"); + return PAM_USER_UNKNOWN; } + + /* DEBUG */ + D(log_message(LOG_DEBUG, pamh, "username is %s", username)); + D(log_message(LOG_DEBUG, pamh, "uid=%d, euid=%d, gid=%d, egid=%d", + getuid(), geteuid(), getgid(), getegid())); + + ch = calloc(1, sizeof(struct challenge)); + if (!ch) + return PAM_AUTHINFO_UNAVAIL; + retval = pam_set_data(pamh, MODULE_NAME":ch", ch, cleanup); + if (retval != PAM_SUCCESS) { + log_message(LOG_ERR, pamh, "pam_set_data() failed"); + return PAM_AUTHINFO_UNAVAIL; + } + + /* consult POSIX password database (to find homedir, etc.) */ + pwd = getpwnam(username); + if (!pwd) { + log_message(LOG_NOTICE, pamh, "username not found"); + return PAM_USER_UNKNOWN; + } + + /* prepare OTPW challenge */ + otpw_prepare(ch, pwd, otpw_flags); if (!(flags & PAM_SILENT) && ch->entries >= 0) { display_notice(pamh, 0, debug,