AB#2222 replace unlicensed passwd package with own implementation

This commit is contained in:
Thomas Tendyck 2022-07-25 14:43:02 +02:00 committed by Thomas Tendyck
parent f57a7e3ed0
commit 48d614c959
8 changed files with 75 additions and 32 deletions

View file

@ -162,17 +162,17 @@ func (l *LinuxUserManager) GetLinuxUser(username string) (LinuxUser, error) {
return LinuxUser{}, ErrUserDoesNotExist
}
entry := entries[username]
uid, err := strconv.Atoi(entry.Uid)
uid, err := strconv.Atoi(entry.UID)
if err != nil {
return LinuxUser{}, fmt.Errorf("parsing users uid: %w", err)
}
gid, err := strconv.Atoi(entry.Gid)
gid, err := strconv.Atoi(entry.GID)
if err != nil {
return LinuxUser{}, fmt.Errorf("parsing users gid: %w", err)
}
return LinuxUser{
Username: username,
Home: entry.Home,
Home: entry.Directory,
UID: uid,
GID: gid,
}, nil

View file

@ -1,12 +1,25 @@
package user
import (
"bufio"
"errors"
"strings"
"github.com/spf13/afero"
"github.com/willdonnelly/passwd"
)
// Entries contains the information for each user defined in '/etc/passwd'. Re-exported to allow other module to only import this passwd module.
type Entries map[string]passwd.Entry
// Entry is an entry of a '/etc/passwd' file.
type Entry struct {
Password string
UID string
GID string
GECOS string
Directory string
Shell string
}
// Entries contains the information for each user defined in '/etc/passwd'.
type Entries map[string]Entry
// Passwd allows to parse users from '/etc/passwd' on the local system.
type Passwd struct{}
@ -24,6 +37,26 @@ func (p Passwd) parseFile(fs afero.Fs, path string) (Entries, error) {
}
defer file.Close()
entries, err := passwd.ParseReader(file)
return Entries(entries), err
entries := Entries{}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
// File format: https://man7.org/linux/man-pages/man5/passwd.5.html
fields := strings.Split(scanner.Text(), ":")
if len(fields) != 7 {
return nil, errors.New("invalid number of fields")
}
entries[fields[0]] = Entry{
Password: fields[1],
UID: fields[2],
GID: fields[3],
GECOS: fields[4],
Directory: fields[5],
Shell: fields[6],
}
}
return entries, scanner.Err()
}

View file

@ -22,12 +22,35 @@ func TestParse(t *testing.T) {
createFile: true,
wantEntries: Entries{
"root": {
Pass: "x",
Uid: "0",
Gid: "0",
Gecos: "root",
Home: "/root",
Shell: "/bin/bash",
Password: "x",
UID: "0",
GID: "0",
GECOS: "root",
Directory: "/root",
Shell: "/bin/bash",
},
},
wantErr: false,
},
"multiple lines": {
passwdContents: "root:x:0:0:root:/root:/bin/bash\nfoo:y:1:2:bar:baz:sh",
createFile: true,
wantEntries: Entries{
"root": {
Password: "x",
UID: "0",
GID: "0",
GECOS: "root",
Directory: "/root",
Shell: "/bin/bash",
},
"foo": {
Password: "y",
UID: "1",
GID: "2",
GECOS: "bar",
Directory: "baz",
Shell: "sh",
},
},
wantErr: false,