--- ssh-1.2.22/acconfig.h.pam Tue Jan 20 13:23:46 1998 +++ ssh-1.2.22/acconfig.h Wed Jan 21 13:22:00 1998 @@ -368,3 +368,6 @@ /* Define this if your spwd struct defined shadow.h have sp_inact field */ #undef HAVE_STRUCT_SPWD_INACT + +/* Define this if you use PAM */ +#undef HAVE_PAM --- ssh-1.2.22/auth-passwd.c.pam Tue Jan 20 13:23:48 1998 +++ ssh-1.2.22/auth-passwd.c Wed Jan 21 14:03:01 1998 @@ -21,6 +21,9 @@ * Fixed kerberos ticket name handling. Added OSF C2 account * locking and expiration support. * + * Revision 1.11a 1997/06/06 06:40:00 jonchen + * Added support for PAM + * * Revision 1.11 1997/04/17 03:57:05 kivinen * Kept FILE: prefix in kerberos ticket filename as DCE cache * code requires it (patch from Doug Engert ). @@ -112,6 +115,13 @@ #include #include #endif /* HAVE_ULTRIX_SHADOW_PASSWORDS */ +#ifdef HAVE_PAM +#include +extern pam_handle_t *pamh; +extern int retval; +extern char* pampasswd; +extern int origretval; +#endif /* HAVE_PAM */ #include "packet.h" #include "ssh.h" #include "servconf.h" @@ -672,6 +682,17 @@ seteuid(UID_ROOT); /* just let it fail if ran by user */ #endif /* SECURE_RPC */ +#ifdef HAVE_PAM + { + retval = origretval; + pampasswd = xstrdup(password); + if (retval == PAM_SUCCESS) + retval = pam_authenticate ((pam_handle_t *)pamh, 0); + if (retval == PAM_SUCCESS) + retval = pam_acct_mgmt ((pam_handle_t *)pamh, 0); + xfree(pampasswd); + } +#else /* HAVE_PAM */ #ifdef HAVE_OSF1_C2_SECURITY switch (osf1c2_getprpwent(correct_passwd, saved_pw_name, sizeof(correct_passwd))) @@ -764,6 +785,7 @@ #endif /* HAVE_ETC_SHADOW */ #endif /* HAVE_SCO_ETC_SHADOW */ #endif /* HAVE_OSF1_C2_SECURITY */ +#endif /* HAVE_PAM */ /* Check for users with no password. */ if (strcmp(password, "") == 0 && strcmp(correct_passwd, "") == 0) @@ -783,6 +805,14 @@ xfree(saved_pw_name); xfree(saved_pw_passwd); + +#ifdef HAVE_PAM + { + if (retval == PAM_SUCCESS) + retval = pam_open_session ((pam_handle_t *)pamh, 0); + return (retval == PAM_SUCCESS); + } +#endif /* HAVE_PAM */ #ifdef HAVE_ULTRIX_SHADOW_PASSWORDS { --- ssh-1.2.22/config.h.in.pam Tue Jan 20 13:24:14 1998 +++ ssh-1.2.22/config.h.in Wed Jan 21 13:22:01 1998 @@ -415,6 +415,9 @@ /* Define this if your spwd struct defined shadow.h have sp_inact field */ #undef HAVE_STRUCT_SPWD_INACT +/* Define this if you use PAM */ +#undef HAVE_PAM + /* The number of bytes in a int. */ #undef SIZEOF_INT --- ssh-1.2.22/configure.in.pam Tue Jan 20 13:24:14 1998 +++ ssh-1.2.22/configure.in Wed Jan 21 13:22:05 1998 @@ -27,6 +27,9 @@ # Fixed AC_MSG_RESULT messages when disabling idea in commercial # version. # +# Revision 1.46a 1997/06/06 18:40:00 jonchen +# Added support for PAM +# # Revision 1.46 1997/04/22 23:59:59 kivinen # Fixed SIGINFO check. # Added check that getpseudotty function exists before using. @@ -679,6 +682,11 @@ AC_CHECK_SIZEOF(long,4) AC_CHECK_SIZEOF(int,4) AC_CHECK_SIZEOF(short,2) + +if test -f /usr/include/security/pam_appl.h; then + AC_DEFINE(HAVE_PAM) + LIBS="$LIBS -lpam -ldl" +fi if test -z "$no_termios"; then AC_CHECK_HEADERS(termios.h) --- ssh-1.2.22/sshd.c.pam Tue Jan 20 13:24:10 1998 +++ ssh-1.2.22/sshd.c Wed Jan 21 13:22:05 1998 @@ -43,6 +43,9 @@ * feature. Added {Allow,Deny}Users feature from Steve Kann * . * + * Revision 1.42a 1997/06/06 18:40:00 jonchen + * Added support for PAM + * * Revision 1.42 1997/04/23 00:05:35 kivinen * Added ifdefs around password expiration and inactivity checks, * because some systems dont have sp_expire and sp_inact fields. @@ -460,6 +463,14 @@ char *ticket = "none\0"; #endif /* KERBEROS */ +#ifdef HAVE_PAM +#include +struct pam_handle_t *pamh=NULL; +char *pampasswd=NULL; +int retval; +int origretval; +#endif /* HAVE_PAM */ + /* Server configuration options. */ ServerOptions options; @@ -547,7 +558,56 @@ void do_child(const char *command, struct passwd *pw, const char *term, const char *display, const char *auth_proto, const char *auth_data, const char *ttyname); +#ifdef HAVE_PAM +static int pamconv (int num_msg, + const struct pam_message **msg, + struct pam_response **resp, + void *appdata_ptr) { + int count = 0, replies = 0; + struct pam_response *reply = NULL; + int size = sizeof(struct pam_response); + + for (count = 0; count < num_msg; count++) { + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_ON: + case PAM_PROMPT_ECHO_OFF: + if (reply) + realloc(reply, size); + else + reply = malloc(size); + if (!reply) return PAM_CONV_ERR; + size += sizeof(struct pam_response); + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies++].resp = xstrdup (pampasswd); + /* PAM frees resp */ + break; + case PAM_TEXT_INFO: + /* ignore it... */ + break; + case PAM_ERROR_MSG: + default: + /* Must be an error of some sort... */ + free (reply); + return PAM_CONV_ERR; + } + } + if (reply) *resp = reply; + return PAM_SUCCESS; +} + +static struct pam_conv conv = { + pamconv, + NULL +}; + +void pam_cleanup_proc (void *context) { + if (retval == PAM_SUCCESS) + retval = pam_close_session ((pam_handle_t *)pamh, 0); + if (pam_end ((pam_handle_t *)pamh, retval) != PAM_SUCCESS) + log_msg ("Cannot release PAM authentication."); +} +#endif /* HAVE_PAM */ /* Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP; the effect is to reread the configuration file (and to regenerate @@ -1254,6 +1314,13 @@ /* The connection has been terminated. */ log_msg("Closing connection to %.100s", get_remote_ipaddr()); +#ifdef HAVE_PAM + if (retval == PAM_SUCCESS) + retval = pam_close_session ((pam_handle_t *)pamh, 0); + if (pam_end ((pam_handle_t *)pamh, retval) != PAM_SUCCESS) + log_msg ("Cannot release PAM authentication."); + fatal_remove_cleanup (&pam_cleanup_proc, NULL); +#endif /* HAVE_PAM */ packet_close(); exit(0); } @@ -1810,7 +1877,13 @@ with any characters that are commonly used to start NIS entries. */ pw = getpwnam(user); if (!pw || user[0] == '-' || user[0] == '+' || user[0] == '@' || - !login_permitted(user, pw)) + !login_permitted(user, pw) +#ifdef HAVE_PAM + || ((retval=pam_start("ssh", pw->pw_name, &conv, (pam_handle_t **)&pamh)), + (fatal_add_cleanup (&pam_cleanup_proc, NULL)), + (origretval = retval), (retval != PAM_SUCCESS)) +#endif /* HAVE_PAM */ + ) do_authentication_fail_loop(); /* Take a copy of the returned structure. */ @@ -1841,6 +1914,7 @@ packet_disconnect("Cannot change user when server not running as root."); debug("Attempting authentication for %.100s.", user); + #if defined (KERBEROS) && defined (KRB5) if (!options.kerberos_authentication && options.password_authentication && .