ports/64528: problems with ipv6 connections when running as non-root
Dariusz Kulinski
takeda3 at netzero.net
Sun Mar 21 05:20:08 UTC 2004
>Number: 64528
>Category: ports
>Synopsis: problems with ipv6 connections when running as non-root
>Confidential: no
>Severity: non-critical
>Priority: high
>Responsible: freebsd-ports-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Sat Mar 20 21:20:08 PST 2004
>Closed-Date:
>Last-Modified:
>Originator: Dariusz Kulinski <takeda3 at netzero.net>
>Release: FreeBSD 4.9-RELEASE-p4 i386
>Organization:
>Environment:
System: FreeBSD freebsd.takeda.tk 4.9-RELEASE-p4 FreeBSD 4.9-RELEASE-p4 #0: Wed Mar 17 22:05:17 PST 2004 root at freebsd.takeda.tk:/usr/obj/usr/src/sys/TUNED i386
>Description:
oidentd had problems with connections through ipv6 while was degraded to regular user
>How-To-Repeat:
>Fix:
--- oidentd.port begins here ---
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# oidentd
# oidentd/Makefile
# oidentd/distinfo
# oidentd/files
# oidentd/files/oidentd.conf.sample
# oidentd/files/patch-configure
# oidentd/files/patch-unprivileged_ipv6
# oidentd/files/oidentd.sh
# oidentd/files/oidentd_masq.conf.sample
# oidentd/pkg-descr
#
echo c - oidentd
mkdir -p oidentd > /dev/null 2>&1
echo x - oidentd/Makefile
sed 's/^X//' >oidentd/Makefile << 'END-of-oidentd/Makefile'
X# New ports collection makefile for: oidentd
X# Date created: 29 Mar 2000
X# Whom: Trevor Johnson
X#
X# $FreeBSD: ports/security/oidentd/Makefile,v 1.23 2004/02/07 12:03:35 oliver Exp $
X#
X
XPORTNAME= oidentd
XPORTVERSION= 2.0.7
XPORTREVISION= 4
XCATEGORIES= security
XMASTER_SITES= ${MASTER_SITE_SOURCEFORGE}
XMASTER_SITE_SUBDIR= ojnk
X
XMAINTAINER= oliver at FreeBSD.org
XCOMMENT= Ident server that supports user-defined ident strings
X
XUSE_GMAKE= yes
XUSE_REINPLACE= yes
XGNU_CONFIGURE= yes
XCONFIGURE_TARGET= --build=${MACHINE_ARCH}-portbld-freebsd${OSREL}
X
XMAN5= oidentd.conf.5 oidentd_masq.conf.5
XMAN8= oidentd.8
XPLIST_FILES= sbin/oidentd
X
X.include <bsd.port.pre.mk>
X
XUSE_RC_SUBR= yes
X
Xpost-patch:
X @${REINPLACE_CMD} -e 's,/etc/,${PREFIX}&,g' ${WRKSRC}/src/oidentd.h
X
Xpost-build:
X @${SED} -e 's,%%PREFIX%%,${PREFIX},g' \
X -e 's,%%RC_SUBR%%,${RC_SUBR},g' \
X <${FILESDIR}/oidentd.sh >${WRKDIR}/oidentd.sh
X
Xdo-install:
X ${INSTALL_PROGRAM} ${WRKSRC}/src/oidentd ${PREFIX}/sbin
X ${INSTALL_DATA} ${MAN5:S,^,${FILESDIR}/,:S,5$,sample,} ${PREFIX}/etc
X ${INSTALL_SCRIPT} ${WRKDIR}/oidentd.sh ${PREFIX}/etc/rc.d
X ${INSTALL_MAN} ${MAN5:S,^,${WRKSRC}/doc/,} ${PREFIX}/man/man5
X ${INSTALL_MAN} ${MAN8:S,^,${WRKSRC}/doc/,} ${PREFIX}/man/man8
X
X.include <bsd.port.post.mk>
END-of-oidentd/Makefile
echo x - oidentd/distinfo
sed 's/^X//' >oidentd/distinfo << 'END-of-oidentd/distinfo'
XMD5 (oidentd-2.0.7.tar.gz) = cf1c017496b066b45ffe3d7a303fd6ad
XSIZE (oidentd-2.0.7.tar.gz) = 196027
END-of-oidentd/distinfo
echo c - oidentd/files
mkdir -p oidentd/files > /dev/null 2>&1
echo x - oidentd/files/oidentd.conf.sample
sed 's/^X//' >oidentd/files/oidentd.conf.sample << 'END-of-oidentd/files/oidentd.conf.sample'
Xdefault {
X default {
X allow spoof
X deny spoof_all
X deny spoof_privport
X allow random_numeric
X allow numeric
X allow hide
X }
X}
X
Xuser root {
X default {
X force reply "UNKNOWN"
X }
X}
X
X#user eggdrop {
X# default {
X# allow spoof
X# allow spoof_all
X# allow spoof_privport
X# }
X#}
END-of-oidentd/files/oidentd.conf.sample
echo x - oidentd/files/patch-configure
sed 's/^X//' >oidentd/files/patch-configure << 'END-of-oidentd/files/patch-configure'
X--- configure.orig Fri Jul 11 17:50:57 2003
X+++ configure Mon Jul 14 17:32:58 2003
X@@ -3597,7 +3597,7 @@
X
X echo "$as_me:$LINENO: checking for egrep" >&5
X echo $ECHO_N "checking for egrep... $ECHO_C" >&6
X-if test "${ac_cv_prog_egrep+set}" = set; then
X+if test "${ac_cv_prog_egrep+set}" = set ; then
X echo $ECHO_N "(cached) $ECHO_C" >&6
X else
X if echo a | (grep -E '(a|b)') >/dev/null 2>&1
X@@ -3858,6 +3858,9 @@
X cat >>conftest.$ac_ext <<_ACEOF
X /* end confdefs.h. */
X $ac_includes_default
X+#include <sys/socket.h>
X+#include <net/if.h>
X+#include <netinet/in.h>
X #include <$ac_header>
X _ACEOF
X rm -f conftest.$ac_objext
X@@ -5478,6 +5481,11 @@
X cat >>conftest.$ac_ext <<_ACEOF
X /* end confdefs.h. */
X $ac_includes_default
X+#include <sys/socket.h>
X+#include <net/if.h>
X+#include <netinet/in.h>
X+#include <netinet/ip_compat.h>
X+#include <netinet/ip_fil.h>
X #include <netinet/ip_nat.h>
X _ACEOF
X rm -f conftest.$ac_objext
END-of-oidentd/files/patch-configure
echo x - oidentd/files/patch-unprivileged_ipv6
sed 's/^X//' >oidentd/files/patch-unprivileged_ipv6 << 'END-of-oidentd/files/patch-unprivileged_ipv6'
Xdiff -ru src.old/kernel/freebsd.c src/kernel/freebsd.c
X--- src.old/kernel/freebsd.c Sat Mar 20 20:36:51 2004
X+++ src/kernel/freebsd.c Sat Mar 20 20:37:09 2004
X@@ -159,11 +159,11 @@
X
X #ifdef _HAVE_OLD_INPCB
X
X-static struct socket *getlist4( void *arg,
X+static struct socket *getlist( void *arg,
X in_port_t lport,
X in_port_t fport,
X- const struct in_addr *laddr,
X- const struct in_addr *faddr)
X+ const struct sockaddr *laddr,
X+ const struct sockaddr *faddr)
X {
X struct inpcb *pcbp = arg;
X struct inpcb *head;
X@@ -175,8 +175,8 @@
X
X do {
X if (opt_enabled(PROXY)) {
X- if (faddr->s_addr == SIN4(&proxy)->sin_addr.s_addr &&
X- laddr->s_addr != SIN4(&proxy)->sin_addr.s_addr &&
X+ if (SIN4(faddr)->sin_addr.s_addr == SIN4(&proxy)->sin_addr.s_addr &&
X+ SIN4(laddr)->sin_addr.s_addr != SIN4(&proxy)->sin_addr.s_addr &&
X pcbp->inp_fport == fport &&
X pcbp->inp_lport == lport)
X {
X@@ -184,8 +184,8 @@
X }
X }
X
X- if (pcbp->inp_faddr.s_addr == faddr->s_addr &&
X- pcbp->inp_laddr.s_addr == laddr->s_addr &&
X+ if (pcbp->inp_faddr.s_addr == SIN4(faddr)->sin_addr.s_addr &&
X+ pcbp->inp_laddr.s_addr == SIN4(laddr)->sin_addr.s_addr &&
X pcbp->inp_fport == fport &&
X pcbp->inp_lport == lport)
X {
X@@ -199,16 +199,33 @@
X
X #else
X
X-static struct socket *getlist4( void *arg,
X+static struct socket *getlist( void *arg,
X in_port_t lport,
X in_port_t fport,
X- const struct in_addr *laddr,
X- const struct in_addr *faddr)
X+ const struct sockaddr *local,
X+ const struct sockaddr *remote)
X {
X struct inpcb *head, pcbp;
X struct inpcbhead *pcbhead = arg;
X+ char *faddr, *laddr, *pfaddr, *pladdr;
X+ int alen;
X
X- (void) laddr;
X+ if (remote->sa_family != local->sa_family)
X+ return (NULL);
X+ switch (remote->sa_family) {
X+ case AF_INET:
X+ faddr = (char *)&SIN4(remote)->sin_addr;
X+ laddr = (char *)&SIN4(local)->sin_addr;
X+ break;
X+#ifdef INP_IPV6
X+ case AF_INET6:
X+ faddr = (char *)&SIN6(remote)->sin6_addr;
X+ laddr = (char *)&SIN6(local)->sin6_addr;
X+ break;
X+#endif
X+ default:
X+ return (NULL);
X+ }
X
X head = pcbhead->lh_first;
X if (head == NULL)
X@@ -218,9 +235,9 @@
X if (getbuf((u_long) head, &pcbp, sizeof(struct inpcb)) == -1)
X break;
X
X- if (opt_enabled(PROXY)) {
X- if (faddr->s_addr == SIN4(&proxy)->sin_addr.s_addr &&
X- laddr->s_addr != SIN4(&proxy)->sin_addr.s_addr &&
X+ if (opt_enabled(PROXY) && remote->sa_family == AF_INET) {
X+ if (SIN4(remote)->sin_addr.s_addr == SIN4(&proxy)->sin_addr.s_addr &&
X+ SIN4(local)->sin_addr.s_addr != SIN4(&proxy)->sin_addr.s_addr &&
X pcbp.inp_fport == fport &&
X pcbp.inp_lport == lport)
X {
X@@ -228,8 +245,32 @@
X }
X }
X
X- if (pcbp.inp_faddr.s_addr == faddr->s_addr &&
X- pcbp.inp_laddr.s_addr == laddr->s_addr &&
X+#ifdef INP_IPV6
X+ if (pcbp.inp_vflag & INP_IPV4)
X+ {
X+ if (remote->sa_family != AF_INET)
X+ continue;
X+ pfaddr = (char *)&pcbp.inp_faddr;
X+ pladdr = (char *)&pcbp.inp_laddr;
X+ alen = sizeof(struct in_addr);
X+ }
X+ else if (pcbp.inp_vflag & INP_IPV6)
X+ {
X+ if (remote->sa_family != AF_INET6)
X+ continue;
X+ pfaddr = (char *)&pcbp.in6p_faddr;
X+ pladdr = (char *)&pcbp.in6p_laddr;
X+ alen = sizeof(struct in6_addr);
X+ }
X+ else
X+ continue;
X+#else
X+ pfaddr = (char *)&pcbp.inp_faddr;
X+ pladdr = (char *)&pcbp.inp_laddr;
X+ alen = sizeof(struct in_addr);
X+#endif
X+ if (memcmp(pfaddr, faddr, alen) == 0 &&
X+ memcmp(pladdr, laddr, alen) == 0 &&
X pcbp.inp_fport == fport &&
X pcbp.inp_lport == lport)
X {
X@@ -248,7 +289,7 @@
X ** Return the UID of the connection owner
X */
X
X-int get_user4( in_port_t lport,
X+static int get_user( in_port_t lport,
X in_port_t fport,
X struct sockaddr_storage *laddr,
X struct sockaddr_storage *faddr)
X@@ -276,8 +317,9 @@
X tcb.inp_prev = (struct inpcb *) kinfo->nl[N_TCB].n_value;
X #endif
X
X- sockp = getlist4(&tcb, lport, fport,
X- &SIN4(laddr)->sin_addr, &SIN4(faddr)->sin_addr);
X+ sockp = getlist(&tcb, lport, fport,
X+ (struct sockaddr *)laddr,
X+ (struct sockaddr *)faddr);
X
X if (sockp == NULL)
X return (-1);
X@@ -346,6 +388,14 @@
X return (-1);
X }
X
X+int get_user4( in_port_t lport,
X+ in_port_t fport,
X+ struct sockaddr_storage *laddr,
X+ struct sockaddr_storage *faddr)
X+{
X+ return (get_user(lport, fport, laddr, faddr));
X+}
X+
X #ifdef MASQ_SUPPORT
X
X /*
X@@ -456,36 +506,7 @@
X struct sockaddr_storage *laddr,
X struct sockaddr_storage *faddr)
X {
X- struct ucred ucred;
X- struct sockaddr_in6 sin6[2];
X- int len;
X- int ret;
X-
X- len = sizeof(struct ucred);
X-
X- memset(sin6, 0, sizeof(sin6));
X-
X- sin6[0].sin6_len = sizeof(struct sockaddr_in6);
X- sin6[0].sin6_family = AF_INET6;
X- sin6[0].sin6_port = lport;
X- memcpy(&sin6[0].sin6_addr, &SIN6(laddr)->sin6_addr,
X- sizeof(sin6[0].sin6_addr));
X-
X- sin6[1].sin6_len = sizeof(struct sockaddr_in6);
X- sin6[1].sin6_family = AF_INET6;
X- sin6[1].sin6_port = fport;
X- memcpy(&sin6[1].sin6_addr, &SIN6(faddr)->sin6_addr,
X- sizeof(sin6[1].sin6_addr));
X-
X- ret = sysctlbyname("net.inet6.tcp6.getcred",
X- &ucred, &len, sin6, sizeof(sin6));
X-
X- if (ret == -1) {
X- debug("sysctlbyname: %s", strerror(errno));
X- return (-1);
X- }
X-
X- return (ucred.cr_uid);
X+ return (get_user(lport, fport, laddr, faddr));
X }
X
X #endif
Xdiff -ru src.old/kernel/freebsd5.c src/kernel/freebsd5.c
X--- src.old/kernel/freebsd5.c Sat Mar 20 20:36:51 2004
X+++ src/kernel/freebsd5.c Sat Mar 20 20:37:13 2004
X@@ -160,11 +160,11 @@
X
X #ifdef _HAVE_OLD_INPCB
X
X-static struct socket *getlist4( void *arg,
X+static struct socket *getlist( void *arg,
X in_port_t lport,
X in_port_t fport,
X- const struct in_addr *laddr,
X- const struct in_addr *faddr)
X+ const struct sockaddr *laddr,
X+ const struct sockaddr *faddr)
X {
X struct inpcb *pcbp = arg;
X struct inpcb *head;
X@@ -176,8 +176,8 @@
X
X do {
X if (opt_enabled(PROXY)) {
X- if (faddr->s_addr == SIN4(&proxy)->sin_addr.s_addr &&
X- laddr->s_addr != SIN4(&proxy)->sin_addr.s_addr &&
X+ if (SIN4(faddr)->sin_addr.s_addr == SIN4(&proxy)->sin_addr.s_addr &&
X+ SIN4(laddr)->sin_addr.s_addr != SIN4(&proxy)->sin_addr.s_addr &&
X pcbp->inp_fport == fport &&
X pcbp->inp_lport == lport)
X {
X@@ -185,8 +185,8 @@
X }
X }
X
X- if (pcbp->inp_faddr.s_addr == faddr->s_addr &&
X- pcbp->inp_laddr.s_addr == laddr->s_addr &&
X+ if (pcbp->inp_faddr.s_addr == SIN4(faddr)->sin_addr.s_addr &&
X+ pcbp->inp_laddr.s_addr == SIN4(laddr)->sin_addr.s_addr &&
X pcbp->inp_fport == fport &&
X pcbp->inp_lport == lport)
X {
X@@ -200,16 +200,31 @@
X
X #else
X
X-static struct socket *getlist4( void *arg,
X+static struct socket *getlist( void *arg,
X in_port_t lport,
X in_port_t fport,
X- const struct in_addr *laddr,
X- const struct in_addr *faddr)
X+ const struct sockaddr *local,
X+ const struct sockaddr *remote)
X {
X struct inpcb *head, pcbp;
X struct inpcbhead *pcbhead = arg;
X+ char *faddr, *laddr, *pfaddr, *pladdr;
X+ int alen;
X
X- (void) laddr;
X+ if (remote->sa_family != local->sa_family)
X+ return (NULL);
X+ switch (remote->sa_family) {
X+ case AF_INET:
X+ faddr = (char *)&SIN4(remote)->sin_addr;
X+ laddr = (char *)&SIN4(local)->sin_addr;
X+ break;
X+ case AF_INET6:
X+ faddr = (char *)&SIN6(remote)->sin6_addr;
X+ laddr = (char *)&SIN6(local)->sin6_addr;
X+ break;
X+ default:
X+ return (NULL);
X+ }
X
X head = pcbhead->lh_first;
X if (head == NULL)
X@@ -219,9 +234,9 @@
X if (getbuf((u_long) head, &pcbp, sizeof(struct inpcb)) == -1)
X break;
X
X- if (opt_enabled(PROXY)) {
X- if (faddr->s_addr == SIN4(&proxy)->sin_addr.s_addr &&
X- laddr->s_addr != SIN4(&proxy)->sin_addr.s_addr &&
X+ if (opt_enabled(PROXY) && remote->sa_family == AF_INET) {
X+ if (SIN4(remote)->sin_addr.s_addr == SIN4(&proxy)->sin_addr.s_addr &&
X+ SIN4(local)->sin_addr.s_addr != SIN4(&proxy)->sin_addr.s_addr &&
X pcbp.inp_fport == fport &&
X pcbp.inp_lport == lport)
X {
X@@ -229,8 +244,26 @@
X }
X }
X
X- if (pcbp.inp_faddr.s_addr == faddr->s_addr &&
X- pcbp.inp_laddr.s_addr == laddr->s_addr &&
X+ if (pcbp.inp_vflag & INP_IPV4)
X+ {
X+ if (remote->sa_family != AF_INET)
X+ continue;
X+ pfaddr = (char *)&pcbp.inp_faddr;
X+ pladdr = (char *)&pcbp.inp_laddr;
X+ alen = sizeof(struct in_addr);
X+ }
X+ else if (pcbp.inp_vflag & INP_IPV6)
X+ {
X+ if (remote->sa_family != AF_INET6)
X+ continue;
X+ pfaddr = (char *)&pcbp.in6p_faddr;
X+ pladdr = (char *)&pcbp.in6p_laddr;
X+ alen = sizeof(struct in6_addr);
X+ }
X+ else
X+ continue;
X+ if (memcmp(pfaddr, faddr, alen) == 0 &&
X+ memcmp(pladdr, laddr, alen) == 0 &&
X pcbp.inp_fport == fport &&
X pcbp.inp_lport == lport)
X {
X@@ -249,7 +282,7 @@
X ** Return the UID of the connection owner
X */
X
X-int get_user4( in_port_t lport,
X+static int get_user( in_port_t lport,
X in_port_t fport,
X struct sockaddr_storage *laddr,
X struct sockaddr_storage *faddr)
X@@ -276,8 +309,9 @@
X tcb.inp_prev = (struct inpcb *) kinfo->nl[N_TCB].n_value;
X #endif
X
X- sockp = getlist4(&tcb, lport, fport,
X- &SIN4(laddr)->sin_addr, &SIN4(faddr)->sin_addr);
X+ sockp = getlist(&tcb, lport, fport,
X+ (struct sockaddr *)laddr,
X+ (struct sockaddr *)faddr);
X
X if (sockp == NULL)
X return (-1);
X@@ -338,6 +372,14 @@
X return (-1);
X }
X
X+int get_user4( in_port_t lport,
X+ in_port_t fport,
X+ struct sockaddr_storage *laddr,
X+ struct sockaddr_storage *faddr)
X+{
X+ return (get_user(lport, fport, laddr, faddr));
X+}
X+
X #ifdef MASQ_SUPPORT
X
X /*
X@@ -448,36 +490,7 @@
X struct sockaddr_storage *laddr,
X struct sockaddr_storage *faddr)
X {
X- struct ucred ucred;
X- struct sockaddr_in6 sin6[2];
X- int len;
X- int ret;
X-
X- len = sizeof(struct ucred);
X-
X- memset(sin6, 0, sizeof(sin6));
X-
X- sin6[0].sin6_len = sizeof(struct sockaddr_in6);
X- sin6[0].sin6_family = AF_INET6;
X- sin6[0].sin6_port = lport;
X- memcpy(&sin6[0].sin6_addr, &SIN6(laddr)->sin6_addr,
X- sizeof(sin6[0].sin6_addr));
X-
X- sin6[1].sin6_len = sizeof(struct sockaddr_in6);
X- sin6[1].sin6_family = AF_INET6;
X- sin6[1].sin6_port = fport;
X- memcpy(&sin6[1].sin6_addr, &SIN6(faddr)->sin6_addr,
X- sizeof(sin6[1].sin6_addr));
X-
X- ret = sysctlbyname("net.inet6.tcp6.getcred",
X- &ucred, &len, sin6, sizeof(sin6));
X-
X- if (ret == -1) {
X- debug("sysctlbyname: %s", strerror(errno));
X- return (-1);
X- }
X-
X- return (ucred.cr_uid);
X+ return (get_user(lport, fport, laddr, faddr));
X }
X
X #endif
END-of-oidentd/files/patch-unprivileged_ipv6
echo x - oidentd/files/oidentd.sh
sed 's/^X//' >oidentd/files/oidentd.sh << 'END-of-oidentd/files/oidentd.sh'
X#!/bin/sh
X#
X# $FreeBSD: ports/security/oidentd/files/oidentd.sh,v 1.1 2004/01/31 13:32:34 oliver Exp $
X#
X
X# PROVIDE: oidentd
X# REQUIRE: DAEMON
X# KEYWORD: FreeBSD shutdown
X
X#
X# Add the following lines to /etc/rc.conf to enable dovecot:
X#
X#oidentd_enable="YES"
X#
X# See oidentd(8) for flags.
X#
X
X. %%RC_SUBR%%
X
Xname=oidentd
Xrcvar=`set_rcvar`
X
Xcommand=%%PREFIX%%/sbin/${name}
Xrequired_files=%%PREFIX%%/etc/${name}.conf
X
X# set defaults
X
Xoidentd_enable=${oidentd_enable:-"NO"}
Xoidentd_flags=${oidentd_flags:-""}
X
Xload_rc_config ${name}
Xrun_rc_command "$1"
END-of-oidentd/files/oidentd.sh
echo x - oidentd/files/oidentd_masq.conf.sample
sed 's/^X//' >oidentd/files/oidentd_masq.conf.sample << 'END-of-oidentd/files/oidentd_masq.conf.sample'
X192.168.1.1/32 client1 UNIX
X192.168.2.1/32 client2 UNIX
END-of-oidentd/files/oidentd_masq.conf.sample
echo x - oidentd/pkg-descr
sed 's/^X//' >oidentd/pkg-descr << 'END-of-oidentd/pkg-descr'
XFrom the README:
X
X"oidentd is an ident (rfc1413 compliant) daemon that runs on Linux,
XFreeBSD, OpenBSD and Solaris. oidentd can handle IP masqueraded/NAT connections
Xon Linux, FreeBSD (ipf only) and OpenBSD. oidentd has a flexible mechanism for
Xspecifying ident responses. Users can be granted permission to specify their
Xown ident responses. Responses can be specified according to host and port
Xpairs."
X
XFreeBSD's inetd has a built-in ident service which can also generate
Xbogus responses.
X
XPlease see the TODO file for more information on why only ipf is
Xsupported under FreeBSD.
X
XWWW: http://ojnk.sourceforge.net/
X
XMark Laws
Xmdl at 60hz.org
END-of-oidentd/pkg-descr
exit
--- oidentd.port ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-ports-bugs
mailing list