Date: Sat, 20 Mar 2004 21:17:58 -0800 (PST) From: Dariusz Kulinski <takeda3@netzero.net> To: FreeBSD-gnats-submit@FreeBSD.org Subject: ports/64528: problems with ipv6 connections when running as non-root Message-ID: <200403210517.i2L5HwCh012163@freebsd.takeda.tk> Resent-Message-ID: <200403210520.i2L5K8CO030881@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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@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@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@60hz.org END-of-oidentd/pkg-descr exit --- oidentd.port ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200403210517.i2L5HwCh012163>