Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy Windows file metadata #188

Merged
merged 1 commit into from Dec 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions fs/copy.go
Expand Up @@ -114,7 +114,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
return fmt.Errorf("failed to read %s: %w", src, err)
}

if err := copyFileInfo(stat, dst); err != nil {
if err := copyFileInfo(stat, src, dst); err != nil {
return fmt.Errorf("failed to copy file info for %s: %w", dst, err)
}

Expand Down Expand Up @@ -160,7 +160,8 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
// TODO: Support pipes and sockets
return fmt.Errorf("unsupported mode %s: %w", fi.Mode(), err)
}
if err := copyFileInfo(fi, target); err != nil {

if err := copyFileInfo(fi, source, target); err != nil {
return fmt.Errorf("failed to copy file info: %w", err)
}

Expand Down
2 changes: 1 addition & 1 deletion fs/copy_linux.go
Expand Up @@ -27,7 +27,7 @@ import (
"golang.org/x/sys/unix"
)

func copyFileInfo(fi os.FileInfo, name string) error {
estesp marked this conversation as resolved.
Show resolved Hide resolved
func copyFileInfo(fi os.FileInfo, src, name string) error {
st := fi.Sys().(*syscall.Stat_t)
if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil {
if os.IsPermission(err) {
Expand Down
2 changes: 1 addition & 1 deletion fs/copy_unix.go
Expand Up @@ -28,7 +28,7 @@ import (
"github.com/containerd/continuity/sysx"
)

func copyFileInfo(fi os.FileInfo, name string) error {
func copyFileInfo(fi os.FileInfo, src, name string) error {
st := fi.Sys().(*syscall.Stat_t)
if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil {
if os.IsPermission(err) {
Expand Down
45 changes: 43 additions & 2 deletions fs/copy_windows.go
Expand Up @@ -21,15 +21,56 @@ import (
"fmt"
"io"
"os"

winio "github.com/Microsoft/go-winio"
"golang.org/x/sys/windows"
)

const (
seTakeOwnershipPrivilege = "SeTakeOwnershipPrivilege"
)

func copyFileInfo(fi os.FileInfo, name string) error {
func copyFileInfo(fi os.FileInfo, src, name string) error {
if err := os.Chmod(name, fi.Mode()); err != nil {
return fmt.Errorf("failed to chmod %s: %w", name, err)
}

// TODO: copy windows specific metadata
// Copy file ownership and ACL
// We need SeRestorePrivilege and SeTakeOwnershipPrivilege in order
// to restore security info on a file, especially if we're trying to
// apply security info which includes SIDs not necessarily present on
// the host.
privileges := []string{winio.SeRestorePrivilege, seTakeOwnershipPrivilege}
if err := winio.EnableProcessPrivileges(privileges); err != nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return err
}
defer winio.DisableProcessPrivileges(privileges)

secInfo, err := windows.GetNamedSecurityInfo(
src, windows.SE_FILE_OBJECT,
windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION)

if err != nil {
return err
}

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

sid, _, err := secInfo.Owner()
if err != nil {
return err
}

if err := windows.SetNamedSecurityInfo(
name, windows.SE_FILE_OBJECT,
windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION,
sid, nil, dacl, nil); err != nil {

return err
}
return nil
}

Expand Down
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -6,6 +6,7 @@ require (
// 5883e5a4b512fe2e32f915b1c66a1ddfef81cb3f is the last version to support macOS
// see https://github.com/bazil/fuse/commit/60eaf8f021ce00e5c52529cdcba1067e13c1c2c2
bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512
github.com/Microsoft/go-winio v0.5.1
github.com/dustin/go-humanize v1.0.0
github.com/golang/protobuf v1.3.5
github.com/opencontainers/go-digest v1.0.0
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Expand Up @@ -2,6 +2,8 @@ bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512 h1:SRsZGA7aFnCZETmov57jwPrWuTm
bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
Expand Down Expand Up @@ -65,6 +67,7 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
Expand Down
1 change: 1 addition & 0 deletions vendor/github.com/Microsoft/go-winio/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions vendor/github.com/Microsoft/go-winio/CODEOWNERS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions vendor/github.com/Microsoft/go-winio/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions vendor/github.com/Microsoft/go-winio/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.