- Import of patch from Ben Taylor <bent@clark.net>:

- Improved PAM support
   - "uninstall" rule for Makefile
   - utmpx support
   - Should fix PAM problems on Solaris
This commit is contained in:
Damien Miller 1999-12-09 10:16:54 +11:00
parent fce1648681
commit bf1c9b2012
8 changed files with 157 additions and 51 deletions

View File

@ -1,3 +1,10 @@
19991209
- Import of patch from Ben Taylor <bent@clark.net>:
- Improved PAM support
- "uninstall" rule for Makefile
- utmpx support
- Should fix PAM problems on Solaris
19991208
- Compile fix for Solaris with /dev/ptmx from
David Agraz <dagraz@jahoopa.com>

View File

@ -103,6 +103,36 @@ install: all
$(INSTALL) -m644 sshd_config $(sysconfdir)/sshd_config; \
fi
uninstallall: uninstall
-rm -f $(sysconfdir)/ssh_config
-rm -f $(sysconfdir)/sshd_config
-rmdir $(sysconfdir)
-rmdir $(bindir)
-rmdir $(sbindir)
-rmdir $(mandir)/man1
-rmdir $(mandir)/man8
-rmdir $(mandir)
-rmdir $(libexecdir)
uninstall:
-rm -f $(bindir)/ssh
-rm -f $(bindir)/scp
-rm -f $(bindir)/ssh-add
-rm -f $(bindir)/ssh-agent
-rm -f $(bindir)/ssh-keygen
-rm -f $(sbindir)/sshd
-rm -f $(mandir)/man1/ssh.1
-rm -f $(mandir)/man1/scp.1
-rm -f $(mandir)/man1/ssh-add.1
-rm -f $(mandir)/man1/ssh-agent.1
-rm -f $(mandir)/man1/ssh-keygen.1
-rm -f $(mandir)/man8/sshd.8
-rm -f $(bindir)/slogin
-rm -f $(mandir)/man1/slogin.1
-rm -f $(mandir)/man1/slogin.1
-rm -f ${ASKPASS_PROGRAM}
-rmdir $(libexecdir)/ssh ;
distclean: clean
rm -f Makefile config.h core *~

View File

@ -24,6 +24,9 @@
/* Define is utmp.h has a ut_host field */
#undef HAVE_HOST_IN_UTMP
/* Define is utmpx.h has a ut_host field */
#undef HAVE_HOST_IN_UTMPX
/* Define is libutil has login() function */
#undef HAVE_LIBUTIL_LOGIN
@ -85,6 +88,10 @@
# include <utmp.h> /* For _PATH_XXX */
#endif
#ifdef HAVE_UTMPX_H
# include <utmpx.h> /* For _PATH_XXX */
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h> /* For timersub */
#endif
@ -96,13 +103,13 @@
#ifndef SHUT_RDWR
enum
{
SHUT_RD = 0, /* No more receptions. */
#define SHUT_RD SHUT_RD
SHUT_WR, /* No more transmissions. */
#define SHUT_WR SHUT_WR
SHUT_RDWR /* No more receptions or transmissions. */
#define SHUT_RDWR SHUT_RDWR
SHUT_RD = 0, /* No more receptions. */
SHUT_WR, /* No more transmissions. */
SHUT_RDWR /* No more receptions or transmissions. */
};
# define SHUT_RD SHUT_RD
# define SHUT_WR SHUT_WR
# define SHUT_RDWR SHUT_RDWR
#endif
/* If sys/types.h does not supply intXX_t, supply them ourselves */
@ -164,25 +171,44 @@ enum
# define quad_t int64_t
#endif
/* If _PATH_LASTLOG is not defined by system headers, set it to the */
/* lastlog file detected by autoconf */
#ifndef _PATH_LASTLOG
# ifdef LASTLOG_LOCATION
# define _PATH_LASTLOG LASTLOG_LOCATION
# endif
#endif
/* Use utmpx if supported */
#ifdef HAVE_UTMPX_H
# define UTMP_STR utmpx
#else
# ifdef HAVE_UTMP_H
# define UTMP_STR utmp
# endif
#endif
#ifndef _PATH_UTMP
# ifdef UTMP_FILE
# define _PATH_UTMP UTMP_FILE
# ifdef UTMPX_FILE
# define _PATH_UTMP UTMPX_FILE
# else
# define _PATH_UTMP "/var/adm/utmp"
# ifdef UTMP_FILE
# define _PATH_UTMP UTMP_FILE
# else
# define _PATH_UTMP "/var/adm/utmp"
# endif
# endif
#endif
#ifndef _PATH_WTMP
# ifdef WTMP_FILE
# define _PATH_WTMP WTMP_FILE
# ifdef WTMPX_FILE
# define _PATH_WTMP WTMPX_FILE
# else
# define _PATH_WTMP "/var/adm/wtmp"
# ifdef WTMP_FILE
# define _PATH_WTMP WTMP_FILE
# else
# define _PATH_WTMP "/var/adm/wtmp"
# endif
# endif
#endif
@ -219,9 +245,9 @@ enum
(result)->tv_usec += 1000000; \
} \
} while (0)
#endif
/* In older versions of libpam, pam_strerror takes a single argument */
#ifdef HAVE_OLD_PAM
# define PAM_STRERROR(a,b) pam_strerror((b))
#else
@ -231,3 +257,4 @@ enum
#ifndef __P
# define __P(x) x
#endif

