- (dtucker) [README.platform auth.c configure.ac loginrec.c

openbsd-compat/port-aix.c openbsd-compat/port-aix.h] Bug #835: enable IPv6
   on AIX where possible (see README.platform for details) and work around
   a misfeature of AIX's getnameinfo.  ok djm@
This commit is contained in:
Darren Tucker 2005-02-15 21:45:57 +11:00
parent f04c361675
commit 691d5235ca
7 changed files with 136 additions and 18 deletions

View File

@ -1,5 +1,9 @@
20050215
- (dtucker) [config.sh.in] Collect oslevel -r too.
- (dtucker) [README.platform auth.c configure.ac loginrec.c
openbsd-compat/port-aix.c openbsd-compat/port-aix.h] Bug #835: enable IPv6
on AIX where possible (see README.platform for details) and work around
a misfeature of AIX's getnameinfo. ok djm@
20050211
- (dtucker) [configure.ac] Tidy up configure --help output.
@ -2126,4 +2130,4 @@
- (djm) Trim deprecated options from INSTALL. Mention UsePAM
- (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
$Id: ChangeLog,v 1.3651 2005/02/15 10:26:32 dtucker Exp $
$Id: ChangeLog,v 1.3652 2005/02/15 10:45:57 dtucker Exp $

View File

@ -13,6 +13,15 @@ Accounts in this state must have their passwords reset manually by the
administrator. As a precaution, it is recommended that the administrative
passwords be reset before upgrading from OpenSSH <3.8.
As of OpenSSH 4.0, configure will attempt to detect if your version
and maintenance level of AIX has a working getaddrinfo, and will use it
if found. This will enable IPv6 support. If for some reason configure
gets it wrong, or if you want to build binaries to work on earlier MLs
than the build host then you can add "-DBROKEN_GETADDRINFO" to CFLAGS
to force the previous IPv4-only behaviour.
IPv6 known to work: 5.2ML2 5.2ML5
IPv6 known broken: 4.3.3ML11 5.1ML4
Cygwin
------
@ -27,4 +36,4 @@ Currently, sshd does not support BSM auditting. This can show up as errors
when editting cron entries via crontab. See.
http://bugzilla.mindrot.org/show_bug.cgi?id=125
$Id: README.platform,v 1.2 2004/04/23 08:57:13 dtucker Exp $
$Id: README.platform,v 1.3 2005/02/15 10:45:57 dtucker Exp $

2
auth.c
View File

@ -209,7 +209,7 @@ allowed_user(struct passwd * pw)
}
#ifdef CUSTOM_SYS_AUTH_ALLOWED_USER
if (!sys_auth_allowed_user(pw))
if (!sys_auth_allowed_user(pw, &loginmsg))
return 0;
#endif

View File

