github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/ipc/ipc_unix.go (about)

     1  //go:build ignore
     2  // +build ignore
     3  
     4  ////go:build !windows && !plan9 && !js
     5  //// +build !windows,!plan9,!js
     6  
     7  package ipc
     8  
     9  import (
    10  	"fmt"
    11  	"net"
    12  
    13  	"golang.org/x/sys/unix"
    14  )
    15  
    16  // Read returns peer credentials using the SO_PEERCRED socket option on
    17  // Unix domain sockets.
    18  //
    19  // On unsupported operating systems it returns an error.
    20  func Read(conn *net.UnixConn) (*Cred, error) {
    21  	raw, err := conn.SyscallConn()
    22  	if err != nil {
    23  		return nil, fmt.Errorf("unable to get raw socket connection: %w", err)
    24  	}
    25  
    26  	var (
    27  		ucred      *unix.Ucred
    28  		sockoptErr error
    29  	)
    30  
    31  	err = raw.Control(func(fd uintptr) {
    32  		ucred, sockoptErr = unix.GetsockoptUcred(
    33  			int(fd),
    34  			unix.SOL_SOCKET,
    35  			unix.SO_PEERCRED,
    36  		)
    37  	})
    38  	if err != nil {
    39  		return nil, fmt.Errorf("unable to get raw socket: %w", err)
    40  	}
    41  
    42  	if sockoptErr != nil {
    43  		return nil, fmt.Errorf("unable to get peer credential: %w", sockoptErr)
    44  	}
    45  
    46  	return &Cred{
    47  		PID: ucred.Pid,
    48  		UID: ucred.Uid,
    49  		GID: ucred.Gid,
    50  	}, nil
    51  }