1package system // import "github.com/docker/docker/pkg/system" 2 3import ( 4 "fmt" 5 "path/filepath" 6 "runtime" 7 "strings" 8) 9 10const defaultUnixPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 11 12// DefaultPathEnv is unix style list of directories to search for 13// executables. Each directory is separated from the next by a colon 14// ':' character . 15func DefaultPathEnv(os string) string { 16 if runtime.GOOS == "windows" { 17 if os != runtime.GOOS { 18 return defaultUnixPathEnv 19 } 20 // Deliberately empty on Windows containers on Windows as the default path will be set by 21 // the container. Docker has no context of what the default path should be. 22 return "" 23 } 24 return defaultUnixPathEnv 25 26} 27 28// PathVerifier defines the subset of a PathDriver that CheckSystemDriveAndRemoveDriveLetter 29// actually uses in order to avoid system depending on containerd/continuity. 30type PathVerifier interface { 31 IsAbs(string) bool 32} 33 34// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter, 35// is the system drive. 36// On Linux: this is a no-op. 37// On Windows: this does the following> 38// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path. 39// This is used, for example, when validating a user provided path in docker cp. 40// If a drive letter is supplied, it must be the system drive. The drive letter 41// is always removed. Also, it translates it to OS semantics (IOW / to \). We 42// need the path in this syntax so that it can ultimately be concatenated with 43// a Windows long-path which doesn't support drive-letters. Examples: 44// C: --> Fail 45// C:\ --> \ 46// a --> a 47// /a --> \a 48// d:\ --> Fail 49func CheckSystemDriveAndRemoveDriveLetter(path string, driver PathVerifier) (string, error) { 50 if runtime.GOOS != "windows" || LCOWSupported() { 51 return path, nil 52 } 53 54 if len(path) == 2 && string(path[1]) == ":" { 55 return "", fmt.Errorf("No relative path specified in %q", path) 56 } 57 if !driver.IsAbs(path) || len(path) < 2 { 58 return filepath.FromSlash(path), nil 59 } 60 if string(path[1]) == ":" && !strings.EqualFold(string(path[0]), "c") { 61 return "", fmt.Errorf("The specified path is not on the system drive (C:)") 62 } 63 return filepath.FromSlash(path[2:]), nil 64} 65