--- /sys/i386/linux/linux.h.orig Wed Sep 6 20:36:43 2006 +++ /sys/i386/linux/linux.h Wed Sep 6 20:37:15 2006 @@ -615,6 +615,7 @@ #define LINUX_SO_NO_CHECK 11 #define LINUX_SO_PRIORITY 12 #define LINUX_SO_LINGER 13 +#define LINUX_SO_PEERCRED 17 #define LINUX_IP_TOS 1 #define LINUX_IP_TTL 2 --- /sys/alpha/linux/linux.h.orig Sun Oct 3 12:52:08 2004 +++ /sys/alpha/linux/linux.h Thu Sep 7 00:58:26 2006 @@ -447,6 +447,7 @@ #define LINUX_SO_NO_CHECK 11 #define LINUX_SO_PRIORITY 12 #define LINUX_SO_LINGER 13 +#define LINUX_SO_PEERCRED 17 #define LINUX_IP_TOS 1 #define LINUX_IP_TTL 2 --- /sys/amd64/linux32/linux.h.orig Mon Aug 16 09:55:06 2004 +++ /sys/amd64/linux32/linux.h Thu Sep 7 00:58:01 2006 @@ -635,6 +635,7 @@ #define LINUX_SO_NO_CHECK 11 #define LINUX_SO_PRIORITY 12 #define LINUX_SO_LINGER 13 +#define LINUX_SO_PEERCRED 17 #define LINUX_IP_TOS 1 #define LINUX_IP_TTL 2 --- /sys/compat/linux/linux_socket.c.orig Thu Sep 7 01:04:09 2006 +++ /sys/compat/linux/linux_socket.c Thu Sep 7 01:06:29 2006 @@ -27,7 +27,7 @@ */ #include -__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/compat/linux/linux_socket.c,v 1.59.2.1 2006/01/10 10:12:55 glebius Exp $"); +__FBSDID("$FreeBSD: src/sys/compat/linux/linux_socket.c,v 1.59.2.1 2006/01/10 10:12:55 glebius Exp $"); /* XXX we use functions that might not exist. */ #include "opt_compat.h" @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -53,6 +54,7 @@ #include #include #include +#include #include #include @@ -299,6 +301,8 @@ return (SO_OOBINLINE); case LINUX_SO_LINGER: return (SO_LINGER); + case LINUX_SO_PEERCRED: + return (LOCAL_PEERCRED); } return (-1); } @@ -1114,7 +1118,13 @@ caddr_t val; int *avalsize; } */ bsd_args; - int error, name; + struct linux_ucred { + uint32_t pid; + uint32_t uid; + uint32_t gid; + } linux_ucred; + struct xucred xuc; + int error, name, optlen, rc, xuclen; if ((error = copyin(args, &linux_args, sizeof(linux_args)))) return (error); @@ -1136,13 +1146,43 @@ name = -1; break; } - if (name == -1) + if (name == -1) { + log(LOG_WARNING, "LINUX: 'getsockopt' level=0x%04x" + "optname=0x%04x not implemented\n", + linux_args.level, linux_args.optname); return (EINVAL); + }; bsd_args.name = name; - bsd_args.val = PTRIN(linux_args.optval); - bsd_args.avalsize = PTRIN(linux_args.optlen); - return (getsockopt(td, &bsd_args)); + if (bsd_args.level == SOL_SOCKET && name == LOCAL_PEERCRED) { + if ((error = copyin(PTRIN(linux_args.optval), + &linux_ucred, sizeof(linux_ucred)))) + return (error); + if ((error = copyin(PTRIN(linux_args.optlen), + &optlen, sizeof(optlen)))) + return (error); + if (optlen < sizeof(linux_ucred)) + return (EFAULT); + xuclen = sizeof(xuc); + if ((rc = error = kern_getsockopt(td, bsd_args.s, + 0, bsd_args.name, + (caddr_t) &xuc, UIO_SYSSPACE, &xuclen))) + return (error); + if (xuc.cr_version != XUCRED_VERSION) + return (EINVAL); + /* XXX get PID */ + linux_ucred.pid = 0; + linux_ucred.uid = xuc.cr_uid; + linux_ucred.gid = xuc.cr_gid; + if ((error = copyout(&linux_ucred, + PTRIN(linux_args.optval), sizeof(linux_ucred)))) + return (error); + return (rc); + } else { + bsd_args.val = PTRIN(linux_args.optval); + bsd_args.avalsize = PTRIN(linux_args.optlen); + return (getsockopt(td, &bsd_args)); + }; } int