Browse code

Merge pull request #41290 from thaJeztah/getuser_refactor

Simplify getUser() to use libcontainer built-in functionality

Tibor Vass authored on 2020/09/29 09:00:24
Showing 2 changed files
... ...
@@ -12,15 +12,11 @@ import (
12 12
 
13 13
 func (daemon *Daemon) execSetPlatformOpt(c *container.Container, ec *exec.Config, p *specs.Process) error {
14 14
 	if len(ec.User) > 0 {
15
-		uid, gid, additionalGids, err := getUser(c, ec.User)
15
+		var err error
16
+		p.User, err = getUser(c, ec.User)
16 17
 		if err != nil {
17 18
 			return err
18 19
 		}
19
-		p.User = specs.User{
20
-			UID:            uid,
21
-			GID:            gid,
22
-			AdditionalGids: additionalGids,
23
-		}
24 20
 	}
25 21
 	if ec.Privileged {
26 22
 		if p.Capabilities == nil {
... ...
@@ -3,7 +3,6 @@ package daemon // import "github.com/docker/docker/daemon"
3 3
 import (
4 4
 	"context"
5 5
 	"fmt"
6
-	"io"
7 6
 	"io/ioutil"
8 7
 	"os"
9 8
 	"os/exec"
... ...
@@ -171,64 +170,42 @@ func WithCapabilities(c *container.Container) coci.SpecOpts {
171 171
 	}
172 172
 }
173 173
 
174
-func readUserFile(c *container.Container, p string) (io.ReadCloser, error) {
175
-	fp, err := c.GetResourcePath(p)
174
+func resourcePath(c *container.Container, getPath func() (string, error)) (string, error) {
175
+	p, err := getPath()
176 176
 	if err != nil {
177
-		return nil, err
178
-	}
179
-	fh, err := os.Open(fp)
180
-	if err != nil {
181
-		// This is needed because a nil *os.File is different to a nil
182
-		// io.ReadCloser and this causes GetExecUser to not detect that the
183
-		// container file is missing.
184
-		return nil, err
177
+		return "", err
185 178
 	}
186
-	return fh, nil
179
+	return c.GetResourcePath(p)
187 180
 }
188 181
 
189
-func getUser(c *container.Container, username string) (uint32, uint32, []uint32, error) {
190
-	passwdPath, err := user.GetPasswdPath()
182
+func getUser(c *container.Container, username string) (specs.User, error) {
183
+	var usr specs.User
184
+	passwdPath, err := resourcePath(c, user.GetPasswdPath)
191 185
 	if err != nil {
192
-		return 0, 0, nil, err
186
+		return usr, err
193 187
 	}
194
-	groupPath, err := user.GetGroupPath()
188
+	groupPath, err := resourcePath(c, user.GetGroupPath)
195 189
 	if err != nil {
196
-		return 0, 0, nil, err
190
+		return usr, err
197 191
 	}
198
-	passwdFile, err := readUserFile(c, passwdPath)
199
-	if err == nil {
200
-		defer passwdFile.Close()
201
-	}
202
-	groupFile, err := readUserFile(c, groupPath)
203
-	if err == nil {
204
-		defer groupFile.Close()
205
-	}
206
-
207
-	execUser, err := user.GetExecUser(username, nil, passwdFile, groupFile)
192
+	execUser, err := user.GetExecUserPath(username, nil, passwdPath, groupPath)
208 193
 	if err != nil {
209
-		return 0, 0, nil, err
194
+		return usr, err
210 195
 	}
196
+	usr.UID = uint32(execUser.Uid)
197
+	usr.GID = uint32(execUser.Gid)
211 198
 
212
-	// todo: fix this double read by a change to libcontainer/user pkg
213
-	groupFile, err = readUserFile(c, groupPath)
214
-	if err == nil {
215
-		defer groupFile.Close()
216
-	}
217 199
 	var addGroups []int
218 200
 	if len(c.HostConfig.GroupAdd) > 0 {
219
-		addGroups, err = user.GetAdditionalGroups(c.HostConfig.GroupAdd, groupFile)
201
+		addGroups, err = user.GetAdditionalGroupsPath(c.HostConfig.GroupAdd, groupPath)
220 202
 		if err != nil {
221
-			return 0, 0, nil, err
203
+			return usr, err
222 204
 		}
223 205
 	}
224
-	uid := uint32(execUser.Uid)
225
-	gid := uint32(execUser.Gid)
226
-	sgids := append(execUser.Sgids, addGroups...)
227
-	var additionalGids []uint32
228
-	for _, g := range sgids {
229
-		additionalGids = append(additionalGids, uint32(g))
206
+	for _, g := range append(execUser.Sgids, addGroups...) {
207
+		usr.AdditionalGids = append(usr.AdditionalGids, uint32(g))
230 208
 	}
231
-	return uid, gid, additionalGids, nil
209
+	return usr, nil
232 210
 }
233 211
 
234 212
 func setNamespace(s *specs.Spec, ns specs.LinuxNamespace) {
... ...
@@ -1023,14 +1000,9 @@ func WithSysctls(c *container.Container) coci.SpecOpts {
1023 1023
 // WithUser sets the container's user
1024 1024
 func WithUser(c *container.Container) coci.SpecOpts {
1025 1025
 	return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
1026
-		uid, gid, additionalGids, err := getUser(c, c.Config.User)
1027
-		if err != nil {
1028
-			return err
1029
-		}
1030
-		s.Process.User.UID = uid
1031
-		s.Process.User.GID = gid
1032
-		s.Process.User.AdditionalGids = additionalGids
1033
-		return nil
1026
+		var err error
1027
+		s.Process.User, err = getUser(c, c.Config.User)
1028
+		return err
1034 1029
 	}
1035 1030
 }
1036 1031