github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/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 "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 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 := winio.SddlToSecurityDescriptor(sddlString) 71 if err != nil { 72 return err 73 } 74 75 var daclPresent uint32 76 var daclDefaulted uint32 77 var dacl *byte 78 79 err = system.GetSecurityDescriptorDacl(&securityDescriptor[0], &daclPresent, &dacl, &daclDefaulted) 80 if err != nil { 81 return err 82 } 83 84 return system.SetNamedSecurityInfo(windows.StringToUTF16Ptr(destination), system.SE_FILE_OBJECT, system.OWNER_SECURITY_INFORMATION|system.DACL_SECURITY_INFORMATION, sid, nil, dacl, nil) 85 } 86 87 func validateCopySourcePath(imageSource *imageMount, origPath, platform string) error { 88 // validate windows paths from other images + LCOW 89 if imageSource == nil || platform != "windows" { 90 return nil 91 } 92 93 origPath = filepath.FromSlash(origPath) 94 p := strings.ToLower(filepath.Clean(origPath)) 95 if !filepath.IsAbs(p) { 96 if filepath.VolumeName(p) != "" { 97 if p[len(p)-2:] == ":." { // case where clean returns weird c:. paths 98 p = p[:len(p)-1] 99 } 100 p += "\\" 101 } else { 102 p = filepath.Join("c:\\", p) 103 } 104 } 105 if _, blacklisted := pathBlacklist[p]; blacklisted { 106 return errors.New("copy from c:\\ or c:\\windows is not allowed on windows") 107 } 108 return nil 109 }