Skip to content

Commit 144f937

Browse files
Only report user info from API
1 parent decaaff commit 144f937

4 files changed

Lines changed: 203 additions & 43 deletions

File tree

auth.go

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,58 @@ import (
77
"fmt"
88
"io/ioutil"
99
"net/http"
10+
"os"
1011
"time"
1112
)
1213

13-
const userID = 1337
14-
const groupID = 100
14+
const baseUserUID = 2000
15+
const GroupID = 100 // users
1516

1617
type User struct {
1718
Admin bool `json:"is_staff"`
1819
Email string `json:"email"`
19-
ID int `json:"id"`
20+
ID uint `json:"id"`
21+
UID uint `json:"uid"`
2022
Username string `json:"username"`
2123
}
2224

2325
func (u User) GetPasswdLine() []byte {
24-
return []byte(fmt.Sprintf("%s:x:%d:%d::/home/%s:/bin/bash\n", u.Username, userID, groupID, u.Username))
26+
return []byte(fmt.Sprintf("%s:x:%d:%d::/home/%s:/bin/bash\n", u.Username, u.UID, GroupID, u.Username))
2527
}
2628

2729
type TokenUser struct {
2830
Token string `json:"token"`
2931
User User `json:"user"`
3032
}
3133

34+
func (t TokenUser) WriteTokenFile() error {
35+
if _, err := os.Stat(AppConfig.TokenFile); os.IsNotExist(err) {
36+
return ioutil.WriteFile(AppConfig.TokenFile, []byte(t.Token), 0644)
37+
}
38+
return nil
39+
}
40+
41+
func (u User) WriteUserFile() error {
42+
data, _ := json.MarshalIndent(u, "", " ")
43+
if _, err := os.Stat(AppConfig.UserFile); os.IsNotExist(err) {
44+
return ioutil.WriteFile(AppConfig.UserFile, data, 0644)
45+
}
46+
return nil
47+
}
48+
49+
func (u *User) ReadUserFile() error {
50+
data, err := ioutil.ReadFile(AppConfig.UserFile)
51+
if err != nil {
52+
return err
53+
}
54+
55+
if err := json.Unmarshal(data, u); err != nil {
56+
return err
57+
}
58+
59+
return nil
60+
}
61+
3262
var backoffSchedule = []time.Duration{
3363
1 * time.Second,
3464
3 * time.Second,
@@ -99,6 +129,7 @@ func Authenticate(user, password string) (*TokenUser, error) {
99129
if err != nil {
100130
return nil, err
101131
}
132+
tokenUser.User.UID = tokenUser.User.ID + baseUserUID
102133

103134
return &tokenUser, nil
104135
}

nss-https/main.go

Lines changed: 157 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
package main
22

33
import (
4+
"encoding/csv"
45
"fmt"
6+
"os"
7+
"strconv"
58

69
. "github.com/protosam/go-libnss"
710
. "github.com/protosam/go-libnss/structs"
811

912
humcommon "github.com/xeedio/linux-https-user-management"
1013
)
1114

12-
const httpsRemoteUserID = 1337
15+
var validGroupNames []string
16+
var groupsById map[uint]string
17+
var groupsByName map[string]uint
1318

14-
var defaultHttpsRemoteUser Passwd
15-
16-
// We're creating a struct that implements LIBNSS stub methods.
19+
// We're creating a struct that implements HTTPSRemoteUserImpl stub methods.
1720
type HTTPSRemoteUserImpl struct {
1821
LIBNSS
1922
}
@@ -24,14 +27,20 @@ func (self HTTPSRemoteUserImpl) PasswdByName(name string) (Status, Passwd) {
2427
humcommon.Log().Info("Exit early due to config error")
2528
return StatusNotfound, Passwd{}
2629
}
30+
2731
humcommon.Log().Infof("PasswordByName: %s", name)
32+
user := &humcommon.User{}
33+
if err := user.ReadUserFile(); err != nil {
34+
humcommon.Log().Infof("Can't get user info: %v", err)
35+
return StatusNotfound, Passwd{}
36+
}
37+
2838
entry := Passwd{
29-
Username: name,
39+
Username: user.Username,
3040
Password: "x",
31-
UID: httpsRemoteUserID,
32-
GID: 100, // users
33-
Gecos: "HTTPS Remote User",
34-
Dir: fmt.Sprintf("/home/%s", name),
41+
UID: user.UID,
42+
GID: humcommon.GroupID, // users
43+
Dir: fmt.Sprintf("/home/%s", user.Username),
3544
Shell: "/bin/bash",
3645
}
3746
return StatusSuccess, entry
@@ -43,11 +52,27 @@ func (self HTTPSRemoteUserImpl) PasswdByUid(uid uint) (Status, Passwd) {
4352
humcommon.Log().Info("Exit early due to config error")
4453
return StatusNotfound, Passwd{}
4554
}
55+
4656
humcommon.Log().Infof("PasswordByUid: %d", uid)
47-
if uid == httpsRemoteUserID {
48-
return StatusSuccess, defaultHttpsRemoteUser
57+
user := &humcommon.User{}
58+
if err := user.ReadUserFile(); err != nil {
59+
humcommon.Log().Infof("Can't get user info: %v", err)
60+
return StatusNotfound, Passwd{}
61+
}
62+
63+
if uid != user.UID {
64+
return StatusNotfound, Passwd{}
65+
}
66+
67+
entry := Passwd{
68+
Username: user.Username,
69+
Password: "x",
70+
UID: user.UID,
71+
GID: 100, // users
72+
Dir: fmt.Sprintf("/home/%s", user.Username),
73+
Shell: "/bin/bash",
4974
}
50-
return StatusNotfound, Passwd{}
75+
return StatusSuccess, entry
5176
}
5277

5378
func (self HTTPSRemoteUserImpl) ShadowByName(name string) (Status, Shadow) {
@@ -70,15 +95,127 @@ func (self HTTPSRemoteUserImpl) ShadowByName(name string) (Status, Shadow) {
7095
return StatusSuccess, entry
7196
}
7297

98+
func (self HTTPSRemoteUserImpl) GroupAll() (Status, []Group) {
99+
if humcommon.ConfigError {
100+
humcommon.Log().Info("Exit early due to config error")
101+
return StatusNotfound, []Group{}
102+
}
103+
104+
user := &humcommon.User{}
105+
if err := user.ReadUserFile(); err != nil {
106+
humcommon.Log().Infof("Can't get user info: %v", err)
107+
return StatusNotfound, []Group{}
108+
}
109+
110+
groupList := make([]Group, 0)
111+
for groupName, groupId := range groupsByName {
112+
groupList = append(groupList, Group{
113+
Groupname: groupName,
114+
Password: "x",
115+
GID: groupId,
116+
Members: []string{user.Username},
117+
},
118+
)
119+
}
120+
121+
return StatusSuccess, groupList
122+
}
123+
124+
func (self HTTPSRemoteUserImpl) GroupByName(name string) (Status, Group) {
125+
if humcommon.ConfigError {
126+
humcommon.Log().Info("Exit early due to config error")
127+
return StatusNotfound, Group{}
128+
}
129+
130+
user := &humcommon.User{}
131+
if err := user.ReadUserFile(); err != nil {
132+
humcommon.Log().Infof("Can't get user info: %v", err)
133+
return StatusNotfound, Group{}
134+
}
135+
136+
if !isValidGroup(name) {
137+
return StatusNotfound, Group{}
138+
}
139+
140+
return StatusSuccess, Group{
141+
Groupname: name,
142+
Password: "x",
143+
GID: groupsByName[name],
144+
Members: []string{user.Username},
145+
}
146+
}
147+
148+
func (self HTTPSRemoteUserImpl) GroupByGid(gid uint) (Status, Group) {
149+
if humcommon.ConfigError {
150+
humcommon.Log().Info("Exit early due to config error")
151+
return StatusNotfound, Group{}
152+
}
153+
154+
user := &humcommon.User{}
155+
if err := user.ReadUserFile(); err != nil {
156+
humcommon.Log().Infof("Can't get user info: %v", err)
157+
return StatusNotfound, Group{}
158+
}
159+
160+
if _, ok := groupsById[gid]; !ok {
161+
return StatusNotfound, Group{}
162+
}
163+
164+
return StatusSuccess, Group{
165+
Groupname: groupsById[gid],
166+
Password: "x",
167+
GID: gid,
168+
Members: []string{user.Username},
169+
}
170+
}
171+
172+
func parseEtcGroup() error {
173+
groupFile, err := os.Open("/etc/group")
174+
if err != nil {
175+
humcommon.Log().Warnf("Error opening groups: %v", err)
176+
return err
177+
}
178+
defer groupFile.Close()
179+
180+
r := csv.NewReader(groupFile)
181+
r.Comma = ':'
182+
r.Comment = '#'
183+
184+
for {
185+
record, err := r.Read()
186+
if record == nil || err != nil {
187+
break
188+
}
189+
groupName := record[0]
190+
if isValidGroup(groupName) {
191+
groupId, _ := strconv.Atoi(record[2])
192+
uGroupId := uint(groupId)
193+
groupsById[uGroupId] = groupName
194+
groupsByName[groupName] = uGroupId
195+
}
196+
}
197+
198+
return nil
199+
}
200+
201+
func isValidGroup(groupName string) bool {
202+
for _, testGroup := range validGroupNames {
203+
if testGroup == groupName {
204+
return true
205+
}
206+
}
207+
208+
return false
209+
}
210+
73211
func init() {
74-
defaultHttpsRemoteUser = Passwd{
75-
Username: "remoteuser",
76-
Password: "x",
77-
UID: httpsRemoteUserID,
78-
GID: 100, // users
79-
Gecos: "HTTPS Remote User",
80-
Dir: "/home/remoteuser",
81-
Shell: "/bin/bash",
212+
validGroupNames = append(validGroupNames, "adm", "cdrom", "sudo", "plugdev", "lpadmin")
213+
214+
groupsById = make(map[uint]string)
215+
groupsByName = make(map[string]uint)
216+
217+
if err := parseEtcGroup(); err != nil {
218+
humcommon.Log().Warnf("Unable to parse etc group: %v", err)
82219
}
83220

84221
// We set our implementation to "HTTPSRemoteUserImpl", so that go-libnss will use the methods we create

nss-https/nss_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func TestPasswdByName(t *testing.T) {
1414
}
1515

1616
func TestPasswdByUidBad(t *testing.T) {
17-
status, _ := HTTPSRemoteUserImpl{}.PasswdByUid(httpsRemoteUserID)
17+
status, _ := HTTPSRemoteUserImpl{}.PasswdByUid(2001)
1818
assert.Equal(t, nss.Status(0), status, "Expected success")
1919
}
2020

@@ -27,3 +27,11 @@ func TestShadowByName(t *testing.T) {
2727
status, _ := HTTPSRemoteUserImpl{}.ShadowByName("user0")
2828
assert.Equal(t, nss.Status(0), status, "Expected success")
2929
}
30+
31+
func TestParseEtcGroup(t *testing.T) {
32+
if err := parseEtcGroup(); err != nil {
33+
t.Errorf("Error parsing etc group: %v", err)
34+
}
35+
t.Logf("GroupsById: %+v", groupsById)
36+
t.Logf("GroupsByName: %+v", groupsByName)
37+
}

pam-https/main.go

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package main
22

33
import (
44
"bytes"
5-
"encoding/json"
65
"io/ioutil"
76
"os"
87

@@ -65,11 +64,11 @@ func (mp *mypam) Authenticate(hdl pam.Handle, args pam.Args) pam.Value {
6564
humcommon.Log().Warnf("Error appending passwd file: %v", err)
6665
return pam.AuthInfoUnavailable
6766
}
68-
if err := writeTokenFile(tokenUser.Token); err != nil {
67+
if err := tokenUser.WriteTokenFile(); err != nil {
6968
humcommon.Log().Warnf("Error writing token file: %v", err)
7069
return pam.AuthInfoUnavailable
7170
}
72-
if err := writeUserFile(tokenUser.User); err != nil {
71+
if err := tokenUser.User.WriteUserFile(); err != nil {
7372
humcommon.Log().Warnf("Error writing user file: %v", err)
7473
return pam.AuthInfoUnavailable
7574
}
@@ -79,21 +78,6 @@ func (mp *mypam) Authenticate(hdl pam.Handle, args pam.Args) pam.Value {
7978
return pam.PermissionDenied
8079
}
8180

82-
func writeTokenFile(token string) error {
83-
if _, err := os.Stat(humcommon.AppConfig.TokenFile); os.IsNotExist(err) {
84-
return ioutil.WriteFile(humcommon.AppConfig.TokenFile, []byte(token), 0644)
85-
}
86-
return nil
87-
}
88-
89-
func writeUserFile(user humcommon.User) error {
90-
data, _ := json.MarshalIndent(user, "", " ")
91-
if _, err := os.Stat(humcommon.AppConfig.UserFile); os.IsNotExist(err) {
92-
return ioutil.WriteFile(humcommon.AppConfig.UserFile, data, 0644)
93-
}
94-
return nil
95-
}
96-
9781
func fileContains(line []byte, filePath string) (bool, error) {
9882
data, err := ioutil.ReadFile(filePath)
9983
if err != nil {

0 commit comments

Comments
 (0)