@ -1,4 +1,4 @@
# $Id: configure.ac,v 1.241 2005/02/11 05:11:49 dtucker Exp $
# $Id: configure.ac,v 1.242 2005/02/15 10:45:57 dtucker Exp $
#
# Copyright (c) 1999-2004 Damien Miller
#
@ -135,7 +135,7 @@ case "$host" in
[#include <usersec.h>]
)
AC_CHECK_FUNCS(setauthdb)
AC_DEFINE(BROKEN_GETADDRINFO)
check_for_aix_broken_getaddrinfo=1
AC_DEFINE(BROKEN_REALPATH)
AC_DEFINE(SETEUID_BREAKS_SETUID)
AC_DEFINE(BROKEN_SETREUID)
@ -1146,6 +1146,64 @@ main(void)
)
fi
if test "x$ac_cv_func_getaddrinfo" = "xyes" -a "x$check_for_aix_broken_getaddrinfo" = "x1"; then
AC_MSG_CHECKING(if getaddrinfo seems to work)
AC_TRY_RUN(
[
#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <netinet/in.h>
#define TEST_PORT "2222"
int
main(void)
{
int err, sock;
struct addrinfo *gai_ai, *ai, hints;
char ntop[NI_MAXHOST], strport[NI_MAXSERV], *name = NULL;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
err = getaddrinfo(name, TEST_PORT, &hints, &gai_ai);
if (err != 0) {
fprintf(stderr, "getaddrinfo failed (%s)", gai_strerror(err));
exit(1);
}
for (ai = gai_ai; ai != NULL; ai = ai->ai_next) {
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
continue;
err = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop,
sizeof(ntop), strport, sizeof(strport),
NI_NUMERICHOST|NI_NUMERICSERV);
if (ai->ai_family == AF_INET && err != 0) {
perror("getnameinfo");
exit(2);
}
}
exit(0);
}
],
[
AC_MSG_RESULT(yes)
AC_DEFINE(AIX_GETNAMEINFO_HACK, [],
[Define if you have a getaddrinfo that fails for the all-zeros IPv6 address])
],
[
AC_MSG_RESULT(no)
AC_DEFINE(BROKEN_GETADDRINFO)
]
)
fi
if test "x$check_for_conflicting_getspnam" = "x1"; then
AC_MSG_CHECKING(for conflicting getspnam in shadow.h)
AC_COMPILE_IFELSE(

View File

@ -164,7 +164,7 @@
# include <libutil.h>
#endif
RCSID("$Id: loginrec.c,v 1.65 2005/02/08 10:52:48 dtucker Exp $");
RCSID("$Id: loginrec.c,v 1.66 2005/02/15 10:45:57 dtucker Exp $");
/**
** prototypes for helper functions in this file
@ -192,6 +192,8 @@ int lastlog_get_entry(struct logininfo *li);
int wtmp_get_entry(struct logininfo *li);
int wtmpx_get_entry(struct logininfo *li);
extern Buffer loginmsg;
/* pick the shortest string */
#define MIN_SIZEOF(s1,s2) (sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2))
@ -441,7 +443,7 @@ login_write(struct logininfo *li)
#endif
#ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN
if (li->type == LTYPE_LOGIN &&
!sys_auth_record_login(li->username,li->hostname,li->line))
!sys_auth_record_login(li->username,li->hostname,li->line, &loginmsg))
logit("Writing login record failed for %s", li->username);
#endif
#ifdef SSH_AUDIT_EVENTS

View File

