- pam_retval = pam_set_item(__pamh, PAM_RHOST, rhost);
- if (pam_retval != PAM_SUCCESS)
- fatal("PAM set rhost failed[%d]: %.200s", pam_retval,
- PAM_STRERROR(__pamh, pam_retval));
-#ifdef PAM_TTY_KLUDGE
- /*
- * Some PAM modules (e.g. pam_time) require a TTY to operate,
- * and will fail in various stupid ways if they don't get one.
- * sshd doesn't set the tty until too late in the auth process and may
- * not even need one (for tty-less connections)
- * Kludge: Set a fake PAM_TTY
- */
- pam_retval = pam_set_item(__pamh, PAM_TTY, "NODEVssh");
- if (pam_retval != PAM_SUCCESS)
- fatal("PAM set tty failed[%d]: %.200s",
- pam_retval, PAM_STRERROR(__pamh, pam_retval));
-#endif /* PAM_TTY_KLUDGE */
+ if ((reply = calloc(n, sizeof(*reply))) == NULL)
+ return (PAM_CONV_ERR);
+
+ for (i = 0; i < n; ++i) {
+ switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
+ case PAM_PROMPT_ECHO_OFF:
+ reply[i].resp =
+ read_passphrase(PAM_MSG_MEMBER(msg, i, msg),
+ RP_ALLOW_STDIN);
+ reply[i].resp_retcode = PAM_SUCCESS;
+ break;
+ case PAM_PROMPT_ECHO_ON:
+ fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg));
+ fgets(input, sizeof input, stdin);
+ if ((reply[i].resp = strdup(input)) == NULL)
+ goto fail;
+ reply[i].resp_retcode = PAM_SUCCESS;
+ break;
+ case PAM_ERROR_MSG:
+ case PAM_TEXT_INFO:
+ fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg));
+ reply[i].resp_retcode = PAM_SUCCESS;
+ break;
+ default:
+ goto fail;
+ }
+ }
+ *resp = reply;
+ return (PAM_SUCCESS);
+
+ fail:
+ for(i = 0; i < n; i++) {
+ if (reply[i].resp != NULL)
+ xfree(reply[i].resp);
+ }
+ xfree(reply);
+ return (PAM_CONV_ERR);
+}
+
+static struct pam_conv tty_conv = { sshpam_tty_conv, NULL };
+
+/*
+ * XXX this should be done in the authentication phase, but ssh1 doesn't
+ * support that
+ */
+void
+do_pam_chauthtok(void)
+{
+ if (use_privsep)
+ fatal("Password expired (unable to change with privsep)");
+ sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
+ (const void *)&tty_conv);
+ if (sshpam_err != PAM_SUCCESS)
+ fatal("PAM: failed to set PAM_CONV: %s",
+ pam_strerror(sshpam_handle, sshpam_err));
+ debug("PAM: changing password");
+ sshpam_err = pam_chauthtok(sshpam_handle, PAM_CHANGE_EXPIRED_AUTHTOK);
+ if (sshpam_err != PAM_SUCCESS)
+ fatal("PAM: pam_chauthtok(): %s",
+ pam_strerror(sshpam_handle, sshpam_err));
+}
+
+void
+do_pam_session(void)
+{
+ debug3("PAM: opening session");
+ sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
+ (const void *)&store_conv);
+ if (sshpam_err != PAM_SUCCESS)
+ fatal("PAM: failed to set PAM_CONV: %s",
+ pam_strerror(sshpam_handle, sshpam_err));
+ sshpam_err = pam_open_session(sshpam_handle, 0);
+ if (sshpam_err == PAM_SUCCESS)
+ sshpam_session_open = 1;
+ else {
+ sshpam_session_open = 0;
+ disable_forwarding();
+ error("PAM: pam_open_session(): %s",
+ pam_strerror(sshpam_handle, sshpam_err));
+ }