github.com/jwhonce/docker@v0.6.7-0.20190327063223-da823cf3a5a3/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  }