code.flowtr.dev/mirrors/u-root@v1.0.0/cmds/which/which_unix.go (about)

     1  // Copyright 2016-2017 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
     6  
     7  package main
     8  
     9  import (
    10  	"os"
    11  
    12  	"golang.org/x/sys/unix"
    13  )
    14  
    15  var (
    16  	// Effective UID and GID. Technically, Linux checks the fsuid and
    17  	// fsgid. But those are in 99.999% of cases the same as EUID and EGID.
    18  	// Nobody uses that moldy stuff anymore.
    19  	eUID = uint32(os.Geteuid())
    20  	eGID = uint32(os.Getegid())
    21  )
    22  
    23  func stat(path string) (unix.Stat_t, error) {
    24  	var s unix.Stat_t
    25  	if err := unix.Stat(path, &s); err != nil {
    26  		return unix.Stat_t{}, err
    27  	}
    28  	return s, nil
    29  }
    30  
    31  // Execute permission bits.
    32  const (
    33  	otherExec = 1
    34  	groupExec = 1 << 3
    35  	userExec  = 1 << 6
    36  )
    37  
    38  func canExecute(path string) bool {
    39  	info, err := stat(path)
    40  	if err != nil {
    41  		return false
    42  	}
    43  
    44  	// This is a... first-order approximation.
    45  	//
    46  	// Somebody should write a Go capabilities library. Then we can check
    47  	// CAP_DAC_OVERRIDE. Probably not really necessary, though. Who has
    48  	// Unix shell users with select capabilities? Hopefully nobody.
    49  	if eUID == 0 {
    50  		return true
    51  	} else if info.Uid == eUID {
    52  		return info.Mode&userExec == userExec
    53  	} else if info.Gid == eGID {
    54  		return info.Mode&groupExec == groupExec
    55  	}
    56  	return info.Mode&otherExec == otherExec
    57  }