github.com/dctrud/umoci@v0.4.3-0.20191016193643-05a1d37de015/third_party/user/lookup.go (about) 1 /* 2 * Imported from opencontainers/runc/libcontainer/user. 3 * Copyright (C) 2014 Docker, Inc. 4 * Copyright (C) The Linux Foundation 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package user 20 21 import ( 22 "errors" 23 "syscall" 24 ) 25 26 var ( 27 // The current operating system does not provide the required data for user lookups. 28 ErrUnsupported = errors.New("user lookup: operating system does not provide passwd-formatted data") 29 // No matching entries found in file. 30 ErrNoPasswdEntries = errors.New("no matching entries in passwd file") 31 ErrNoGroupEntries = errors.New("no matching entries in group file") 32 ) 33 34 func lookupUser(filter func(u User) bool) (User, error) { 35 // Get operating system-specific passwd reader-closer. 36 passwd, err := GetPasswd() 37 if err != nil { 38 return User{}, err 39 } 40 defer passwd.Close() 41 42 // Get the users. 43 users, err := ParsePasswdFilter(passwd, filter) 44 if err != nil { 45 return User{}, err 46 } 47 48 // No user entries found. 49 if len(users) == 0 { 50 return User{}, ErrNoPasswdEntries 51 } 52 53 // Assume the first entry is the "correct" one. 54 return users[0], nil 55 } 56 57 // CurrentUser looks up the current user by their user id in /etc/passwd. If the 58 // user cannot be found (or there is no /etc/passwd file on the filesystem), 59 // then CurrentUser returns an error. 60 func CurrentUser() (User, error) { 61 return LookupUid(syscall.Getuid()) 62 } 63 64 // LookupUser looks up a user by their username in /etc/passwd. If the user 65 // cannot be found (or there is no /etc/passwd file on the filesystem), then 66 // LookupUser returns an error. 67 func LookupUser(username string) (User, error) { 68 return lookupUser(func(u User) bool { 69 return u.Name == username 70 }) 71 } 72 73 // LookupUid looks up a user by their user id in /etc/passwd. If the user cannot 74 // be found (or there is no /etc/passwd file on the filesystem), then LookupId 75 // returns an error. 76 func LookupUid(uid int) (User, error) { 77 return lookupUser(func(u User) bool { 78 return u.Uid == uid 79 }) 80 } 81 82 func lookupGroup(filter func(g Group) bool) (Group, error) { 83 // Get operating system-specific group reader-closer. 84 group, err := GetGroup() 85 if err != nil { 86 return Group{}, err 87 } 88 defer group.Close() 89 90 // Get the users. 91 groups, err := ParseGroupFilter(group, filter) 92 if err != nil { 93 return Group{}, err 94 } 95 96 // No user entries found. 97 if len(groups) == 0 { 98 return Group{}, ErrNoGroupEntries 99 } 100 101 // Assume the first entry is the "correct" one. 102 return groups[0], nil 103 } 104 105 // CurrentGroup looks up the current user's group by their primary group id's 106 // entry in /etc/passwd. If the group cannot be found (or there is no 107 // /etc/group file on the filesystem), then CurrentGroup returns an error. 108 func CurrentGroup() (Group, error) { 109 return LookupGid(syscall.Getgid()) 110 } 111 112 // LookupGroup looks up a group by its name in /etc/group. If the group cannot 113 // be found (or there is no /etc/group file on the filesystem), then LookupGroup 114 // returns an error. 115 func LookupGroup(groupname string) (Group, error) { 116 return lookupGroup(func(g Group) bool { 117 return g.Name == groupname 118 }) 119 } 120 121 // LookupGid looks up a group by its group id in /etc/group. If the group cannot 122 // be found (or there is no /etc/group file on the filesystem), then LookupGid 123 // returns an error. 124 func LookupGid(gid int) (Group, error) { 125 return lookupGroup(func(g Group) bool { 126 return g.Gid == gid 127 }) 128 }