lookup.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package user
  2. import (
  3. "errors"
  4. "syscall"
  5. )
  6. var (
  7. // The current operating system does not provide the required data for user lookups.
  8. ErrUnsupported = errors.New("user lookup: operating system does not provide passwd-formatted data")
  9. // No matching entries found in file.
  10. ErrNoPasswdEntries = errors.New("no matching entries in passwd file")
  11. ErrNoGroupEntries = errors.New("no matching entries in group file")
  12. )
  13. func lookupUser(filter func(u User) bool) (User, error) {
  14. // Get operating system-specific passwd reader-closer.
  15. passwd, err := GetPasswd()
  16. if err != nil {
  17. return User{}, err
  18. }
  19. defer passwd.Close()
  20. // Get the users.
  21. users, err := ParsePasswdFilter(passwd, filter)
  22. if err != nil {
  23. return User{}, err
  24. }
  25. // No user entries found.
  26. if len(users) == 0 {
  27. return User{}, ErrNoPasswdEntries
  28. }
  29. // Assume the first entry is the "correct" one.
  30. return users[0], nil
  31. }
  32. // CurrentUser looks up the current user by their user id in /etc/passwd. If the
  33. // user cannot be found (or there is no /etc/passwd file on the filesystem),
  34. // then CurrentUser returns an error.
  35. func CurrentUser() (User, error) {
  36. return LookupUid(syscall.Getuid())
  37. }
  38. // LookupUser looks up a user by their username in /etc/passwd. If the user
  39. // cannot be found (or there is no /etc/passwd file on the filesystem), then
  40. // LookupUser returns an error.
  41. func LookupUser(username string) (User, error) {
  42. return lookupUser(func(u User) bool {
  43. return u.Name == username
  44. })
  45. }
  46. // LookupUid looks up a user by their user id in /etc/passwd. If the user cannot
  47. // be found (or there is no /etc/passwd file on the filesystem), then LookupId
  48. // returns an error.
  49. func LookupUid(uid int) (User, error) {
  50. return lookupUser(func(u User) bool {
  51. return u.Uid == uid
  52. })
  53. }
  54. func lookupGroup(filter func(g Group) bool) (Group, error) {
  55. // Get operating system-specific group reader-closer.
  56. group, err := GetGroup()
  57. if err != nil {
  58. return Group{}, err
  59. }
  60. defer group.Close()
  61. // Get the users.
  62. groups, err := ParseGroupFilter(group, filter)
  63. if err != nil {
  64. return Group{}, err
  65. }
  66. // No user entries found.
  67. if len(groups) == 0 {
  68. return Group{}, ErrNoGroupEntries
  69. }
  70. // Assume the first entry is the "correct" one.
  71. return groups[0], nil
  72. }
  73. // CurrentGroup looks up the current user's group by their primary group id's
  74. // entry in /etc/passwd. If the group cannot be found (or there is no
  75. // /etc/group file on the filesystem), then CurrentGroup returns an error.
  76. func CurrentGroup() (Group, error) {
  77. return LookupGid(syscall.Getgid())
  78. }
  79. // LookupGroup looks up a group by its name in /etc/group. If the group cannot
  80. // be found (or there is no /etc/group file on the filesystem), then LookupGroup
  81. // returns an error.
  82. func LookupGroup(groupname string) (Group, error) {
  83. return lookupGroup(func(g Group) bool {
  84. return g.Name == groupname
  85. })
  86. }
  87. // LookupGid looks up a group by its group id in /etc/group. If the group cannot
  88. // be found (or there is no /etc/group file on the filesystem), then LookupGid
  89. // returns an error.
  90. func LookupGid(gid int) (Group, error) {
  91. return lookupGroup(func(g Group) bool {
  92. return g.Gid == gid
  93. })
  94. }