Initial Commit
This commit is contained in:
69
loginshell/loginshell.go
Normal file
69
loginshell/loginshell.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package loginshell
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"io/fs"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrInvalidPasswd is returned when the passwd file is invalid and can't be parsed
|
||||
ErrInvalidPasswd = errors.New("loginshell: invalid passwd file")
|
||||
|
||||
// ErrNoSuchUser is returned when a given user isn't in the passwd file
|
||||
ErrNoSuchUser = errors.New("loginshell: provided uid not found in passwd file")
|
||||
|
||||
// ErrUnsupported is returned on unsupported platforms, such as Windows
|
||||
ErrUnsupported = errors.New("loginshell: unsupported platform")
|
||||
)
|
||||
|
||||
// Get returns the login shell belonging to the provided uid by parsing the passwd file.
|
||||
// If uid is less than zero, the current uid will be used instead.
|
||||
func Get(uid int) (string, error) {
|
||||
if uid < 0 {
|
||||
uid = os.Getuid()
|
||||
}
|
||||
|
||||
// os.Getuid returns -1 on unsupported platforms
|
||||
if uid == -1 {
|
||||
return "", ErrUnsupported
|
||||
}
|
||||
|
||||
fl, err := os.Open("/etc/passwd")
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return "", ErrUnsupported
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer fl.Close()
|
||||
|
||||
s := bufio.NewScanner(fl)
|
||||
for s.Scan() {
|
||||
luid, shell, err := parsePasswdLine(s.Text())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if luid == uid {
|
||||
return shell, nil
|
||||
}
|
||||
}
|
||||
if err := s.Err(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "", ErrNoSuchUser
|
||||
}
|
||||
|
||||
func parsePasswdLine(line string) (int, string, error) {
|
||||
sline := strings.Split(line, ":")
|
||||
if len(sline) < 7 {
|
||||
return 0, "", ErrInvalidPasswd
|
||||
}
|
||||
uid, err := strconv.Atoi(sline[2])
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
return uid, sline[6], nil
|
||||
}
|
||||
Reference in New Issue
Block a user