2018-02-05 16:05:59 -05:00
|
|
|
package dockerfile // import "github.com/docker/docker/builder/dockerfile"
|
2017-05-14 14:18:48 -04:00
|
|
|
|
2017-08-03 20:22:00 -04:00
|
|
|
import (
|
2017-11-16 01:20:33 -05:00
|
|
|
"fmt"
|
|
|
|
"os"
|
2017-08-03 20:22:00 -04:00
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
|
2019-08-05 10:37:47 -04:00
|
|
|
winio "github.com/Microsoft/go-winio"
|
2017-08-03 20:22:00 -04:00
|
|
|
"github.com/docker/docker/pkg/idtools"
|
2017-11-16 01:20:33 -05:00
|
|
|
"github.com/docker/docker/pkg/reexec"
|
|
|
|
"github.com/docker/docker/pkg/system"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"golang.org/x/sys/windows"
|
2017-08-03 20:22:00 -04:00
|
|
|
)
|
2017-05-14 14:18:48 -04:00
|
|
|
|
2020-07-14 04:41:34 -04:00
|
|
|
var pathDenyList = map[string]bool{
|
2017-09-28 20:55:35 -04:00
|
|
|
"c:\\": true,
|
|
|
|
"c:\\windows": true,
|
|
|
|
}
|
|
|
|
|
2017-11-16 01:20:33 -05:00
|
|
|
func init() {
|
|
|
|
reexec.Register("windows-fix-permissions", fixPermissionsReexec)
|
|
|
|
}
|
|
|
|
|
|
|
|
func fixPermissions(source, destination string, identity idtools.Identity, _ bool) error {
|
|
|
|
if identity.SID == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd := reexec.Command("windows-fix-permissions", source, destination, identity.SID)
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
|
|
|
|
|
|
return errors.Wrapf(err, "failed to exec windows-fix-permissions: %s", output)
|
|
|
|
}
|
|
|
|
|
|
|
|
func fixPermissionsReexec() {
|
|
|
|
err := fixPermissionsWindows(os.Args[1], os.Args[2], os.Args[3])
|
|
|
|
if err != nil {
|
|
|
|
fmt.Fprint(os.Stderr, err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func fixPermissionsWindows(source, destination, SID string) error {
|
|
|
|
|
|
|
|
privileges := []string{winio.SeRestorePrivilege, system.SeTakeOwnershipPrivilege}
|
|
|
|
|
|
|
|
err := winio.EnableProcessPrivileges(privileges)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer winio.DisableProcessPrivileges(privileges)
|
|
|
|
|
|
|
|
sid, err := windows.StringToSid(SID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Owners on *nix have read/write/delete/read control and write DAC.
|
|
|
|
// Add an ACE that grants this to the user/group specified with the
|
|
|
|
// chown option. Currently Windows is not honoring the owner change,
|
|
|
|
// however, they are aware of this and it should be fixed at some
|
|
|
|
// point.
|
|
|
|
|
|
|
|
sddlString := system.SddlAdministratorsLocalSystem
|
|
|
|
sddlString += "(A;OICI;GRGWGXRCWDSD;;;" + SID + ")"
|
|
|
|
|
2020-03-09 07:42:08 -04:00
|
|
|
securityDescriptor, err := windows.SecurityDescriptorFromString(sddlString)
|
2017-11-16 01:20:33 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-03-09 07:42:08 -04:00
|
|
|
dacl, _, err := securityDescriptor.DACL()
|
2017-11-16 01:20:33 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-03-09 07:42:08 -04:00
|
|
|
return windows.SetNamedSecurityInfo(destination, windows.SE_FILE_OBJECT, windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION, sid, nil, dacl, nil)
|
2017-05-14 14:18:48 -04:00
|
|
|
}
|
2017-08-03 20:22:00 -04:00
|
|
|
|
|
|
|
func validateCopySourcePath(imageSource *imageMount, origPath, platform string) error {
|
|
|
|
// validate windows paths from other images + LCOW
|
|
|
|
if imageSource == nil || platform != "windows" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
origPath = filepath.FromSlash(origPath)
|
|
|
|
p := strings.ToLower(filepath.Clean(origPath))
|
|
|
|
if !filepath.IsAbs(p) {
|
|
|
|
if filepath.VolumeName(p) != "" {
|
|
|
|
if p[len(p)-2:] == ":." { // case where clean returns weird c:. paths
|
|
|
|
p = p[:len(p)-1]
|
|
|
|
}
|
|
|
|
p += "\\"
|
|
|
|
} else {
|
|
|
|
p = filepath.Join("c:\\", p)
|
|
|
|
}
|
|
|
|
}
|
2020-07-14 04:41:34 -04:00
|
|
|
if _, ok := pathDenyList[p]; ok {
|
2017-08-03 20:22:00 -04:00
|
|
|
return errors.New("copy from c:\\ or c:\\windows is not allowed on windows")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|