--- /dev/null
+diff -ruN --exclude *.wiget cyrus-sasl-1.5.27.noipv6/acconfig.h cyrus-sasl-1.5.27/acconfig.h
+--- cyrus-sasl-1.5.27.noipv6/acconfig.h Thu Apr 26 16:20:50 2001
++++ cyrus-sasl-1.5.27/acconfig.h Thu Apr 26 16:21:12 2001
+@@ -137,8 +137,20 @@
+ /* define if your system has getpid() */
+ #undef HAVE_GETPID
+
++/* define if your system has struct sockaddr_storage */
++#undef HAVE_SOCKADDR_STORAGE
++
+ @BOTTOM@
+
++/* define if your system has getnameinfo() */
++#undef HAVE_GETNAMEINFO
++
++/* Define if you have ss_family in struct sockaddr_storage. */
++#undef HAVE_SS_FAMILY
++
++/* do we have socklen_t? */
++#undef HAVE_SOCKLEN_T
++
+ /* location of the random number generator */
+ #ifndef DEV_RANDOM
+ #define DEV_RANDOM "/dev/random"
+@@ -181,6 +193,22 @@
+ #endif /* WIN32 */
+ #include <string.h>
+
++#if defined(HAVE_SOCKADDR_STORAGE) && defined(HAVE_GETNAMEINFO)
++#define INET6
++#endif
++#ifdef INET6
++#include <sys/socket.h>
++#ifndef NI_WITHSCOPEID
++#define NI_WITHSCOPEID 0
++#endif
++#ifndef HAVE_SS_FAMILY
++#define ss_family __ss_family
++#endif
++#endif
+ #include <netinet/in.h>
++
++#ifndef HAVE_SOCKLEN_T
++typedef int socklen_t;
++#endif
+
+ #endif /* CONFIG_H */
+diff -ruN --exclude *.wiget cyrus-sasl-1.5.27.noipv6/aclocal.m4 cyrus-sasl-1.5.27/aclocal.m4
+--- cyrus-sasl-1.5.27.noipv6/aclocal.m4 Sat Mar 24 02:48:12 2001
++++ cyrus-sasl-1.5.27/aclocal.m4 Thu Apr 26 16:21:12 2001
+@@ -692,3 +692,72 @@
+ AC_SUBST(LIB_SOCKET)
+ ])
+
++dnl See whether we can use IPv6 related functions
++AC_DEFUN(IPv6_CHECK_FUNC, [
++changequote(, )dnl
++ac_tr_lib=HAVE_`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \
++ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
++changequote([, ])dnl
++AC_CHECK_FUNC($1, [dnl
++ AC_DEFINE_UNQUOTED($ac_tr_lib)
++ ac_cv_lib_socket_$1=no
++ ac_cv_lib_inet6_$1=no
++], [dnl
++ AC_CHECK_LIB(socket, $1, [dnl
++ AC_DEFINE_UNQUOTED($ac_tr_lib)
++ LIBS="$LIBS -lsocket"
++ ac_cv_lib_inet6_$1=no
++ ], [dnl
++ AC_MSG_CHECKING([whether your system has IPv6 directory])
++ AC_CACHE_VAL(ipv6_cv_dir, [dnl
++ for ipv6_cv_dir in /usr/local/v6 /usr/inet6 no; do
++ if test $ipv6_cv_dir = no -o -d $ipv6_cv_dir; then
++ break
++ fi
++ done])dnl
++ AC_MSG_RESULT($ipv6_cv_dir)
++ if test $ipv6_cv_dir = no; then
++ ac_cv_lib_inet6_$1=no
++ else
++ if test x$ipv6_libinet6 = x; then
++ ipv6_libinet6=no
++ SAVELDFLAGS="$LDFLAGS"
++ LDFLAGS="$LDFLAGS -L$ipv6_cv_dir/lib"
++ fi
++ AC_CHECK_LIB(inet6, $1, [dnl
++ AC_DEFINE_UNQUOTED($ac_tr_lib)
++ if test $ipv6_libinet6 = no; then
++ ipv6_libinet6=yes
++ LIBS="$LIBS -linet6"
++ fi],)dnl
++ if test $ipv6_libinet6 = no; then
++ LDFLAGS="$SAVELDFLAGS"
++ fi
++ fi])dnl
++])dnl
++if test $ac_cv_func_$1 = yes -o $ac_cv_lib_socket_$1 = yes \
++ -o $ac_cv_lib_inet6_$1 = yes
++then
++ ipv6_cv_$1=yes
++ ifelse([$2], , :, [$2])
++else
++ ipv6_cv_$1=no
++ ifelse([$3], , :, [$3])
++fi])
++
++
++dnl See whether we have ss_family in sockaddr_storage
++AC_DEFUN(IPv6_CHECK_SS_FAMILY, [
++AC_MSG_CHECKING([whether you have ss_family in struct sockaddr_storage])
++AC_CACHE_VAL(ipv6_cv_ss_family, [dnl
++AC_TRY_COMPILE([#include <sys/types.h>
++#include <sys/socket.h>],
++ [struct sockaddr_storage ss; int i = ss.ss_family;],
++ [ipv6_cv_ss_family=yes], [ipv6_cv_ss_family=no])])dnl
++if test $ipv6_cv_ss_family = yes; then
++ ifelse([$1], , AC_DEFINE(HAVE_SS_FAMILY), [$1])
++else
++ ifelse([$2], , :, [$2])
++fi
++AC_MSG_RESULT($ipv6_cv_ss_family)])
++
+diff -ruN --exclude *.wiget cyrus-sasl-1.5.27.noipv6/cmulocal/ipv6.m4 cyrus-sasl-1.5.27/cmulocal/ipv6.m4
+--- cyrus-sasl-1.5.27.noipv6/cmulocal/ipv6.m4 Thu Jan 1 01:00:00 1970
++++ cyrus-sasl-1.5.27/cmulocal/ipv6.m4 Thu Apr 26 16:21:12 2001
+@@ -0,0 +1,68 @@
++dnl See whether we can use IPv6 related functions
++AC_DEFUN(IPv6_CHECK_FUNC, [
++changequote(, )dnl
++ac_tr_lib=HAVE_`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \
++ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
++changequote([, ])dnl
++AC_CHECK_FUNC($1, [dnl
++ AC_DEFINE_UNQUOTED($ac_tr_lib)
++ ac_cv_lib_socket_$1=no
++ ac_cv_lib_inet6_$1=no
++], [dnl
++ AC_CHECK_LIB(socket, $1, [dnl
++ AC_DEFINE_UNQUOTED($ac_tr_lib)
++ LIBS="$LIBS -lsocket"
++ ac_cv_lib_inet6_$1=no
++ ], [dnl
++ AC_MSG_CHECKING([whether your system has IPv6 directory])
++ AC_CACHE_VAL(ipv6_cv_dir, [dnl
++ for ipv6_cv_dir in /usr/local/v6 /usr/inet6 no; do
++ if test $ipv6_cv_dir = no -o -d $ipv6_cv_dir; then
++ break
++ fi
++ done])dnl
++ AC_MSG_RESULT($ipv6_cv_dir)
++ if test $ipv6_cv_dir = no; then
++ ac_cv_lib_inet6_$1=no
++ else
++ if test x$ipv6_libinet6 = x; then
++ ipv6_libinet6=no
++ SAVELDFLAGS="$LDFLAGS"
++ LDFLAGS="$LDFLAGS -L$ipv6_cv_dir/lib"
++ fi
++ AC_CHECK_LIB(inet6, $1, [dnl
++ AC_DEFINE_UNQUOTED($ac_tr_lib)
++ if test $ipv6_libinet6 = no; then
++ ipv6_libinet6=yes
++ LIBS="$LIBS -linet6"
++ fi],)dnl
++ if test $ipv6_libinet6 = no; then
++ LDFLAGS="$SAVELDFLAGS"
++ fi
++ fi])dnl
++])dnl
++if test $ac_cv_func_$1 = yes -o $ac_cv_lib_socket_$1 = yes \
++ -o $ac_cv_lib_inet6_$1 = yes
++then
++ ipv6_cv_$1=yes
++ ifelse([$2], , :, [$2])
++else
++ ipv6_cv_$1=no
++ ifelse([$3], , :, [$3])
++fi])
++
++
++dnl See whether we have ss_family in sockaddr_storage
++AC_DEFUN(IPv6_CHECK_SS_FAMILY, [
++AC_MSG_CHECKING([whether you have ss_family in struct sockaddr_storage])
++AC_CACHE_VAL(ipv6_cv_ss_family, [dnl
++AC_TRY_COMPILE([#include <sys/types.h>
++#include <sys/socket.h>],
++ [struct sockaddr_storage ss; int i = ss.ss_family;],
++ [ipv6_cv_ss_family=yes], [ipv6_cv_ss_family=no])])dnl
++if test $ipv6_cv_ss_family = yes; then
++ ifelse([$1], , AC_DEFINE(HAVE_SS_FAMILY), [$1])
++else
++ ifelse([$2], , :, [$2])
++fi
++AC_MSG_RESULT($ipv6_cv_ss_family)])
+diff -ruN --exclude *.wiget cyrus-sasl-1.5.27.noipv6/config.h.in cyrus-sasl-1.5.27/config.h.in
+--- cyrus-sasl-1.5.27.noipv6/config.h.in Wed Mar 14 05:49:33 2001
++++ cyrus-sasl-1.5.27/config.h.in Thu Apr 26 16:21:12 2001
+@@ -119,6 +119,9 @@
+ /* do we have a preferred mechanism, or should we just pick the highest ssf? */
+ #undef PREFER_MECH
+
++/* define if your system has struct sockaddr_storage */
++#undef HAVE_SOCKADDR_STORAGE
++
+ /* Define if you have the getdomainname function. */
+ #undef HAVE_GETDOMAINNAME
+
+@@ -198,6 +201,15 @@
+ #undef HAVE___ATTRIBUTE__
+
+
++/* define if your system has getnameinfo() */
++#undef HAVE_GETNAMEINFO
++
++/* Define if you have ss_family in struct sockaddr_storage. */
++#undef HAVE_SS_FAMILY
++
++/* do we have socklen_t? */
++#undef HAVE_SOCKLEN_T
++
+ /* location of the random number generator */
+ #ifndef DEV_RANDOM
+ #define DEV_RANDOM "/dev/random"
+@@ -239,6 +251,22 @@
+ #endif /* WIN32 */
+ #include <string.h>
+
++#if defined(HAVE_SOCKADDR_STORAGE) && defined(HAVE_GETNAMEINFO)
++#define INET6
++#endif
++#ifdef INET6
++#include <sys/socket.h>
++#ifndef NI_WITHSCOPEID
++#define NI_WITHSCOPEID 0
++#endif
++#ifndef HAVE_SS_FAMILY
++#define ss_family __ss_family
++#endif
++#endif
+ #include <netinet/in.h>
++
++#ifndef HAVE_SOCKLEN_T
++typedef int socklen_t;
++#endif
+
+ #endif /* CONFIG_H */
+diff -ruN --exclude *.wiget cyrus-sasl-1.5.27.noipv6/configure.in cyrus-sasl-1.5.27/configure.in
+--- cyrus-sasl-1.5.27.noipv6/configure.in Thu Apr 26 16:20:50 2001
++++ cyrus-sasl-1.5.27/configure.in Thu Apr 26 16:21:12 2001
+@@ -782,6 +782,19 @@
+ AC_DEFINE_UNQUOTED(PREFER_MECH, "KERBEROS_V4")
+ fi
+
++AC_ARG_ENABLE(ipv6, [ --disable-ipv6 Don't compile in IPv6 support],
++ ipv6="$enableval", ipv6="yes")
++if test "$ipv6" != "yes"; then
++ AC_MSG_RESULT(IPv6 support is disabled)
++else
++ IPv6_CHECK_FUNC(getnameinfo)
++ AC_EGREP_HEADER(sockaddr_storage, sys/socket.h,
++ AC_DEFINE(HAVE_SOCKADDR_STORAGE))
++ IPv6_CHECK_SS_FAMILY()
++fi
++
++AC_EGREP_HEADER(socklen_t, sys/socket.h, AC_DEFINE(HAVE_SOCKLEN_T))
++
+ AC_SUBST(DIRS)
+
+ AC_OUTPUT(Makefile
+diff -ruN --exclude *.wiget cyrus-sasl-1.5.27.noipv6/lib/checkpw.c cyrus-sasl-1.5.27/lib/checkpw.c
+--- cyrus-sasl-1.5.27.noipv6/lib/checkpw.c Thu Apr 26 16:20:50 2001
++++ cyrus-sasl-1.5.27/lib/checkpw.c Thu Apr 26 16:23:39 2001
+@@ -571,7 +571,12 @@
+ const char **reply)
+ {
+ char *host;
++#ifdef INET6
++ struct sockaddr *addr;
++ socklen_t salen;
++#else
+ struct sockaddr_in *addr;
++#endif
+ char *argv[2], *argv0 = "SASL";
+ SIAENTITY *ent;
+ int ret;
+@@ -586,8 +591,21 @@
+ /* Get the remote host */
+ if (sasl_getprop(conn, SASL_IP_REMOTE, (void **) &addr) != SASL_OK)
+ host = NULL;
+- else
++ else {
++#ifdef INET6
++#ifdef SIN6_LEN
++ salen = addr->sa_len;
++#else
++ salen = (addr->sa_family == AF_INET) ? sizeof(struct sockaddr_in)
++ : sizeof(struct sockaddr_in6);
++#endif
++ getnameinfo(addr, salen, hbuf, sizeof(hbuf), NULL, 0,
++ NI_NUMERICHOST | NI_WITHSCOPEID);
++ host = hbuf;
++#else
+ host = inet_ntoa(*addr);
++#endif
++ }
+
+ /* Try to validate */
+ if (sia_ses_init (&ent, 1, argv, host, userid, NULL, 0, NULL) != SIASUCCESS)
+diff -ruN --exclude *.wiget cyrus-sasl-1.5.27.noipv6/lib/common.c cyrus-sasl-1.5.27/lib/common.c
+--- cyrus-sasl-1.5.27.noipv6/lib/common.c Thu Apr 26 16:20:49 2001
++++ cyrus-sasl-1.5.27/lib/common.c Thu Apr 26 16:21:12 2001
+@@ -359,13 +359,21 @@
+ if (! conn->got_ip_local)
+ result = SASL_NOTDONE;
+ else
++#ifdef INET6
++ *(struct sockaddr **)pvalue = (struct sockaddr *)&conn->ip_local;
++#else
+ *(struct sockaddr_in **)pvalue = &conn->ip_local;
++#endif
+ break;
+ case SASL_IP_REMOTE:
+ if (! conn->got_ip_remote)
+ result = SASL_NOTDONE;
+ else
++#ifdef INET6
++ *(struct sockaddr **)pvalue = (struct sockaddr *)&conn->ip_remote;
++#else
+ *(struct sockaddr_in **)pvalue = &conn->ip_remote;
++#endif
+ break;
+ default:
+ result = SASL_BADPARAM;
+@@ -382,6 +390,10 @@
+ {
+ int result = SASL_OK;
+ char *str;
++#ifdef INET6
++ int family;
++ socklen_t salen;
++#endif
+
+ /* make sure the sasl context is valid */
+ if (!conn)
+@@ -413,12 +425,40 @@
+ sizeof(sasl_security_properties_t));
+ break;
+ case SASL_IP_LOCAL:
+- conn->got_ip_local = 1;
++#ifdef INET6
++ /* XXX: Yes, this is ugly. But, there is such code, eg. testsuite.c */
++ family = ((struct sockaddr *)value)->sa_family;
++ if (family!= AF_INET && family != AF_INET6)
++ family = AF_INET;
++ salen = (family == AF_INET) ? sizeof(struct sockaddr_in)
++ : sizeof(struct sockaddr_in6);
++ memcpy(&conn->ip_local, value, salen);
++ conn->ip_local.ss_family = family;
++#ifdef SIN6_LEN
++ conn->ip_local.ss_len = salen;
++#endif
++#else
+ conn->ip_local= *(struct sockaddr_in *) value;
++#endif
++ conn->got_ip_local = 1;
+ break;
+ case SASL_IP_REMOTE:
+- conn->got_ip_remote = 1;
++#ifdef INET6
++ /* XXX: Yes, this is ugly. But, there is such code, eg. testsuite.c */
++ family = ((struct sockaddr *)value)->sa_family;
++ if (family!= AF_INET && family != AF_INET6)
++ family = AF_INET;
++ salen = (family == AF_INET) ? sizeof(struct sockaddr_in)
++ : sizeof(struct sockaddr_in6);
++ memcpy(&conn->ip_remote, value, salen);
++ conn->ip_remote.ss_family = family;
++#ifdef SIN6_LEN
++ conn->ip_remote.ss_len = salen;
++#endif
++#else
+ conn->ip_remote= *(struct sockaddr_in *) value;
++#endif
++ conn->got_ip_remote = 1;
+ break;
+ default:
+ result = SASL_BADPARAM;
+diff -ruN --exclude *.wiget cyrus-sasl-1.5.27.noipv6/lib/saslint.h cyrus-sasl-1.5.27/lib/saslint.h
+--- cyrus-sasl-1.5.27.noipv6/lib/saslint.h Thu Apr 26 16:20:49 2001
++++ cyrus-sasl-1.5.27/lib/saslint.h Thu Apr 26 16:21:12 2001
+@@ -95,7 +95,11 @@
+
+ int secflags; /* security layer flags passed to sasl_*_new */
+ int got_ip_local, got_ip_remote;
++#ifdef INET6
++ struct sockaddr_storage ip_local, ip_remote;
++#else
+ struct sockaddr_in ip_local, ip_remote;
++#endif
+ sasl_external_properties_t external;
+
+ void *context;
+diff -ruN --exclude *.wiget cyrus-sasl-1.5.27.noipv6/plugins/anonymous.c cyrus-sasl-1.5.27/plugins/anonymous.c
+--- cyrus-sasl-1.5.27.noipv6/plugins/anonymous.c Sat Mar 10 06:56:44 2001
++++ cyrus-sasl-1.5.27/plugins/anonymous.c Thu Apr 26 16:21:12 2001
+@@ -101,7 +101,11 @@
+ const char **errstr)
+ {
+ int result;
++#ifdef INET6
++ struct sockaddr *remote_addr;
++#else
+ struct sockaddr_in *remote_addr;
++#endif
+ char *clientdata;
+
+ if (!sparams
+@@ -133,6 +137,23 @@
+ SASL_IP_REMOTE, (void **)&remote_addr);
+
+ if (result==SASL_OK) {
++#ifdef INET6
++ socklen_t salen;
++ char hbuf[NI_MAXHOST];
++
++#ifdef SIN6_LEN
++ salen = remote_addr->sa_len;
++#else
++ salen = (remote_addr->sa_family == AF_INET)
++ ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
++#endif
++ getnameinfo(remote_addr, salen, hbuf, sizeof(hbuf), NULL, 0,
++ NI_NUMERICHOST | NI_WITHSCOPEID);
++ sparams->utils->log(sparams->utils->conn,
++ SASL_LOG_INFO,
++ "ANONYMOUS", 0, 0,
++ "login: \"%s\" from [%s]", clientdata, hbuf);
++#else
+ int ipnum = remote_addr->sin_addr.s_addr;
+
+ sparams->utils->log(sparams->utils->conn,
+@@ -144,6 +165,7 @@
+ ipnum >> 16 & 0xFF,
+ ipnum >> 8 &0xFF,
+ ipnum & 0xFF);
++#endif
+ } else {
+ sparams->utils->log(sparams->utils->conn,
+ SASL_LOG_INFO,
+diff -ruN --exclude *.wiget cyrus-sasl-1.5.27.noipv6/plugins/kerberos4.c cyrus-sasl-1.5.27/plugins/kerberos4.c
+--- cyrus-sasl-1.5.27.noipv6/plugins/kerberos4.c Thu Apr 26 16:20:50 2001
++++ cyrus-sasl-1.5.27/plugins/kerberos4.c Thu Apr 26 16:21:12 2001
+@@ -131,10 +131,17 @@
+ des_key_schedule dec_keysched; /* decryption key schedule */
+
+
++#ifdef INET6
++ struct sockaddr *ip_local; /* local ip address and port.
++ needed for layers */
++ struct sockaddr *ip_remote; /* remote ip address and port.
++ needed for layers */
++#else
+ struct sockaddr_in *ip_local; /* local ip address and port.
+ needed for layers */
+ struct sockaddr_in *ip_remote; /* remote ip address and port.
+ needed for layers */
++#endif
+
+ sasl_malloc_t *malloc; /* encode and decode need these */
+ sasl_realloc_t *realloc;
+@@ -580,7 +587,11 @@
+ AUTH_DAT ad;
+ KTEXT_ST ticket;
+ int lup;
++#ifdef INET6
++ struct sockaddr *addr;
++#else
+ struct sockaddr_in *addr;
++#endif
+
+ VL(("KERBEROS_V4 Step 2\n"));
+
+@@ -619,9 +630,17 @@
+ return SASL_BADAUTH;
+ }
+ #endif
++#ifdef INET6
++ if (addr->sa_family != AF_INET) {
++ if (errstr)
++ *errstr = "unsupported address family";
++ return SASL_BADAUTH;
++ }
++#endif
+ /* check ticket */
+ result = krb_rd_req(&ticket, (char *) sparams->service, text->instance,
+- addr ? addr->sin_addr.s_addr : 0L, &ad, srvtab);
++ addr ? ((struct sockaddr_in *)addr)->sin_addr.s_addr
++ : 0L, &ad, srvtab);
+
+ if (result) { /* if fails mechanism fails */
+ VL(("krb_rd_req failed service=%s instance=%s error code=%i\n",