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  }