File: copy_windows.go

package info (click to toggle)
docker.io 20.10.24%2Bdfsg1-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bookworm-proposed-updates
  • size: 60,824 kB
  • sloc: sh: 5,621; makefile: 593; ansic: 179; python: 162; asm: 7
file content (105 lines) | stat: -rw-r--r-- 2,766 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package dockerfile // import "github.com/docker/docker/builder/dockerfile"

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	winio "github.com/Microsoft/go-winio"
	"github.com/docker/docker/pkg/idtools"
	"github.com/docker/docker/pkg/reexec"
	"github.com/docker/docker/pkg/system"
	"github.com/pkg/errors"
	"golang.org/x/sys/windows"
)

var pathDenyList = map[string]bool{
	"c:\\":        true,
	"c:\\windows": true,
}

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 + ")"

	securityDescriptor, err := windows.SecurityDescriptorFromString(sddlString)
	if err != nil {
		return err
	}

	dacl, _, err := securityDescriptor.DACL()
	if err != nil {
		return err
	}

	return windows.SetNamedSecurityInfo(destination, windows.SE_FILE_OBJECT, windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION, sid, nil, dacl, nil)
}

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)
		}
	}
	if _, ok := pathDenyList[p]; ok {
		return errors.New("copy from c:\\ or c:\\windows is not allowed on windows")
	}
	return nil
}