go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/users/etcpasswd.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package users 5 6 import ( 7 "bufio" 8 "io" 9 "strconv" 10 "strings" 11 12 "github.com/rs/zerolog/log" 13 "go.mondoo.com/cnquery/providers/os/connection/shared" 14 ) 15 16 // a good description of this file is available at: 17 // https://www.cyberciti.biz/faq/understanding-etcpasswd-file-format/ 18 func ParseEtcPasswd(input io.Reader) ([]*User, error) { 19 var users []*User 20 scanner := bufio.NewScanner(input) 21 for scanner.Scan() { 22 line := scanner.Text() 23 24 // check if line starts with # 25 if strings.HasPrefix(strings.TrimSpace(line), "#") { 26 continue 27 } 28 29 m := strings.Split(line, ":") 30 31 if len(m) >= 7 { 32 // parse uid 33 uid, err := strconv.ParseInt(m[2], 10, 0) 34 if err != nil { 35 log.Error().Err(err).Str("user", m[0]).Msg("could not parse uid") 36 } 37 gid, err := strconv.ParseInt(m[3], 10, 0) 38 if err != nil { 39 log.Error().Err(err).Str("user", m[0]).Msg("could not parse gid") 40 } 41 42 // bin:x:1:1:bin:/bin:/sbin/nologin 43 users = append(users, &User{ 44 ID: m[2], 45 Name: m[0], 46 Uid: uid, 47 Gid: gid, 48 Description: m[4], 49 Home: m[5], 50 Shell: m[6], 51 }) 52 } 53 } 54 55 return users, nil 56 } 57 58 type UnixUserManager struct { 59 conn shared.Connection 60 } 61 62 func (s *UnixUserManager) Name() string { 63 return "Unix User Manager" 64 } 65 66 func (s *UnixUserManager) User(id string) (*User, error) { 67 users, err := s.List() 68 if err != nil { 69 return nil, err 70 } 71 72 return findUser(users, id) 73 } 74 75 func (s *UnixUserManager) List() ([]*User, error) { 76 f, err := s.conn.FileSystem().Open("/etc/passwd") 77 if err != nil { 78 return nil, err 79 } 80 defer f.Close() 81 return ParseEtcPasswd(f) 82 }