github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/builder/dockerfile/copy_windows.go (about) 1 package dockerfile // import "github.com/demonoid81/moby/builder/dockerfile" 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 9 winio "github.com/Microsoft/go-winio" 10 "github.com/demonoid81/moby/pkg/idtools" 11 "github.com/demonoid81/moby/pkg/reexec" 12 "github.com/demonoid81/moby/pkg/system" 13 "github.com/pkg/errors" 14 "golang.org/x/sys/windows" 15 ) 16 17 var pathBlacklist = map[string]bool{ 18 "c:\\": true, 19 "c:\\windows": true, 20 } 21 22 func init() { 23 reexec.Register("windows-fix-permissions", fixPermissionsReexec) 24 } 25 26 func fixPermissions(source, destination string, identity idtools.Identity, _ bool) error { 27 if identity.SID == "" { 28 return nil 29 } 30 31 cmd := reexec.Command("windows-fix-permissions", source, destination, identity.SID) 32 output, err := cmd.CombinedOutput() 33 34 return errors.Wrapf(err, "failed to exec windows-fix-permissions: %s", output) 35 } 36 37 func fixPermissionsReexec() { 38 err := fixPermissionsWindows(os.Args[1], os.Args[2], os.Args[3]) 39 if err != nil { 40 fmt.Fprint(os.Stderr, err) 41 os.Exit(1) 42 } 43 } 44 45 func fixPermissionsWindows(source, destination, SID string) error { 46 47 privileges := []string{winio.SeRestorePrivilege, system.SeTakeOwnershipPrivilege} 48 49 err := winio.EnableProcessPrivileges(privileges) 50 if err != nil { 51 return err 52 } 53 54 defer winio.DisableProcessPrivileges(privileges) 55 56 sid, err := windows.StringToSid(SID) 57 if err != nil { 58 return err 59 } 60 61 // Owners on *nix have read/write/delete/read control and write DAC. 62 // Add an ACE that grants this to the user/group specified with the 63 // chown option. Currently Windows is not honoring the owner change, 64 // however, they are aware of this and it should be fixed at some 65 // point. 66 67 sddlString := system.SddlAdministratorsLocalSystem 68 sddlString += "(A;OICI;GRGWGXRCWDSD;;;" + SID + ")" 69 70 securityDescriptor, err := windows.SecurityDescriptorFromString(sddlString) 71 if err != nil { 72 return err 73 } 74 75 dacl, _, err := securityDescriptor.DACL() 76 if err != nil { 77 return err 78 } 79 80 return windows.SetNamedSecurityInfo(destination, windows.SE_FILE_OBJECT, windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION, sid, nil, dacl, nil) 81 } 82 83 func validateCopySourcePath(imageSource *imageMount, origPath, platform string) error { 84 // validate windows paths from other images + LCOW 85 if imageSource == nil || platform != "windows" { 86 return nil 87 } 88 89 origPath = filepath.FromSlash(origPath) 90 p := strings.ToLower(filepath.Clean(origPath)) 91 if !filepath.IsAbs(p) { 92 if filepath.VolumeName(p) != "" { 93 if p[len(p)-2:] == ":." { // case where clean returns weird c:. paths 94 p = p[:len(p)-1] 95 } 96 p += "\\" 97 } else { 98 p = filepath.Join("c:\\", p) 99 } 100 } 101 if _, blacklisted := pathBlacklist[p]; blacklisted { 102 return errors.New("copy from c:\\ or c:\\windows is not allowed on windows") 103 } 104 return nil 105 }