Skip to content

Commit

Permalink
Set ownership on directories in chroot
Browse files Browse the repository at this point in the history
Also support getOwner on all Unixes as they all have `Stat_t.{U,G}id`
  • Loading branch information
schmichael committed Apr 17, 2017
1 parent 1cffc73 commit 17471bf
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 31 deletions.
34 changes: 27 additions & 7 deletions client/allocdir/alloc_dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ import (
"github.com/hpcloud/tail/watch"
)

const (
// idUnsupported is what the uid/gid will be set to on platforms (eg
// Windows) that don't support integer ownership identifiers.
idUnsupported = -1
)

var (
// The name of the directory that is shared across tasks in a task group.
SharedAllocName = "alloc"
Expand Down Expand Up @@ -405,7 +411,7 @@ func fileCopy(src, dst string, uid, gid int, perm os.FileMode) error {
return fmt.Errorf("Couldn't copy %q to %q: %v", src, dst, err)
}

if uid >= 0 && gid >= 0 {
if uid != idUnsupported && gid != idUnsupported {
if err := dstFile.Chown(uid, gid); err != nil {
return fmt.Errorf("Couldn't copy %q to %q: %v", src, dst, err)
}
Expand Down Expand Up @@ -456,6 +462,12 @@ func createDir(basePath, relPath string) error {
if err := os.MkdirAll(destDir, fi.Perm); err != nil {
return err
}

if fi.Uid != idUnsupported && fi.Gid != idUnsupported {
if err := os.Chown(destDir, fi.Uid, fi.Gid); err != nil {
return err
}
}
}
return nil
}
Expand All @@ -464,24 +476,30 @@ func createDir(basePath, relPath string) error {
type fileInfo struct {
Name string
Perm os.FileMode

// Uid and Gid are unsupported on Windows
Uid int
Gid int
}

// splitPath stats each subdirectory of a path. The first element of the array
// is the file passed to this function, and the last element is the root of the
// path.
func splitPath(path string) ([]fileInfo, error) {
var mode os.FileMode
i, err := os.Stat(path)
fi, err := os.Stat(path)

// If the path is not present in the host then we respond with the most
// flexible permission.
uid, gid := idUnsupported, idUnsupported
if err != nil {
mode = os.ModePerm
} else {
mode = i.Mode()
uid, gid = getOwner(fi)
mode = fi.Mode()
}
var dirs []fileInfo
dirs = append(dirs, fileInfo{Name: path, Perm: mode})
dirs = append(dirs, fileInfo{Name: path, Perm: mode, Uid: uid, Gid: gid})
currentDir := path
for {
dir := filepath.Dir(filepath.Clean(currentDir))
Expand All @@ -491,13 +509,15 @@ func splitPath(path string) ([]fileInfo, error) {

// We try to find the permission of the file in the host. If the path is not
// present in the host then we respond with the most flexible permission.
i, err = os.Stat(dir)
uid, gid := idUnsupported, idUnsupported
fi, err := os.Stat(dir)
if err != nil {
mode = os.ModePerm
} else {
mode = i.Mode()
uid, gid = getOwner(fi)
mode = fi.Mode()
}
dirs = append(dirs, fileInfo{Name: dir, Perm: mode})
dirs = append(dirs, fileInfo{Name: dir, Perm: mode, Uid: uid, Gid: gid})
currentDir = dir
}
return dirs, nil
Expand Down
5 changes: 0 additions & 5 deletions client/allocdir/fs_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,3 @@ func createSecretDir(dir string) error {
func removeSecretDir(dir string) error {
return os.RemoveAll(dir)
}

// getOwner isn't implemented for Darwin
func getOwner(os.FileInfo) (int, int) {
return -1, -1
}
5 changes: 0 additions & 5 deletions client/allocdir/fs_freebsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,3 @@ func createSecretDir(dir string) error {
func removeSecretDir(dir string) error {
return os.RemoveAll(dir)
}

// getOwner isn't implemented for FreeBSD
func getOwner(os.FileInfo) (int, int) {
return -1, -1
}
8 changes: 0 additions & 8 deletions client/allocdir/fs_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,3 @@ func removeSecretDir(dir string) error {
}
return os.RemoveAll(dir)
}

func getOwner(fi os.FileInfo) (int, int) {
stat, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
return -1, -1
}
return int(stat.Uid), int(stat.Gid)
}
5 changes: 0 additions & 5 deletions client/allocdir/fs_solaris.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,3 @@ func createSecretDir(dir string) error {
func removeSecretDir(dir string) error {
return os.RemoveAll(dir)
}

// getOwner isn't implemented for Solaris
func getOwner(os.FileInfo) (int, int) {
return -1, -1
}
9 changes: 9 additions & 0 deletions client/allocdir/fs_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os/user"
"path/filepath"
"strconv"
"syscall"

"golang.org/x/sys/unix"
)
Expand Down Expand Up @@ -96,3 +97,11 @@ func linkOrCopy(src, dst string, uid, gid int, perm os.FileMode) error {

return fileCopy(src, dst, uid, gid, perm)
}

func getOwner(fi os.FileInfo) (int, int) {
stat, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
return -1, -1
}
return int(stat.Uid), int(stat.Gid)
}
2 changes: 1 addition & 1 deletion client/allocdir/fs_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,5 @@ func unmountSpecialDirs(taskDir string) error {

// getOwner doesn't work on Windows as Windows doesn't use int user IDs
func getOwner(os.FileInfo) (int, int) {
return -1, -1
return idUnsupported, idUnsupported
}

0 comments on commit 17471bf

Please sign in to comment.