#include "ssh.h"
#include "xmalloc.h"
#include "log.h"
+#include "auth.h"
#include "auth-pam.h"
#include "servconf.h"
#include "canohost.h"
#include "readpass.h"
+extern char *__progname;
+
RCSID("$Id$");
#define NEW_AUTHTOK_MSG \
* messages with into __pam_msg. This is used during initial
* authentication to bypass the normal PAM password prompt.
*
- * OTHER mode handles PAM_PROMPT_ECHO_OFF with read_passphrase(prompt, 1)
+ * OTHER mode handles PAM_PROMPT_ECHO_OFF with read_passphrase()
* and outputs messages to stderr. This mode is used if pam_chauthtok()
* is called to update expired passwords.
*/
reply[count].resp_retcode = PAM_SUCCESS;
break;
case PAM_PROMPT_ECHO_OFF:
- reply[count].resp = xstrdup(
- read_passphrase(PAM_MSG_MEMBER(msg, count,
- msg), 1));
+ reply[count].resp =
+ read_passphrase(PAM_MSG_MEMBER(msg, count,
+ msg), RP_ALLOW_STDIN);
reply[count].resp_retcode = PAM_SUCCESS;
break;
case PAM_ERROR_MSG:
/* Called at exit to cleanly shutdown PAM */
void do_pam_cleanup_proc(void *context)
{
- int pam_retval;
+ int pam_retval = PAM_SUCCESS;
if (__pamh && session_opened) {
pam_retval = pam_close_session(__pamh, 0);
}
/* Attempt password authentation using PAM */
-int auth_pam_password(struct passwd *pw, const char *password)
+int auth_pam_password(Authctxt *authctxt, const char *password)
{
extern ServerOptions options;
int pam_retval;
+ struct passwd *pw = authctxt->pw;
do_pam_set_conv(&conv);
/* deny if no user. */
if (pw == NULL)
return 0;
- if (pw->pw_uid == 0 && options.permit_root_login == 2)
+ if (pw->pw_uid == 0 && options.permit_root_login == PERMIT_NO_PASSWD)
return 0;
if (*password == '\0' && options.permit_empty_passwd == 0)
return 0;
__pampasswd = password;
pamstate = INITIAL_LOGIN;
- pam_retval = do_pam_authenticate(0);
+ pam_retval = do_pam_authenticate(
+ options.permit_empty_passwd == 0 ? PAM_DISALLOW_NULL_AUTHTOK : 0);
if (pam_retval == PAM_SUCCESS) {
debug("PAM Password authentication accepted for "
"user \"%.100s\"", pw->pw_name);
}
pam_retval = pam_acct_mgmt(__pamh, 0);
+ debug2("pam_acct_mgmt() = %d", pam_retval);
switch (pam_retval) {
case PAM_SUCCESS:
/* This is what we want */
break;
+#if 0
case PAM_NEW_AUTHTOK_REQD:
message_cat(&__pam_msg, NEW_AUTHTOK_MSG);
/* flag that password change is necessary */
password_change_required = 1;
break;
+#endif
default:
log("PAM rejected by account configuration[%d]: "
"%.200s", pam_retval, PAM_STRERROR(__pamh,
{
int pam_retval;
+ do_pam_set_conv(&conv);
+
if (ttyname != NULL) {
debug("PAM setting tty to \"%.200s\"", ttyname);
pam_retval = pam_set_item(__pamh, PAM_TTY, ttyname);
if (pam_retval != PAM_SUCCESS)
fatal("PAM session setup failed[%d]: %.200s",
pam_retval, PAM_STRERROR(__pamh, pam_retval));
+
session_opened = 1;
}
/* Set PAM credentials */
-void do_pam_setcred(void)
+void do_pam_setcred(int init)
{
int pam_retval;
+ do_pam_set_conv(&conv);
+
debug("PAM establishing creds");
- pam_retval = pam_setcred(__pamh, PAM_ESTABLISH_CRED);
+ pam_retval = pam_setcred(__pamh,
+ init ? PAM_ESTABLISH_CRED : PAM_REINITIALIZE_CRED);
if (pam_retval != PAM_SUCCESS) {
if (was_authenticated)
fatal("PAM setcred failed[%d]: %.200s",
{
int pam_retval;
+ do_pam_set_conv(&conv);
+
if (password_change_required) {
pamstate = OTHER;
- /* XXX: should we really loop forever? */
- do {
- pam_retval = pam_chauthtok(__pamh,
- PAM_CHANGE_EXPIRED_AUTHTOK);
- if (pam_retval != PAM_SUCCESS)
- log("PAM pam_chauthtok failed[%d]: %.200s",
- pam_retval, PAM_STRERROR(__pamh, pam_retval));
- } while (pam_retval != PAM_SUCCESS);
+ pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+ if (pam_retval != PAM_SUCCESS)
+ fatal("PAM pam_chauthtok failed[%d]: %.200s",
+ pam_retval, PAM_STRERROR(__pamh, pam_retval));
}
}
{
int pam_retval;
extern ServerOptions options;
+ extern u_int utmp_len;
+ const char *rhost;
debug("Starting up PAM with username \"%.200s\"", user);
fatal("PAM initialisation failed[%d]: %.200s",
pam_retval, PAM_STRERROR(__pamh, pam_retval));
- debug("PAM setting rhost to \"%.200s\"",
- get_canonical_hostname(options.reverse_mapping_check));
- pam_retval = pam_set_item(__pamh, PAM_RHOST,
- get_canonical_hostname(options.reverse_mapping_check));
+ rhost = get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping);
+ debug("PAM setting rhost to \"%.200s\"", rhost);
+
+ 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));
* not even need one (for tty-less connections)
* Kludge: Set a fake PAM_TTY
*/
- pam_retval = pam_set_item(__pamh, PAM_TTY, "ssh");
+ 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));