|
1 | 1 | //go:build !windows
|
2 | 2 |
|
3 |
| -package idtools // import "github.com/docker/docker/pkg/idtools" |
| 3 | +package idtools |
4 | 4 |
|
5 | 5 | import (
|
6 |
| - "bytes" |
7 | 6 | "fmt"
|
8 |
| - "io" |
9 | 7 | "os"
|
10 |
| - "os/exec" |
11 | 8 | "path/filepath"
|
12 | 9 | "strconv"
|
13 | 10 | "syscall"
|
@@ -72,127 +69,25 @@ func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting
|
72 | 69 | return nil
|
73 | 70 | }
|
74 | 71 |
|
75 |
| -// LookupUser uses traditional local system files lookup (from libcontainer/user) on a username, |
76 |
| -// followed by a call to `getent` for supporting host configured non-files passwd and group dbs |
| 72 | +// LookupUser uses traditional local system files lookup (from libcontainer/user) on a username |
| 73 | +// |
| 74 | +// Deprecated: use [user.LookupUser] instead |
77 | 75 | func LookupUser(name string) (user.User, error) {
|
78 |
| - // first try a local system files lookup using existing capabilities |
79 |
| - usr, err := user.LookupUser(name) |
80 |
| - if err == nil { |
81 |
| - return usr, nil |
82 |
| - } |
83 |
| - // local files lookup failed; attempt to call `getent` to query configured passwd dbs |
84 |
| - usr, err = getentUser(name) |
85 |
| - if err != nil { |
86 |
| - return user.User{}, err |
87 |
| - } |
88 |
| - return usr, nil |
| 76 | + return user.LookupUser(name) |
89 | 77 | }
|
90 | 78 |
|
91 |
| -// LookupUID uses traditional local system files lookup (from libcontainer/user) on a uid, |
92 |
| -// followed by a call to `getent` for supporting host configured non-files passwd and group dbs |
| 79 | +// LookupUID uses traditional local system files lookup (from libcontainer/user) on a uid |
| 80 | +// |
| 81 | +// Deprecated: use [user.LookupUid] instead |
93 | 82 | func LookupUID(uid int) (user.User, error) {
|
94 |
| - // first try a local system files lookup using existing capabilities |
95 |
| - usr, err := user.LookupUid(uid) |
96 |
| - if err == nil { |
97 |
| - return usr, nil |
98 |
| - } |
99 |
| - // local files lookup failed; attempt to call `getent` to query configured passwd dbs |
100 |
| - return getentUser(strconv.Itoa(uid)) |
101 |
| -} |
102 |
| - |
103 |
| -func getentUser(name string) (user.User, error) { |
104 |
| - reader, err := callGetent("passwd", name) |
105 |
| - if err != nil { |
106 |
| - return user.User{}, err |
107 |
| - } |
108 |
| - users, err := user.ParsePasswd(reader) |
109 |
| - if err != nil { |
110 |
| - return user.User{}, err |
111 |
| - } |
112 |
| - if len(users) == 0 { |
113 |
| - return user.User{}, fmt.Errorf("getent failed to find passwd entry for %q", name) |
114 |
| - } |
115 |
| - return users[0], nil |
| 83 | + return user.LookupUid(uid) |
116 | 84 | }
|
117 | 85 |
|
118 | 86 | // LookupGroup uses traditional local system files lookup (from libcontainer/user) on a group name,
|
119 |
| -// followed by a call to `getent` for supporting host configured non-files passwd and group dbs |
| 87 | +// |
| 88 | +// Deprecated: use [user.LookupGroup] instead |
120 | 89 | func LookupGroup(name string) (user.Group, error) {
|
121 |
| - // first try a local system files lookup using existing capabilities |
122 |
| - group, err := user.LookupGroup(name) |
123 |
| - if err == nil { |
124 |
| - return group, nil |
125 |
| - } |
126 |
| - // local files lookup failed; attempt to call `getent` to query configured group dbs |
127 |
| - return getentGroup(name) |
128 |
| -} |
129 |
| - |
130 |
| -// LookupGID uses traditional local system files lookup (from libcontainer/user) on a group ID, |
131 |
| -// followed by a call to `getent` for supporting host configured non-files passwd and group dbs |
132 |
| -func LookupGID(gid int) (user.Group, error) { |
133 |
| - // first try a local system files lookup using existing capabilities |
134 |
| - group, err := user.LookupGid(gid) |
135 |
| - if err == nil { |
136 |
| - return group, nil |
137 |
| - } |
138 |
| - // local files lookup failed; attempt to call `getent` to query configured group dbs |
139 |
| - return getentGroup(strconv.Itoa(gid)) |
140 |
| -} |
141 |
| - |
142 |
| -func getentGroup(name string) (user.Group, error) { |
143 |
| - reader, err := callGetent("group", name) |
144 |
| - if err != nil { |
145 |
| - return user.Group{}, err |
146 |
| - } |
147 |
| - groups, err := user.ParseGroup(reader) |
148 |
| - if err != nil { |
149 |
| - return user.Group{}, err |
150 |
| - } |
151 |
| - if len(groups) == 0 { |
152 |
| - return user.Group{}, fmt.Errorf("getent failed to find groups entry for %q", name) |
153 |
| - } |
154 |
| - return groups[0], nil |
155 |
| -} |
156 |
| - |
157 |
| -func callGetent(database, key string) (io.Reader, error) { |
158 |
| - getentCmd, err := resolveBinary("getent") |
159 |
| - // if no `getent` command within the execution environment, can't do anything else |
160 |
| - if err != nil { |
161 |
| - return nil, fmt.Errorf("unable to find getent command: %w", err) |
162 |
| - } |
163 |
| - command := exec.Command(getentCmd, database, key) |
164 |
| - // we run getent within container filesystem, but without /dev so /dev/null is not available for exec to mock stdin |
165 |
| - command.Stdin = io.NopCloser(bytes.NewReader(nil)) |
166 |
| - out, err := command.CombinedOutput() |
167 |
| - if err != nil { |
168 |
| - exitCode, errC := getExitCode(err) |
169 |
| - if errC != nil { |
170 |
| - return nil, err |
171 |
| - } |
172 |
| - switch exitCode { |
173 |
| - case 1: |
174 |
| - return nil, fmt.Errorf("getent reported invalid parameters/database unknown") |
175 |
| - case 2: |
176 |
| - return nil, fmt.Errorf("getent unable to find entry %q in %s database", key, database) |
177 |
| - case 3: |
178 |
| - return nil, fmt.Errorf("getent database doesn't support enumeration") |
179 |
| - default: |
180 |
| - return nil, err |
181 |
| - } |
182 |
| - } |
183 |
| - return bytes.NewReader(out), nil |
184 |
| -} |
185 |
| - |
186 |
| -// getExitCode returns the ExitStatus of the specified error if its type is |
187 |
| -// exec.ExitError, returns 0 and an error otherwise. |
188 |
| -func getExitCode(err error) (int, error) { |
189 |
| - exitCode := 0 |
190 |
| - if exiterr, ok := err.(*exec.ExitError); ok { |
191 |
| - if procExit, ok := exiterr.Sys().(syscall.WaitStatus); ok { |
192 |
| - return procExit.ExitStatus(), nil |
193 |
| - } |
194 |
| - } |
195 |
| - return exitCode, fmt.Errorf("failed to get exit code") |
| 90 | + return user.LookupGroup(name) |
196 | 91 | }
|
197 | 92 |
|
198 | 93 | // setPermissions performs a chown/chmod only if the uid/gid don't match what's requested
|
@@ -223,7 +118,8 @@ func setPermissions(p string, mode os.FileMode, owner Identity, stat os.FileInfo
|
223 | 118 | // using the data from /etc/sub{uid,gid} ranges, creates the
|
224 | 119 | // proper uid and gid remapping ranges for that user/group pair
|
225 | 120 | func LoadIdentityMapping(name string) (IdentityMapping, error) {
|
226 |
| - usr, err := LookupUser(name) |
| 121 | + // TODO: Consider adding support for calling out to "getent" |
| 122 | + usr, err := user.LookupUser(name) |
227 | 123 | if err != nil {
|
228 | 124 | return IdentityMapping{}, fmt.Errorf("could not get user for username %s: %v", name, err)
|
229 | 125 | }
|
|
0 commit comments