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  }