|
@@ -14,7 +14,6 @@ import (
|
|
|
"sync"
|
|
|
"syscall"
|
|
|
|
|
|
- "github.com/docker/docker/pkg/system"
|
|
|
"github.com/opencontainers/runc/libcontainer/user"
|
|
|
)
|
|
|
|
|
@@ -29,7 +28,7 @@ func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- stat, err := system.Stat(path)
|
|
|
+ stat, err := os.Stat(path)
|
|
|
if err == nil {
|
|
|
if !stat.IsDir() {
|
|
|
return &os.PathError{Op: "mkdir", Path: path, Err: syscall.ENOTDIR}
|
|
@@ -38,8 +37,8 @@ func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
- // short-circuit--we were called with an existing directory and chown was requested
|
|
|
- return setPermissions(path, mode, owner.UID, owner.GID, stat)
|
|
|
+ // short-circuit -- we were called with an existing directory and chown was requested
|
|
|
+ return setPermissions(path, mode, owner, stat)
|
|
|
}
|
|
|
|
|
|
// make an array containing the original path asked for, plus (for mkAll == true)
|
|
@@ -60,51 +59,26 @@ func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting
|
|
|
if dirPath == "/" {
|
|
|
break
|
|
|
}
|
|
|
- if _, err := os.Stat(dirPath); err != nil && os.IsNotExist(err) {
|
|
|
+ if _, err = os.Stat(dirPath); err != nil && os.IsNotExist(err) {
|
|
|
paths = append(paths, dirPath)
|
|
|
}
|
|
|
}
|
|
|
- if err := os.MkdirAll(path, mode); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- } else {
|
|
|
- if err := os.Mkdir(path, mode); err != nil && !os.IsExist(err) {
|
|
|
+ if err = os.MkdirAll(path, mode); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
+ } else if err = os.Mkdir(path, mode); err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
// 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 := setPermissions(pathComponent, mode, owner.UID, owner.GID, nil); err != nil {
|
|
|
+ if err = setPermissions(pathComponent, mode, owner, nil); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// CanAccess takes a valid (existing) directory and a uid, gid pair and determines
|
|
|
-// if that uid, gid pair has access (execute bit) to the directory
|
|
|
-func CanAccess(path string, pair Identity) bool {
|
|
|
- statInfo, err := system.Stat(path)
|
|
|
- if err != nil {
|
|
|
- return false
|
|
|
- }
|
|
|
- perms := os.FileMode(statInfo.Mode()).Perm()
|
|
|
- if perms&0o001 == 0o001 {
|
|
|
- // world access
|
|
|
- return true
|
|
|
- }
|
|
|
- if statInfo.UID() == uint32(pair.UID) && (perms&0o100 == 0o100) {
|
|
|
- // owner access.
|
|
|
- return true
|
|
|
- }
|
|
|
- if statInfo.GID() == uint32(pair.GID) && (perms&0o010 == 0o010) {
|
|
|
- // group access.
|
|
|
- return true
|
|
|
- }
|
|
|
- return false
|
|
|
-}
|
|
|
-
|
|
|
// LookupUser uses traditional local system files lookup (from libcontainer/user) on a username,
|
|
|
// followed by a call to `getent` for supporting host configured non-files passwd and group dbs
|
|
|
func LookupUser(name string) (user.User, error) {
|
|
@@ -229,23 +203,24 @@ func getExitCode(err error) (int, error) {
|
|
|
// 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.
|
|
|
// Likewise for setting permissions.
|
|
|
-func setPermissions(p string, mode os.FileMode, uid, gid int, stat *system.StatT) error {
|
|
|
+func setPermissions(p string, mode os.FileMode, owner Identity, stat os.FileInfo) error {
|
|
|
if stat == nil {
|
|
|
var err error
|
|
|
- stat, err = system.Stat(p)
|
|
|
+ stat, err = os.Stat(p)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
}
|
|
|
- if os.FileMode(stat.Mode()).Perm() != mode.Perm() {
|
|
|
+ if 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) {
|
|
|
+ ssi := stat.Sys().(*syscall.Stat_t)
|
|
|
+ if ssi.Uid == uint32(owner.UID) && ssi.Gid == uint32(owner.GID) {
|
|
|
return nil
|
|
|
}
|
|
|
- return os.Chown(p, uid, gid)
|
|
|
+ return os.Chown(p, owner.UID, owner.GID)
|
|
|
}
|
|
|
|
|
|
// LoadIdentityMapping takes a requested username and
|