Source file
src/os/user/listgroups_unix.go
1
2
3
4
5
6
7 package user
8
9 import (
10 "bufio"
11 "bytes"
12 "errors"
13 "fmt"
14 "io"
15 "os"
16 "strconv"
17 )
18
19 const groupFile = "/etc/group"
20
21 var colon = []byte{':'}
22
23 func listGroupsFromReader(u *User, r io.Reader) ([]string, error) {
24 if u.Username == "" {
25 return nil, errors.New("user: list groups: empty username")
26 }
27 primaryGid, err := strconv.Atoi(u.Gid)
28 if err != nil {
29 return nil, fmt.Errorf("user: list groups for %s: invalid gid %q", u.Username, u.Gid)
30 }
31
32 userCommas := []byte("," + u.Username + ",")
33 userFirst := userCommas[1:]
34 userLast := userCommas[:len(userCommas)-1]
35 userOnly := userCommas[1 : len(userCommas)-1]
36
37
38 groups := []string{u.Gid}
39
40 rd := bufio.NewReader(r)
41 done := false
42 for !done {
43 line, err := rd.ReadBytes('\n')
44 if err != nil {
45 if err == io.EOF {
46 done = true
47 } else {
48 return groups, err
49 }
50 }
51
52
53
54
55
56
57
58 line = bytes.TrimSpace(line)
59 if len(line) == 0 || line[0] == '#' ||
60
61
62
63 line[0] == '+' || line[0] == '-' {
64 continue
65 }
66
67
68
69
70
71
72 listIdx := bytes.LastIndexByte(line, ':')
73 if listIdx == -1 || listIdx == len(line)-1 {
74
75 continue
76 }
77 if bytes.Count(line[:listIdx], colon) != 2 {
78
79 continue
80 }
81 list := line[listIdx+1:]
82
83 if !(bytes.Equal(list, userOnly) || bytes.HasPrefix(list, userFirst) || bytes.HasSuffix(list, userLast) || bytes.Contains(list, userCommas)) {
84 continue
85 }
86
87
88 parts := bytes.Split(line[:listIdx], colon)
89 if len(parts) != 3 || len(parts[0]) == 0 {
90 continue
91 }
92 gid := string(parts[2])
93
94 numGid, err := strconv.Atoi(gid)
95 if err != nil || numGid == primaryGid {
96 continue
97 }
98
99 groups = append(groups, gid)
100 }
101
102 return groups, nil
103 }
104
105 func listGroups(u *User) ([]string, error) {
106 f, err := os.Open(groupFile)
107 if err != nil {
108 return nil, err
109 }
110 defer f.Close()
111
112 return listGroupsFromReader(u, f)
113 }
114
View as plain text