summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Goff <cpuguy83@gmail.com>2020-10-06 19:30:07 +0000
committerTibor Vass <tibor@docker.com>2021-01-26 17:23:32 +0000
commitedb62a3ace8c4303822a391b38231e577f8c2ee8 (patch)
tree600e1b04904a58bbdef721fafc1a0b13e50170e5
parent8891c58a433a823ce0a65b57efff45f32ee9cb45 (diff)
downloaddocker-edb62a3ace8c4303822a391b38231e577f8c2ee8.tar.gz
Ensure MkdirAllAndChown also sets perms
Generally if we ever need to change perms of a dir, between versions, this ensures the permissions actually change when we think it should change without having to handle special cases if it already existed. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
-rw-r--r--pkg/idtools/idtools.go11
-rw-r--r--pkg/idtools/idtools_unix.go14
2 files changed, 18 insertions, 7 deletions
diff --git a/pkg/idtools/idtools.go b/pkg/idtools/idtools.go
index 7569ac15dd..25a57b231e 100644
--- a/pkg/idtools/idtools.go
+++ b/pkg/idtools/idtools.go
@@ -35,13 +35,13 @@ const (
// MkdirAllAndChown creates a directory (include any along the path) and then modifies
// ownership to the requested uid/gid. If the directory already exists, this
-// function will still change ownership to the requested uid/gid pair.
+// function will still change ownership and permissions.
func MkdirAllAndChown(path string, mode os.FileMode, owner Identity) error {
return mkdirAs(path, mode, owner, true, true)
}
// MkdirAndChown creates a directory and then modifies ownership to the requested uid/gid.
-// If the directory already exists, this function still changes ownership.
+// If the directory already exists, this function still changes ownership and permissions.
// Note that unlike os.Mkdir(), this function does not return IsExist error
// in case path already exists.
func MkdirAndChown(path string, mode os.FileMode, owner Identity) error {
@@ -50,7 +50,7 @@ func MkdirAndChown(path string, mode os.FileMode, owner Identity) error {
// MkdirAllAndChownNew creates a directory (include any along the path) and then modifies
// ownership ONLY of newly created directories to the requested uid/gid. If the
-// directories along the path exist, no change of ownership will be performed
+// directories along the path exist, no change of ownership or permissions will be performed
func MkdirAllAndChownNew(path string, mode os.FileMode, owner Identity) error {
return mkdirAs(path, mode, owner, true, false)
}
@@ -234,3 +234,8 @@ func parseSubidFile(path, username string) (ranges, error) {
return rangeList, s.Err()
}
+
+// CurrentIdentity returns the identity of the current process
+func CurrentIdentity() Identity {
+ return Identity{UID: os.Getuid(), GID: os.Getegid()}
+}
diff --git a/pkg/idtools/idtools_unix.go b/pkg/idtools/idtools_unix.go
index 5defe6459f..a03af12045 100644
--- a/pkg/idtools/idtools_unix.go
+++ b/pkg/idtools/idtools_unix.go
@@ -40,7 +40,7 @@ func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting
}
// short-circuit--we were called with an existing directory and chown was requested
- return lazyChown(path, owner.UID, owner.GID, stat)
+ return setPermissions(path, mode, owner.UID, owner.GID, stat)
}
if os.IsNotExist(err) {
@@ -71,7 +71,7 @@ func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting
// even if it existed, we will chown the requested path + any subpaths that
// didn't exist when we called MkdirAll
for _, pathComponent := range paths {
- if err := lazyChown(pathComponent, owner.UID, owner.GID, nil); err != nil {
+ if err := setPermissions(pathComponent, mode, owner.UID, owner.GID, nil); err != nil {
return err
}
}
@@ -213,10 +213,11 @@ func callGetent(database, key string) (io.Reader, error) {
return bytes.NewReader(out), nil
}
-// lazyChown performs a chown only if the uid/gid don't match what's requested
+// setPermissions performs a chown/chmod only if the uid/gid don't match what's requested
// Normally a Chown is a no-op if uid/gid match, but in some cases this can still cause an error, e.g. if the
// dir is on an NFS share, so don't call chown unless we absolutely must.
-func lazyChown(p string, uid, gid int, stat *system.StatT) error {
+// Likewise for setting permissions.
+func setPermissions(p string, mode os.FileMode, uid, gid int, stat *system.StatT) error {
if stat == nil {
var err error
stat, err = system.Stat(p)
@@ -224,6 +225,11 @@ func lazyChown(p string, uid, gid int, stat *system.StatT) error {
return err
}
}
+ if os.FileMode(stat.Mode()).Perm() != mode.Perm() {
+ if err := os.Chmod(p, mode.Perm()); err != nil {
+ return err
+ }
+ }
if stat.UID() == uint32(uid) && stat.GID() == uint32(gid) {
return nil
}