@ -34,14 +34,13 @@
#ifdef _AIX
#include <uinfo.h>
#include <sys/socket.h>
#include "port-aix.h"
/* These should be in the system headers but are not. */
int usrinfo(int, char *, int);
int setauthdb(const char *, char *);
extern Buffer loginmsg;
# ifdef HAVE_SETAUTHDB
static char old_registry[REGISTRY_SIZE] = "";
# endif
@ -156,7 +155,7 @@ aix_valid_authentications(const char *user)
* returns 0.
*/
int
sys_auth_passwd(Authctxt *ctxt, const char *password)
sys_auth_passwd(Authctxt *ctxt, const char *password, Buffer *loginmsg)
{
char *authmsg = NULL, *msg, *name = ctxt->pw->pw_name;
int authsuccess = 0, expired, reenter, result;
@ -186,7 +185,7 @@ sys_auth_passwd(Authctxt *ctxt, const char *password)
*/
expired = passwdexpired(name, &msg);
if (msg && *msg) {
buffer_append(&loginmsg, msg, strlen(msg));
buffer_append(loginmsg, msg, strlen(msg));
aix_remove_embedded_newlines(msg);
}
debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg);
@ -219,7 +218,7 @@ sys_auth_passwd(Authctxt *ctxt, const char *password)
* Returns 1 if login is allowed, 0 if not allowed.
*/
int
sys_auth_allowed_user(struct passwd *pw)
sys_auth_allowed_user(struct passwd *pw, Buffer *loginmsg)
{
char *msg = NULL;
int result, permitted = 0;
@ -246,7 +245,7 @@ sys_auth_allowed_user(struct passwd *pw)
if (result == -1 && errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0)
permitted = 1;
else if (msg != NULL)
buffer_append(&loginmsg, msg, strlen(msg));
buffer_append(loginmsg, msg, strlen(msg));
if (msg == NULL)
msg = xstrdup("(none)");
aix_remove_embedded_newlines(msg);
@ -259,7 +258,8 @@ sys_auth_allowed_user(struct passwd *pw)
}
int
sys_auth_record_login(const char *user, const char *host, const char *ttynm)
sys_auth_record_login(const char *user, const char *host, const char *ttynm,
Buffer *loginmsg)
{
char *msg;
int success = 0;
@ -269,7 +269,7 @@ sys_auth_record_login(const char *user, const char *host, const char *ttynm)
success = 1;
if (msg != NULL) {
debug("AIX/loginsuccess: msg %s", msg);
buffer_append(&loginmsg, msg, strlen(msg));
buffer_append(loginmsg, msg, strlen(msg));
xfree(msg);
}
}
@ -349,4 +349,33 @@ aix_restoreauthdb(void)
# endif /* WITH_AIXAUTHENTICATE */
# if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_ADDRINFO)
# undef getnameinfo
/*
* For some reason, AIX's getnameinfo will refuse to resolve the all-zeros
* IPv6 address into its textual representation ("::"), so we wrap it
* with a function that will.
*/
int
sshaix_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
size_t hostlen, char *serv, size_t servlen, int flags)
{
struct sockaddr_in6 *sa6;
u_int32_t *a6;
if (flags & (NI_NUMERICHOST|NI_NUMERICSERV) &&
sa->sa_family == AF_INET6) {
sa6 = (struct sockaddr_in6 *)sa;
a6 = sa6->sin6_addr.u6_addr.u6_addr32;
if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) {
strlcpy(host, "::", hostlen);
snprintf(serv, servlen, "%d", sa6->sin6_port);
return 0;
}
}
return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
}
# endif /* AIX_GETNAMEINFO_HACK */
#endif /* _AIX */

View File

@ -1,4 +1,4 @@
/* $Id: port-aix.h,v 1.22 2005/02/02 06:10:11 dtucker Exp $ */
/* $Id: port-aix.h,v 1.23 2005/02/15 10:45:58 dtucker Exp $ */
/*
*
@ -27,6 +27,10 @@
#ifdef _AIX
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef WITH_AIXAUTHENTICATE
# include <login.h>
# include <userpw.h>
@ -36,6 +40,8 @@
# include <usersec.h>
#endif
#include "buffer.h"
/* Some versions define r_type in the above headers, which causes a conflict */
#ifdef r_type
# undef r_type
@ -64,13 +70,23 @@ void aix_usrinfo(struct passwd *);
#ifdef WITH_AIXAUTHENTICATE
# define CUSTOM_SYS_AUTH_PASSWD 1
# define CUSTOM_SYS_AUTH_ALLOWED_USER 1
int sys_auth_allowed_user(struct passwd *);
int sys_auth_allowed_user(struct passwd *, Buffer *);
# define CUSTOM_SYS_AUTH_RECORD_LOGIN 1
int sys_auth_record_login(const char *, const char *, const char *);
int sys_auth_record_login(const char *, const char *, const char *, Buffer *);
# define CUSTOM_FAILED_LOGIN 1
#endif
void aix_setauthdb(const char *);
void aix_restoreauthdb(void);
void aix_remove_embedded_newlines(char *);
#if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_GETADDRINFO)
# ifdef getnameinfo
# undef getnameinfo
# endif
int sshaix_getnameinfo(const struct sockaddr *, size_t, char *, size_t,
char *, size_t, int);
# define getnameinfo(a,b,c,d,e,f,g) (sshaix_getnameinfo(a,b,c,d,e,f,g))
#endif
#endif /* _AIX */