forked from kubernetes/kops
-
Notifications
You must be signed in to change notification settings - Fork 0
/
users.go
152 lines (134 loc) · 3.16 KB
/
users.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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package fi
import (
"fmt"
"github.com/golang/glog"
"io/ioutil"
"strconv"
"strings"
)
// This file parses /etc/passwd and /etc/group to get information about users & groups
// Go has built-in user functionality, and group functionality is merged but not yet released
// TODO: Replace this file with e.g. user.LookupGroup once 42f07ff2679d38a03522db3ccd488f4cc230c8c2 lands in go 1.7
type User struct {
Name string
Uid int
Gid int
Comment string
Home string
Shell string
}
func parseUsers() (map[string]*User, error) {
users := make(map[string]*User)
path := "/etc/passwd"
b, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("error reading user file %q", path)
}
for _, line := range strings.Split(string(b), "\n") {
line = strings.TrimSpace(line)
if line == "" {
continue
}
tokens := strings.Split(line, ":")
if len(tokens) < 7 {
glog.Warning("Ignoring malformed /etc/passwd line (too few tokens): %q", line)
continue
}
uid, err := strconv.Atoi(tokens[2])
if err != nil {
glog.Warning("Ignoring malformed /etc/passwd line (bad uid): %q", line)
continue
}
gid, err := strconv.Atoi(tokens[3])
if err != nil {
glog.Warning("Ignoring malformed /etc/passwd line (bad gid): %q", line)
continue
}
u := &User{
Name: tokens[0],
// Password
Uid: uid,
Gid: gid,
Comment: tokens[4],
Home: tokens[5],
Shell: tokens[6],
}
users[u.Name] = u
}
return users, nil
}
func LookupUser(name string) (*User, error) {
users, err := parseUsers()
if err != nil {
return nil, fmt.Errorf("error reading users: %v", err)
}
return users[name], nil
}
func LookupUserById(uid int) (*User, error) {
users, err := parseUsers()
if err != nil {
return nil, fmt.Errorf("error reading users: %v", err)
}
for _, v := range users {
if v.Uid == uid {
return v, nil
}
}
return nil, nil
}
type Group struct {
Name string
Gid int
//Members []string
}
func parseGroups() (map[string]*Group, error) {
groups := make(map[string]*Group)
path := "/etc/group"
b, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("error reading group file %q", path)
}
for _, line := range strings.Split(string(b), "\n") {
line = strings.TrimSpace(line)
if line == "" {
continue
}
tokens := strings.Split(line, ":")
if len(tokens) < 4 {
glog.Warning("Ignoring malformed /etc/group line (too few tokens): %q", line)
continue
}
gid, err := strconv.Atoi(tokens[2])
if err != nil {
glog.Warning("Ignoring malformed /etc/group line (bad gid): %q", line)
continue
}
g := &Group{
Name: tokens[0],
// Password: tokens[1]
Gid: gid,
// Members: strings.Split(tokens[3], ",")
}
groups[g.Name] = g
}
return groups, nil
}
func LookupGroup(name string) (*Group, error) {
groups, err := parseGroups()
if err != nil {
return nil, fmt.Errorf("error reading groups: %v", err)
}
return groups[name], nil
}
func LookupGroupById(gid int) (*Group, error) {
users, err := parseGroups()
if err != nil {
return nil, fmt.Errorf("error reading groups: %v", err)
}
for _, v := range users {
if v.Gid == gid {
return v, nil
}
}
return nil, nil
}