sftpd: document chmod/chown on Windows

chmod is partially supported and chown is not supported on Windows.

Skip unsupported test cases on Windows
This commit is contained in:
Nicola Murino 2019-11-15 17:09:00 +01:00
parent 3ac5af47f2
commit fc442d7862
3 changed files with 66 additions and 11 deletions

View file

@ -365,8 +365,8 @@ For each account the following properties can be configured:
- `rename` rename files or directories is allowed
- `create_dirs` create directories is allowed
- `create_symlinks` create symbolic links is allowed
- `chmod` changing file or directory permissions is allowed
- `chown` changing file or directory owner and group is allowed
- `chmod` changing file or directory permissions is allowed. On Windows, only the 0200 bit (owner writable) of mode is used; it controls whether the file's read-only attribute is set or cleared. The other bits are currently unused. Use mode 0400 for a read-only file and 0600 for a readable+writable file.
- `chown` changing file or directory owner and group is allowed. Changing owner and group is not supported on Windows.
- `upload_bandwidth` maximum upload bandwidth as KB/s, 0 means unlimited.
- `download_bandwidth` maximum download bandwidth as KB/s, 0 means unlimited.

View file

@ -229,7 +229,7 @@ func (c Connection) Filelist(request *sftp.Request) (sftp.ListerAt, error) {
return nil, sftp.ErrSSHFxPermissionDenied
}
c.Log(logger.LevelDebug, logSender, "requested Stat for file: %#v", p)
c.Log(logger.LevelDebug, logSender, "requested stat for file: %#v", p)
s, err := os.Stat(p)
if err != nil {
c.Log(logger.LevelWarn, logSender, "error running Stat on file: %#v", err)

View file

@ -519,6 +519,69 @@ func TestStat(t *testing.T) {
if err != nil {
t.Errorf("stat error: %v", err)
}
// mode 0666 and 0444 works on Windows too
newPerm := os.FileMode(0666)
err = client.Chmod(testFileName, newPerm)
if err != nil {
t.Errorf("chmod error: %v", err)
}
newFi, err := client.Lstat(testFileName)
if err != nil {
t.Errorf("stat error: %v", err)
}
if newPerm != newFi.Mode().Perm() {
t.Errorf("chmod failed expected: %v, actual: %v", newPerm, newFi.Mode().Perm())
}
newPerm = os.FileMode(0444)
err = client.Chmod(testFileName, newPerm)
if err != nil {
t.Errorf("chmod error: %v", err)
}
newFi, err = client.Lstat(testFileName)
if err != nil {
t.Errorf("stat error: %v", err)
}
if newPerm != newFi.Mode().Perm() {
t.Errorf("chmod failed expected: %v, actual: %v", newPerm, newFi.Mode().Perm())
}
_, err = client.ReadLink(testFileName)
if err == nil {
t.Errorf("readlink is not supported and must fail")
}
err = client.Chtimes(testFileName, time.Now(), time.Now())
if err != nil {
t.Errorf("chtime must be silently ignored: %v", err)
}
}
_, err = httpd.RemoveUser(user, http.StatusOK)
if err != nil {
t.Errorf("unable to remove user: %v", err)
}
os.RemoveAll(user.GetHomeDir())
}
func TestStatChownChmod(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("chown is not supported on Windows, chmod is partially supported")
}
usePubKey := true
user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
if err != nil {
t.Errorf("unable to add user: %v", err)
}
client, err := getSftpClient(user, usePubKey)
if err != nil {
t.Errorf("unable to create sftp client: %v", err)
} else {
defer client.Close()
testFileName := "test_file.dat"
testFilePath := filepath.Join(homeBasePath, testFileName)
testFileSize := int64(65535)
createTestFile(testFilePath, testFileSize)
err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
if err != nil {
t.Errorf("file upload error: %v", err)
}
err = client.Chown(testFileName, os.Getuid(), os.Getgid())
if err != nil {
t.Errorf("chown error: %v", err)
@ -535,10 +598,6 @@ func TestStat(t *testing.T) {
if newPerm != newFi.Mode().Perm() {
t.Errorf("chown failed expected: %v, actual: %v", newPerm, newFi.Mode().Perm())
}
_, err = client.ReadLink(testFileName)
if err == nil {
t.Errorf("readlink is not supported and must fail")
}
err = client.Remove(testFileName)
if err != nil {
t.Errorf("error removing uploaded file: %v", err)
@ -552,10 +611,6 @@ func TestStat(t *testing.T) {
if err != os.ErrNotExist {
t.Errorf("unexpected chown error: %v expected: %v", err, os.ErrNotExist)
}
err = client.Chtimes(testFileName, time.Now(), time.Now())
if err != nil {
t.Errorf("chtime must be silently ignored: %v", err)
}
}
_, err = httpd.RemoveUser(user, http.StatusOK)
if err != nil {