5f08e609c0
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
113 lines
1.9 KiB
Go
113 lines
1.9 KiB
Go
package continuity
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// TODO(stevvooe): This needs a lot of work before we can call it useful.
|
|
|
|
type groupIndex struct {
|
|
byName map[string]*group
|
|
byGID map[int]*group
|
|
}
|
|
|
|
func getGroupIndex() (*groupIndex, error) {
|
|
f, err := os.Open("/etc/group")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer f.Close()
|
|
|
|
groups, err := parseGroups(f)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return newGroupIndex(groups), nil
|
|
}
|
|
|
|
func newGroupIndex(groups []group) *groupIndex {
|
|
gi := &groupIndex{
|
|
byName: make(map[string]*group),
|
|
byGID: make(map[int]*group),
|
|
}
|
|
|
|
for i, group := range groups {
|
|
gi.byGID[group.gid] = &groups[i]
|
|
gi.byName[group.name] = &groups[i]
|
|
}
|
|
|
|
return gi
|
|
}
|
|
|
|
type group struct {
|
|
name string
|
|
gid int
|
|
members []string
|
|
}
|
|
|
|
func getGroupName(gid int) (string, error) {
|
|
f, err := os.Open("/etc/group")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer f.Close()
|
|
|
|
groups, err := parseGroups(f)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
for _, group := range groups {
|
|
if group.gid == gid {
|
|
return group.name, nil
|
|
}
|
|
}
|
|
|
|
return "", fmt.Errorf("no group for gid")
|
|
}
|
|
|
|
// parseGroups parses an /etc/group file for group names, ids and membership.
|
|
// This is unix specific.
|
|
func parseGroups(rd io.Reader) ([]group, error) {
|
|
var groups []group
|
|
scanner := bufio.NewScanner(rd)
|
|
|
|
for scanner.Scan() {
|
|
if strings.HasPrefix(scanner.Text(), "#") {
|
|
continue // skip comment
|
|
}
|
|
|
|
parts := strings.SplitN(scanner.Text(), ":", 4)
|
|
|
|
if len(parts) != 4 {
|
|
return nil, fmt.Errorf("bad entry: %q", scanner.Text())
|
|
}
|
|
|
|
name, _, sgid, smembers := parts[0], parts[1], parts[2], parts[3]
|
|
|
|
gid, err := strconv.Atoi(sgid)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("bad gid: %q", gid)
|
|
}
|
|
|
|
members := strings.Split(smembers, ",")
|
|
|
|
groups = append(groups, group{
|
|
name: name,
|
|
gid: gid,
|
|
members: members,
|
|
})
|
|
}
|
|
|
|
if scanner.Err() != nil {
|
|
return nil, scanner.Err()
|
|
}
|
|
|
|
return groups, nil
|
|
}
|