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