github.com/jfrazelle/docker@v1.1.2-0.20210712172922-bf78e25fe508/builder/dockerfile/copy_windows.go (about) 1 package dockerfile // import "github.com/docker/docker/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/docker/docker/pkg/idtools" 11 "github.com/docker/docker/pkg/reexec" 12 "github.com/docker/docker/pkg/system" 13 "github.com/pkg/errors" 14 "golang.org/x/sys/windows" 15 ) 16 17 var pathDenyList = 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 privileges := []string{winio.SeRestorePrivilege, idtools.SeTakeOwnershipPrivilege} 47 48 err := winio.EnableProcessPrivileges(privileges) 49 if err != nil { 50 return err 51 } 52 53 defer winio.DisableProcessPrivileges(privileges) 54 55 sid, err := windows.StringToSid(SID) 56 if err != nil { 57 return err 58 } 59 60 // Owners on *nix have read/write/delete/read control and write DAC. 61 // Add an ACE that grants this to the user/group specified with the 62 // chown option. Currently Windows is not honoring the owner change, 63 // however, they are aware of this and it should be fixed at some 64 // point. 65 66 sddlString := system.SddlAdministratorsLocalSystem 67 sddlString += "(A;OICI;GRGWGXRCWDSD;;;" + SID + ")" 68 69 securityDescriptor, err := windows.SecurityDescriptorFromString(sddlString) 70 if err != nil { 71 return err 72 } 73 74 dacl, _, err := securityDescriptor.DACL() 75 if err != nil { 76 return err 77 } 78 79 return windows.SetNamedSecurityInfo(destination, windows.SE_FILE_OBJECT, windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION, sid, nil, dacl, nil) 80 } 81 82 func validateCopySourcePath(imageSource *imageMount, origPath, platform string) error { 83 // validate windows paths from other images + LCOW 84 if imageSource == nil || platform != "windows" { 85 return nil 86 } 87 88 origPath = filepath.FromSlash(origPath) 89 p := strings.ToLower(filepath.Clean(origPath)) 90 if !filepath.IsAbs(p) { 91 if filepath.VolumeName(p) != "" { 92 if p[len(p)-2:] == ":." { // case where clean returns weird c:. paths 93 p = p[:len(p)-1] 94 } 95 p += "\\" 96 } else { 97 p = filepath.Join("c:\\", p) 98 } 99 } 100 if _, ok := pathDenyList[p]; ok { 101 return errors.New("copy from c:\\ or c:\\windows is not allowed on windows") 102 } 103 return nil 104 }