github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/common/group.go (about) 1 // Copyright 2015 The rkt Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package common 16 17 import ( 18 "bufio" 19 "fmt" 20 "io" 21 "os" 22 "strconv" 23 "strings" 24 ) 25 26 const ( 27 groupFilePath = "/etc/group" 28 RktGroup = "rkt" 29 ) 30 31 // Group represents an entry in the group file. 32 type Group struct { 33 Name string 34 Pass string 35 Gid int 36 Users []string 37 } 38 39 // LookupGid reads the group file and returns the gid of the group 40 // specified by groupName. 41 func LookupGid(groupName string) (gid int, err error) { 42 groups, err := parseGroupFile(groupFilePath) 43 if err != nil { 44 return -1, fmt.Errorf("error parsing %q file: %v", groupFilePath, err) 45 } 46 47 group, ok := groups[groupName] 48 if !ok { 49 return -1, fmt.Errorf("%q group not found", groupName) 50 } 51 52 return group.Gid, nil 53 } 54 55 func parseGroupFile(path string) (group map[string]Group, err error) { 56 groupFile, err := os.Open(path) 57 if err != nil { 58 return nil, err 59 } 60 defer groupFile.Close() 61 62 return parseGroups(groupFile) 63 } 64 65 func parseGroups(r io.Reader) (group map[string]Group, err error) { 66 s := bufio.NewScanner(r) 67 out := make(map[string]Group) 68 69 for s.Scan() { 70 if err := s.Err(); err != nil { 71 return nil, err 72 } 73 74 text := s.Text() 75 if text == "" { 76 continue 77 } 78 79 p := Group{} 80 parseGroupLine(text, &p) 81 82 out[p.Name] = p 83 } 84 85 return out, nil 86 } 87 88 func parseGroupLine(line string, group *Group) { 89 const ( 90 NameIdx = iota 91 PassIdx 92 GidIdx 93 UsersIdx 94 ) 95 96 if line == "" { 97 return 98 } 99 100 splits := strings.Split(line, ":") 101 if len(splits) < 4 { 102 return 103 } 104 105 group.Name = splits[NameIdx] 106 group.Pass = splits[PassIdx] 107 group.Gid, _ = strconv.Atoi(splits[GidIdx]) 108 109 u := splits[UsersIdx] 110 if u != "" { 111 group.Users = strings.Split(u, ",") 112 } else { 113 group.Users = []string{} 114 } 115 }