github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/core/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 }