View File

@ -45,47 +45,59 @@ static char *rcsid = "$OpenBSD: login.c,v 1.5 1998/07/13 02:11:12 millert Exp $"
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <utmp.h>
#ifdef HAVE_UTMPX_H
# include <utmpx.h>
#endif
#ifdef HAVE_UTMP_H
# include <utmp.h>
#endif
#include <stdio.h>
void
login(utp)
struct utmp *utp;
struct UTMP_STR *utp;
{
struct utmp old_ut;
struct UTMP_STR old_ut;
register int fd;
int tty;
#ifndef UT_LINESIZE
# define UT_LINESIZE (sizeof(old_ut.ut_line))
# define UT_NAMESIZE (sizeof(old_ut.ut_name))
# ifdef HAVE_UTMPX_H
# define UT_NAMESIZE (sizeof(old_ut.ut_user))
# else
# define UT_NAMESIZE (sizeof(old_ut.ut_name))
# endif
# ifdef HAVE_HOST_IN_UTMP
# define UT_HOSTSIZE (sizeof(old_ut.ut_host))
# endif
# ifdef HAVE_HOST_IN_UTMPX
# define UT_HOSTSIZE (sizeof(old_ut.ut_host))
# endif
#endif
tty = ttyslot();
if (tty > 0 && (fd = open(_PATH_UTMP, O_RDWR|O_CREAT, 0644)) >= 0) {
#ifdef HAVE_HOST_IN_UTMP
(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
#ifdef HAVE_HOST_IN_UTMP || HAVE_HOST_IN_UTMPX
(void)lseek(fd, (off_t)(tty * sizeof(struct UTMP_STR)), SEEK_SET);
/*
* Prevent luser from zero'ing out ut_host.
* If the new ut_line is empty but the old one is not
* and ut_line and ut_name match, preserve the old ut_line.
*/
if (read(fd, &old_ut, sizeof(struct utmp)) ==
sizeof(struct utmp) && utp->ut_host[0] == '\0' &&
if (read(fd, &old_ut, sizeof(struct UTMP_STR)) ==
sizeof(struct UTMP_STR) && utp->ut_host[0] == '\0' &&
old_ut.ut_host[0] != '\0' &&
strncmp(old_ut.ut_line, utp->ut_line, UT_LINESIZE) == 0 &&
strncmp(old_ut.ut_name, utp->ut_name, UT_NAMESIZE) == 0)
(void)memcpy(utp->ut_host, old_ut.ut_host, UT_HOSTSIZE);
#endif /* HAVE_HOST_IN_UTMP */
(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
(void)write(fd, utp, sizeof(struct utmp));
#endif /* HAVE_HOST_IN_UTMP || HAVE_HOST_IN_UTMPX */
(void)lseek(fd, (off_t)(tty * sizeof(struct UTMP_STR)), SEEK_SET);
(void)write(fd, utp, sizeof(struct UTMP_STR));
(void)close(fd);
}
if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
(void)write(fd, utp, sizeof(struct utmp));
(void)write(fd, utp, sizeof(struct UTMP_STR));
(void)close(fd);
}
}

View File

@ -56,7 +56,7 @@ AC_CHECK_LIB(dl, dlopen, , )
AC_CHECK_LIB(pam, pam_authenticate, , )
dnl Checks for header files.
AC_CHECK_HEADERS(endian.h lastlog.h login.h maillock.h netgroup.h paths.h pty.h shadow.h util.h utmp.h sys/select.h sys/stropts.h sys/time.h)
AC_CHECK_HEADERS(endian.h lastlog.h login.h maillock.h netgroup.h paths.h pty.h shadow.h util.h utmp.h utmpx.h sys/select.h sys/stropts.h sys/time.h)
dnl Checks for library functions.
AC_CHECK_FUNCS(arc4random mkdtemp openpty _getpty setenv setlogin setproctitle snprintf strlcat strlcpy vsnprintf)
@ -198,6 +198,13 @@ AC_EGREP_HEADER(ut_host, utmp.h,
[AC_MSG_RESULT(no)]
)
dnl Check for ut_host field in utmpx
AC_MSG_CHECKING([whether utmpx.h has ut_host field])
AC_EGREP_HEADER(ut_host, utmpx.h,
[AC_DEFINE(HAVE_HOST_IN_UTMPX) AC_MSG_RESULT(yes); ],
[AC_MSG_RESULT(no)]
)
dnl Look for lastlog location
AC_MSG_CHECKING([location of lastlog file])
for lastlog in /var/log/lastlog /var/adm/lastlog /etc/security/lastlog ; do

18
login.c
View File

@ -18,9 +18,14 @@
*/
#include "includes.h"
RCSID("$Id: login.c,v 1.5 1999/11/25 02:08:31 damien Exp $");
RCSID("$Id: login.c,v 1.6 1999/12/08 23:16:55 damien Exp $");
#include <utmp.h>
#ifdef HAVE_UTMPX_H
# include <utmpx.h>
#endif
#ifdef HAVE_UTMP_H
# include <utmp.h>
#endif
#include "ssh.h"
#ifdef HAVE_UTIL_H
@ -83,15 +88,20 @@ record_login(int pid, const char *ttyname, const char *user, uid_t uid,
int fd;
struct lastlog ll;
char *lastlog;
struct utmp u;
struct UTMP_STR u;
const char *utmp, *wtmp;
/* Construct an utmp/wtmp entry. */
memset(&u, 0, sizeof(u));
strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line));
#ifdef HAVE_UTMPX_H
u.ut_tv.tv_sec = time(NULL);
strncpy(u.ut_user, user, sizeof(u.ut_name));
#else
u.ut_time = time(NULL);
strncpy(u.ut_name, user, sizeof(u.ut_name));
#ifdef HAVE_HOST_IN_UTMP
#endif
#if defined(HAVE_HOST_IN_UTMP) || defined(HAVE_HOST_IN_UTMPX)
strncpy(u.ut_host, host, sizeof(u.ut_host));
#endif

6
pty.c
View File

@ -14,11 +14,15 @@
*/
#include "includes.h"
RCSID("$Id: pty.c,v 1.7 1999/12/07 21:53:52 damien Exp $");
RCSID("$Id: pty.c,v 1.8 1999/12/08 23:16:55 damien Exp $");
#include "pty.h"
#include "ssh.h"
#ifdef HAVE_DEV_PTMX
#include <sys/stropts.h>
#endif /* HAVE_DEV_PTMX */
/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */
#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY)
#undef HAVE_DEV_PTMX

49
sshd.c
View File

@ -11,7 +11,7 @@
*/
#include "includes.h"
RCSID("$Id: sshd.c,v 1.35 1999/12/07 04:38:32 damien Exp $");
RCSID("$Id: sshd.c,v 1.36 1999/12/08 23:16:55 damien Exp $");
#include "xmalloc.h"
#include "rsa.h"
@ -138,7 +138,8 @@ void do_child(const char *command, struct passwd * pw, const char *term,
#ifdef HAVE_LIBPAM
static int pamconv(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr);
void do_pam_account_and_session(char *username, char *remote_user);
void do_pam_account(char *username, char *remote_user);
void do_pam_session(char *username, char *ttyname);
void pam_cleanup_proc(void *context);
static struct pam_conv conv = {
@ -228,7 +229,7 @@ void pam_cleanup_proc(void *context)
}
}
void do_pam_account_and_session(char *username, char *remote_user)
void do_pam_account(char *username, char *remote_user)
{
int pam_retval;
@ -254,12 +255,22 @@ void do_pam_account_and_session(char *username, char *remote_user)
log("PAM rejected by account configuration: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
do_fake_authloop(username);
}
}
void do_pam_session(char *username, char *ttyname)
{
int pam_retval;
if (ttyname != NULL) {
debug("PAM setting tty to \"%.200s\"", ttyname);
pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, ttyname);
if (pam_retval != PAM_SUCCESS)
fatal("PAM set tty failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
pam_retval = pam_open_session((pam_handle_t *)pamh, 0);
if (pam_retval != PAM_SUCCESS) {
log("PAM session setup failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
do_fake_authloop(username);
}
if (pam_retval != PAM_SUCCESS)
fatal("PAM session setup failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
#endif /* HAVE_LIBPAM */
@ -1476,12 +1487,16 @@ do_authloop(struct passwd * pw)
pam_retval = pam_authenticate((pam_handle_t *)pamh, 0);
if (pam_retval == PAM_SUCCESS) {
log("PAM Password authentication accepted for user \"%.100s\"", pw->pw_name);
memset(password, 0, strlen(password));
xfree(password);
authenticated = 1;
break;
}
log("PAM Password authentication for \"%.100s\" failed: %s",
pw->pw_name, PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
memset(password, 0, strlen(password));
xfree(password);
break;
#else /* HAVE_LIBPAM */
/* Try authentication with the password. */
@ -1561,30 +1576,18 @@ do_authloop(struct passwd * pw)
packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
#else /* HAVE_LIBPAM */
if (authenticated) {
do_pam_account_and_session(pw->pw_name, client_user);
do_pam_account(pw->pw_name, client_user);
/* Clean up */
if (client_user != NULL)
xfree(client_user);
if (password != NULL) {
memset(password, 0, strlen(password));
xfree(password);
}
return;
}
if (attempt > AUTH_FAIL_MAX) {
/* Clean up */
if (client_user != NULL)
xfree(client_user);
if (password != NULL) {
memset(password, 0, strlen(password));
xfree(password);
}
packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
}
#endif /* HAVE_LIBPAM */
@ -1785,6 +1788,12 @@ do_authenticated(struct passwd * pw)
/* Indicate that we now have a pty. */
have_pty = 1;
#ifdef HAVE_LIBPAM
/* do the pam_open_session since we have the pty */
do_pam_session(pw->pw_name,ttyname);
#endif /* HAVE_LIBPAM */
break;
case SSH_CMSG_X11_REQUEST_FORWARDING: