forked from rclone/rclone
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
local: fix permission and ownership on symlinks with --links and --me…
…tadata Before this change, if writing to a local backend with --metadata and --links, if the incoming metadata contained mode or ownership information then rclone would apply the mode/ownership to the destination of the link not the link itself. This fixes the problem by using the link safe sycall variants lchown/fchmodat when --links and --metadata is in use. Note that Linux does not support setting permissions on symlinks, so rclone emits a debug message in this case. This also fixes setting times on symlinks on Windows which wasn't implemented for atime, mtime and was incorrectly setting the target of the symlink for btime. See: GHSA-hrxh-9w67-g4cv
- Loading branch information
Showing
8 changed files
with
202 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
//go:build windows || plan9 || js || linux | ||
|
||
package local | ||
|
||
import "os" | ||
|
||
const haveLChmod = false | ||
|
||
// lChmod changes the mode of the named file to mode. If the file is a symbolic | ||
// link, it changes the link, not the target. If there is an error, | ||
// it will be of type *PathError. | ||
func lChmod(name string, mode os.FileMode) error { | ||
// Can't do this safely on this OS - chmoding a symlink always | ||
// changes the destination. | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
//go:build !windows && !plan9 && !js && !linux | ||
|
||
package local | ||
|
||
import ( | ||
"os" | ||
"syscall" | ||
|
||
"golang.org/x/sys/unix" | ||
) | ||
|
||
const haveLChmod = true | ||
|
||
// syscallMode returns the syscall-specific mode bits from Go's portable mode bits. | ||
// | ||
// Borrowed from the syscall source since it isn't public. | ||
func syscallMode(i os.FileMode) (o uint32) { | ||
o |= uint32(i.Perm()) | ||
if i&os.ModeSetuid != 0 { | ||
o |= syscall.S_ISUID | ||
} | ||
if i&os.ModeSetgid != 0 { | ||
o |= syscall.S_ISGID | ||
} | ||
if i&os.ModeSticky != 0 { | ||
o |= syscall.S_ISVTX | ||
} | ||
return o | ||
} | ||
|
||
// lChmod changes the mode of the named file to mode. If the file is a symbolic | ||
// link, it changes the link, not the target. If there is an error, | ||
// it will be of type *PathError. | ||
func lChmod(name string, mode os.FileMode) error { | ||
// NB linux does not support AT_SYMLINK_NOFOLLOW as a parameter to fchmodat | ||
// and returns ENOTSUP if you try, so we don't support this on linux | ||
if e := unix.Fchmodat(unix.AT_FDCWD, name, syscallMode(mode), unix.AT_SYMLINK_NOFOLLOW); e != nil { | ||
return &os.PathError{Op: "lChmod", Path: name, Err: e} | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
//go:build windows || plan9 || js | ||
//go:build plan9 || js | ||
|
||
package local | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//go:build windows | ||
|
||
package local | ||
|
||
import ( | ||
"time" | ||
) | ||
|
||
const haveLChtimes = true | ||
|
||
// lChtimes changes the access and modification times of the named | ||
// link, similar to the Unix utime() or utimes() functions. | ||
// | ||
// The underlying filesystem may truncate or round the values to a | ||
// less precise time unit. | ||
// If there is an error, it will be of type *PathError. | ||
func lChtimes(name string, atime time.Time, mtime time.Time) error { | ||
return setTimes(name, atime, mtime, time.Time{}, true) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters