diff --git a/unix/mkerrors.sh b/unix/mkerrors.sh index b8313e98..ca98cb48 100755 --- a/unix/mkerrors.sh +++ b/unix/mkerrors.sh @@ -65,6 +65,7 @@ includes_Darwin=' #include #include #include +#include #include #include #include @@ -480,7 +481,7 @@ ccflags="$@" $2 ~ /^LOCK_(SH|EX|NB|UN)$/ || $2 ~ /^LO_(KEY|NAME)_SIZE$/ || $2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ || - $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|MCAST|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ || + $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|MCAST|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL)_/ || $2 ~ /^TP_STATUS_/ || $2 ~ /^FALLOC_/ || $2 == "ICMPV6_FILTER" || diff --git a/unix/syscall_darwin.go b/unix/syscall_darwin.go index 16f9c226..9276fcb1 100644 --- a/unix/syscall_darwin.go +++ b/unix/syscall_darwin.go @@ -378,6 +378,15 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e return } +// GetsockoptXucred is a getsockopt wrapper that returns an Xucred struct. +// The usual level and opt are SOL_LOCAL and LOCAL_PEERCRED, respectively. +func GetsockoptXucred(fd, level, opt int) (*Xucred, error) { + x := new(Xucred) + vallen := _Socklen(unsafe.Sizeof(Xucred{})) + err := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen) + return x, err +} + //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) /* diff --git a/unix/syscall_darwin_test.go b/unix/syscall_darwin_test.go index d9f10139..aeefd537 100644 --- a/unix/syscall_darwin_test.go +++ b/unix/syscall_darwin_test.go @@ -7,8 +7,10 @@ package unix_test import ( "bytes" "io/ioutil" + "net" "os" "path" + "syscall" "testing" "golang.org/x/sys/unix" @@ -217,3 +219,37 @@ func TestFcntlFstore(t *testing.T) { } } + +func TestGetsockoptXucred(t *testing.T) { + fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0) + if err != nil { + t.Fatalf("Socketpair: %v", err) + } + defer syscall.Close(fds[0]) + defer syscall.Close(fds[1]) + + srvFile := os.NewFile(uintptr(fds[0]), "server") + defer srvFile.Close() + srv, err := net.FileConn(srvFile) + if err != nil { + t.Fatalf("FileConn: %v", err) + } + defer srv.Close() + + cliFile := os.NewFile(uintptr(fds[1]), "client") + defer cliFile.Close() + cli, err := net.FileConn(cliFile) + if err != nil { + t.Fatalf("FileConn: %v", err) + } + defer cli.Close() + + cred, err := unix.GetsockoptXucred(fds[1], unix.SOL_LOCAL, unix.LOCAL_PEERCRED) + if err != nil { + t.Fatal(err) + } + t.Logf("got: %+v", cred) + if got, want := cred.Uid, os.Getuid(); int(got) != int(want) { + t.Errorf("uid = %v; want %v", got, want) + } +} diff --git a/unix/types_darwin.go b/unix/types_darwin.go index 71ada9e1..1796a07a 100644 --- a/unix/types_darwin.go +++ b/unix/types_darwin.go @@ -38,6 +38,7 @@ package unix #include #include #include +#include #include #include #include @@ -150,6 +151,8 @@ type RawSockaddrCtl C.struct_sockaddr_ctl type _Socklen C.socklen_t +type Xucred C.struct_xucred + type Linger C.struct_linger type Iovec C.struct_iovec @@ -177,6 +180,7 @@ const ( SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl SizeofSockaddrCtl = C.sizeof_struct_sockaddr_ctl + SizeofXucred = C.sizeof_struct_xucred SizeofLinger = C.sizeof_struct_linger SizeofIovec = C.sizeof_struct_iovec SizeofIPMreq = C.sizeof_struct_ip_mreq diff --git a/unix/zerrors_darwin_amd64.go b/unix/zerrors_darwin_amd64.go index 10d966a3..dcb96c26 100644 --- a/unix/zerrors_darwin_amd64.go +++ b/unix/zerrors_darwin_amd64.go @@ -902,6 +902,12 @@ const ( KERN_OSRELEASE = 0x2 KERN_OSTYPE = 0x1 KERN_VERSION = 0x4 + LOCAL_PEERCRED = 0x1 + LOCAL_PEEREPID = 0x3 + LOCAL_PEEREUUID = 0x5 + LOCAL_PEERPID = 0x2 + LOCAL_PEERTOKEN = 0x6 + LOCAL_PEERUUID = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 @@ -1309,6 +1315,7 @@ const ( SOCK_RDM = 0x4 SOCK_SEQPACKET = 0x5 SOCK_STREAM = 0x1 + SOL_LOCAL = 0x0 SOL_SOCKET = 0xffff SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x2 diff --git a/unix/zerrors_darwin_arm64.go b/unix/zerrors_darwin_arm64.go index 462e8cf7..8602b136 100644 --- a/unix/zerrors_darwin_arm64.go +++ b/unix/zerrors_darwin_arm64.go @@ -902,6 +902,12 @@ const ( KERN_OSRELEASE = 0x2 KERN_OSTYPE = 0x1 KERN_VERSION = 0x4 + LOCAL_PEERCRED = 0x1 + LOCAL_PEEREPID = 0x3 + LOCAL_PEEREUUID = 0x5 + LOCAL_PEERPID = 0x2 + LOCAL_PEERTOKEN = 0x6 + LOCAL_PEERUUID = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 @@ -1309,6 +1315,7 @@ const ( SOCK_RDM = 0x4 SOCK_SEQPACKET = 0x5 SOCK_STREAM = 0x1 + SOL_LOCAL = 0x0 SOL_SOCKET = 0xffff SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x2 diff --git a/unix/ztypes_darwin_amd64.go b/unix/ztypes_darwin_amd64.go index 080ffce3..bb39542f 100644 --- a/unix/ztypes_darwin_amd64.go +++ b/unix/ztypes_darwin_amd64.go @@ -210,6 +210,13 @@ type RawSockaddrCtl struct { type _Socklen uint32 +type Xucred struct { + Version uint32 + Uid uint32 + Ngroups int16 + Groups [16]uint32 +} + type Linger struct { Onoff int32 Linger int32 @@ -273,6 +280,7 @@ const ( SizeofSockaddrUnix = 0x6a SizeofSockaddrDatalink = 0x14 SizeofSockaddrCtl = 0x20 + SizeofXucred = 0x4c SizeofLinger = 0x8 SizeofIovec = 0x10 SizeofIPMreq = 0x8 diff --git a/unix/ztypes_darwin_arm64.go b/unix/ztypes_darwin_arm64.go index c9492428..ec5b5592 100644 --- a/unix/ztypes_darwin_arm64.go +++ b/unix/ztypes_darwin_arm64.go @@ -210,6 +210,13 @@ type RawSockaddrCtl struct { type _Socklen uint32 +type Xucred struct { + Version uint32 + Uid uint32 + Ngroups int16 + Groups [16]uint32 +} + type Linger struct { Onoff int32 Linger int32 @@ -273,6 +280,7 @@ const ( SizeofSockaddrUnix = 0x6a SizeofSockaddrDatalink = 0x14 SizeofSockaddrCtl = 0x20 + SizeofXucred = 0x4c SizeofLinger = 0x8 SizeofIovec = 0x10 SizeofIPMreq = 0x8