github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/user/lookup.go (about)

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