check permissions against sftp path

instead of building filesystem paths and then checking permissions against
path relative to the home dir that is the initial sftp path
This commit is contained in:
Nicola Murino 2020-01-05 11:41:25 +01:00
parent eb2ddc4798
commit e046b35b97
6 changed files with 111 additions and 104 deletions

View file

@ -100,7 +100,8 @@ type User struct {
Filters UserFilters `json:"filters"`
}
// GetPermissionsForPath returns the permissions for the given path
// GetPermissionsForPath returns the permissions for the given path.
// The path must be an SFTP path
func (u *User) GetPermissionsForPath(p string) []string {
permissions := []string{}
if perms, ok := u.Permissions["/"]; ok {
@ -111,17 +112,18 @@ func (u *User) GetPermissionsForPath(p string) []string {
// fallback permissions
permissions = perms
}
relPath := u.GetRelativePath(p)
if len(relPath) == 0 {
relPath = "/"
sftpPath := filepath.ToSlash(p)
if !path.IsAbs(p) {
sftpPath = "/" + sftpPath
}
dirsForPath := []string{relPath}
sftpPath = path.Clean(sftpPath)
dirsForPath := []string{sftpPath}
for {
if relPath == "/" {
if sftpPath == "/" {
break
}
relPath = path.Dir(relPath)
dirsForPath = append(dirsForPath, relPath)
sftpPath = path.Dir(sftpPath)
dirsForPath = append(dirsForPath, sftpPath)
}
// dirsForPath contains all the dirs for a given path in reverse order
// for example if the path is: /1/2/3/4 it contains:

View file

@ -6,6 +6,7 @@ import (
"io/ioutil"
"net"
"os"
"path"
"path/filepath"
"strings"
"sync"
@ -51,13 +52,14 @@ func (c Connection) Log(level logger.LogLevel, sender string, format string, v .
func (c Connection) Fileread(request *sftp.Request) (io.ReaderAt, error) {
updateConnectionActivity(c.ID)
if !c.User.HasPerm(dataprovider.PermDownload, path.Dir(request.Filepath)) {
return nil, sftp.ErrSSHFxPermissionDenied
}
p, err := c.buildPath(request.Filepath)
if err != nil {
return nil, getSFTPErrorFromOSError(err)
}
if !c.User.HasPerm(dataprovider.PermDownload, filepath.Dir(p)) {
return nil, sftp.ErrSSHFxPermissionDenied
}
c.lock.Lock()
defer c.lock.Unlock()
@ -112,7 +114,7 @@ func (c Connection) Filewrite(request *sftp.Request) (io.WriterAt, error) {
stat, statErr := os.Stat(p)
if os.IsNotExist(statErr) {
if !c.User.HasPerm(dataprovider.PermUpload, filepath.Dir(p)) {
if !c.User.HasPerm(dataprovider.PermUpload, path.Dir(request.Filepath)) {
return nil, sftp.ErrSSHFxPermissionDenied
}
return c.handleSFTPUploadToNewFile(p, filePath)
@ -129,7 +131,7 @@ func (c Connection) Filewrite(request *sftp.Request) (io.WriterAt, error) {
return nil, sftp.ErrSSHFxOpUnsupported
}
if !c.User.HasPerm(dataprovider.PermOverwrite, filepath.Dir(filePath)) {
if !c.User.HasPerm(dataprovider.PermOverwrite, path.Dir(request.Filepath)) {
return nil, sftp.ErrSSHFxPermissionDenied
}
@ -157,26 +159,26 @@ func (c Connection) Filecmd(request *sftp.Request) error {
case "Setstat":
return c.handleSFTPSetstat(p, request)
case "Rename":
if err = c.handleSFTPRename(p, target); err != nil {
if err = c.handleSFTPRename(p, target, request); err != nil {
return err
}
break
case "Rmdir":
return c.handleSFTPRmdir(p)
return c.handleSFTPRmdir(p, request)
case "Mkdir":
err = c.handleSFTPMkdir(p)
err = c.handleSFTPMkdir(p, request)
if err != nil {
return err
}
break
case "Symlink":
if err = c.handleSFTPSymlink(p, target); err != nil {
if err = c.handleSFTPSymlink(p, target, request); err != nil {
return err
}
break
case "Remove":
return c.handleSFTPRemove(p)
return c.handleSFTPRemove(p, request)
default:
return sftp.ErrSSHFxOpUnsupported
@ -204,7 +206,7 @@ func (c Connection) Filelist(request *sftp.Request) (sftp.ListerAt, error) {
switch request.Method {
case "List":
if !c.User.HasPerm(dataprovider.PermListItems, p) {
if !c.User.HasPerm(dataprovider.PermListItems, request.Filepath) {
return nil, sftp.ErrSSHFxPermissionDenied
}
@ -218,7 +220,7 @@ func (c Connection) Filelist(request *sftp.Request) (sftp.ListerAt, error) {
return listerAt(files), nil
case "Stat":
if !c.User.HasPerm(dataprovider.PermListItems, filepath.Dir(p)) {
if !c.User.HasPerm(dataprovider.PermListItems, path.Dir(request.Filepath)) {
return nil, sftp.ErrSSHFxPermissionDenied
}
@ -249,7 +251,7 @@ func (c Connection) getSFTPCmdTargetPath(requestTarget string) (string, error) {
return target, nil
}
func (c Connection) handleSFTPSetstat(path string, request *sftp.Request) error {
func (c Connection) handleSFTPSetstat(filePath string, request *sftp.Request) error {
if setstatMode == 1 {
return nil
}
@ -258,10 +260,10 @@ func (c Connection) handleSFTPSetstat(path string, request *sftp.Request) error
c.ClientVersion)
return sftp.ErrSSHFxBadMessage
}
pathForPerms := path
if fi, err := os.Lstat(path); err == nil {
pathForPerms := request.Filepath
if fi, err := os.Lstat(filePath); err == nil {
if fi.IsDir() {
pathForPerms = filepath.Dir(path)
pathForPerms = path.Dir(request.Filepath)
}
}
attrFlags := request.AttrFlags()
@ -270,11 +272,11 @@ func (c Connection) handleSFTPSetstat(path string, request *sftp.Request) error
return sftp.ErrSSHFxPermissionDenied
}
fileMode := request.Attributes().FileMode()
if err := os.Chmod(path, fileMode); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to chmod path %#v, mode: %v, err: %v", path, fileMode.String(), err)
if err := os.Chmod(filePath, fileMode); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to chmod path %#v, mode: %v, err: %v", filePath, fileMode.String(), err)
return getSFTPErrorFromOSError(err)
}
logger.CommandLog(chmodLogSender, path, "", c.User.Username, fileMode.String(), c.ID, c.protocol, -1, -1, "", "", "")
logger.CommandLog(chmodLogSender, filePath, "", c.User.Username, fileMode.String(), c.ID, c.protocol, -1, -1, "", "", "")
return nil
} else if attrFlags.UidGid {
if !c.User.HasPerm(dataprovider.PermChown, pathForPerms) {
@ -282,11 +284,11 @@ func (c Connection) handleSFTPSetstat(path string, request *sftp.Request) error
}
uid := int(request.Attributes().UID)
gid := int(request.Attributes().GID)
if err := os.Chown(path, uid, gid); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to chown path %#v, uid: %v, gid: %v, err: %v", path, uid, gid, err)
if err := os.Chown(filePath, uid, gid); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to chown path %#v, uid: %v, gid: %v, err: %v", filePath, uid, gid, err)
return getSFTPErrorFromOSError(err)
}
logger.CommandLog(chownLogSender, path, "", c.User.Username, "", c.ID, c.protocol, uid, gid, "", "", "")
logger.CommandLog(chownLogSender, filePath, "", c.User.Username, "", c.ID, c.protocol, uid, gid, "", "", "")
return nil
} else if attrFlags.Acmodtime {
if !c.User.HasPerm(dataprovider.PermChtimes, pathForPerms) {
@ -297,24 +299,24 @@ func (c Connection) handleSFTPSetstat(path string, request *sftp.Request) error
modificationTime := time.Unix(int64(request.Attributes().Mtime), 0)
accessTimeString := accessTime.Format(dateFormat)
modificationTimeString := modificationTime.Format(dateFormat)
if err := os.Chtimes(path, accessTime, modificationTime); err != nil {
if err := os.Chtimes(filePath, accessTime, modificationTime); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to chtimes for path %#v, access time: %v, modification time: %v, err: %v",
path, accessTime, modificationTime, err)
filePath, accessTime, modificationTime, err)
return getSFTPErrorFromOSError(err)
}
logger.CommandLog(chtimesLogSender, path, "", c.User.Username, "", c.ID, c.protocol, -1, -1, accessTimeString,
logger.CommandLog(chtimesLogSender, filePath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, accessTimeString,
modificationTimeString, "")
return nil
}
return nil
}
func (c Connection) handleSFTPRename(sourcePath string, targetPath string) error {
func (c Connection) handleSFTPRename(sourcePath string, targetPath string, request *sftp.Request) error {
if c.User.GetRelativePath(sourcePath) == "/" {
c.Log(logger.LevelWarn, logSender, "renaming root dir is not allowed")
return sftp.ErrSSHFxPermissionDenied
}
if !c.User.HasPerm(dataprovider.PermRename, filepath.Dir(targetPath)) {
if !c.User.HasPerm(dataprovider.PermRename, path.Dir(request.Target)) {
return sftp.ErrSSHFxPermissionDenied
}
if err := os.Rename(sourcePath, targetPath); err != nil {
@ -326,41 +328,41 @@ func (c Connection) handleSFTPRename(sourcePath string, targetPath string) error
return nil
}
func (c Connection) handleSFTPRmdir(path string) error {
if c.User.GetRelativePath(path) == "/" {
func (c Connection) handleSFTPRmdir(dirPath string, request *sftp.Request) error {
if c.User.GetRelativePath(dirPath) == "/" {
c.Log(logger.LevelWarn, logSender, "removing root dir is not allowed")
return sftp.ErrSSHFxPermissionDenied
}
if !c.User.HasPerm(dataprovider.PermDelete, filepath.Dir(path)) {
if !c.User.HasPerm(dataprovider.PermDelete, path.Dir(request.Filepath)) {
return sftp.ErrSSHFxPermissionDenied
}
var fi os.FileInfo
var err error
if fi, err = os.Lstat(path); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to remove a dir %#v: stat error: %v", path, err)
if fi, err = os.Lstat(dirPath); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to remove a dir %#v: stat error: %v", dirPath, err)
return getSFTPErrorFromOSError(err)
}
if !fi.IsDir() || fi.Mode()&os.ModeSymlink == os.ModeSymlink {
c.Log(logger.LevelDebug, logSender, "cannot remove %#v is not a directory", path)
c.Log(logger.LevelDebug, logSender, "cannot remove %#v is not a directory", dirPath)
return sftp.ErrSSHFxFailure
}
if err = os.Remove(path); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to remove directory %#v: %v", path, err)
if err = os.Remove(dirPath); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to remove directory %#v: %v", dirPath, err)
return getSFTPErrorFromOSError(err)
}
logger.CommandLog(rmdirLogSender, path, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "")
logger.CommandLog(rmdirLogSender, dirPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "")
return sftp.ErrSSHFxOk
}
func (c Connection) handleSFTPSymlink(sourcePath string, targetPath string) error {
func (c Connection) handleSFTPSymlink(sourcePath string, targetPath string, request *sftp.Request) error {
if c.User.GetRelativePath(sourcePath) == "/" {
c.Log(logger.LevelWarn, logSender, "symlinking root dir is not allowed")
return sftp.ErrSSHFxPermissionDenied
}
if !c.User.HasPerm(dataprovider.PermCreateSymlinks, filepath.Dir(targetPath)) {
if !c.User.HasPerm(dataprovider.PermCreateSymlinks, path.Dir(request.Target)) {
return sftp.ErrSSHFxPermissionDenied
}
if err := os.Symlink(sourcePath, targetPath); err != nil {
@ -372,47 +374,47 @@ func (c Connection) handleSFTPSymlink(sourcePath string, targetPath string) erro
return nil
}
func (c Connection) handleSFTPMkdir(path string) error {
if !c.User.HasPerm(dataprovider.PermCreateDirs, filepath.Dir(path)) {
func (c Connection) handleSFTPMkdir(dirPath string, request *sftp.Request) error {
if !c.User.HasPerm(dataprovider.PermCreateDirs, path.Dir(request.Filepath)) {
return sftp.ErrSSHFxPermissionDenied
}
if err := os.Mkdir(path, 0777); err != nil {
c.Log(logger.LevelWarn, logSender, "error creating missing dir: %#v error: %v", path, err)
if err := os.Mkdir(dirPath, 0777); err != nil {
c.Log(logger.LevelWarn, logSender, "error creating missing dir: %#v error: %v", dirPath, err)
return getSFTPErrorFromOSError(err)
}
utils.SetPathPermissions(path, c.User.GetUID(), c.User.GetGID())
utils.SetPathPermissions(dirPath, c.User.GetUID(), c.User.GetGID())
logger.CommandLog(mkdirLogSender, path, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "")
logger.CommandLog(mkdirLogSender, dirPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "")
return nil
}
func (c Connection) handleSFTPRemove(path string) error {
if !c.User.HasPerm(dataprovider.PermDelete, filepath.Dir(path)) {
func (c Connection) handleSFTPRemove(filePath string, request *sftp.Request) error {
if !c.User.HasPerm(dataprovider.PermDelete, path.Dir(request.Filepath)) {
return sftp.ErrSSHFxPermissionDenied
}
var size int64
var fi os.FileInfo
var err error
if fi, err = os.Lstat(path); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to remove a file %#v: stat error: %v", path, err)
if fi, err = os.Lstat(filePath); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to remove a file %#v: stat error: %v", filePath, err)
return getSFTPErrorFromOSError(err)
}
if fi.IsDir() && fi.Mode()&os.ModeSymlink != os.ModeSymlink {
c.Log(logger.LevelDebug, logSender, "cannot remove %#v is not a file/symlink", path)
c.Log(logger.LevelDebug, logSender, "cannot remove %#v is not a file/symlink", filePath)
return sftp.ErrSSHFxFailure
}
size = fi.Size()
if err := os.Remove(path); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to remove a file/symlink %#v: %v", path, err)
if err := os.Remove(filePath); err != nil {
c.Log(logger.LevelWarn, logSender, "failed to remove a file/symlink %#v: %v", filePath, err)
return getSFTPErrorFromOSError(err)
}
logger.CommandLog(removeLogSender, path, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "")
logger.CommandLog(removeLogSender, filePath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "")
if fi.Mode()&os.ModeSymlink != os.ModeSymlink {
dataprovider.UpdateUserQuota(dataProvider, c.User, -1, -size, false)
}
go executeAction(operationDelete, c.User.Username, path, "", "")
go executeAction(operationDelete, c.User.Username, filePath, "", "")
return sftp.ErrSSHFxOk
}

View file

@ -310,6 +310,26 @@ func TestSSHCommandPath(t *testing.T) {
if path != "/" {
t.Errorf("unexpected path: %v", path)
}
sshCommand.args = []string{"-t", "."}
path = sshCommand.getDestPath()
if path != "/" {
t.Errorf("unexpected path: %v", path)
}
sshCommand.args = []string{"-t", "//"}
path = sshCommand.getDestPath()
if path != "/" {
t.Errorf("unexpected path: %v", path)
}
sshCommand.args = []string{"-t", "../.."}
path = sshCommand.getDestPath()
if path != "/" {
t.Errorf("unexpected path: %v", path)
}
sshCommand.args = []string{"-t", "/.."}
path = sshCommand.getDestPath()
if path != "/" {
t.Errorf("unexpected path: %v", path)
}
}
func TestSSHCommandErrors(t *testing.T) {
@ -636,13 +656,6 @@ func TestSCPFileMode(t *testing.T) {
}
}
func TestSCPGetNonExistingDirContent(t *testing.T) {
_, err := getDirContents("non_existing")
if err == nil {
t.Errorf("get non existing dir contents must fail")
}
}
func TestSCPParseUploadMessage(t *testing.T) {
buf := make([]byte, 65535)
stdErrBuf := make([]byte, 65535)

View file

@ -3,6 +3,7 @@ package sftpd
import (
"fmt"
"io"
"io/ioutil"
"math"
"os"
"path"
@ -83,7 +84,7 @@ func (c *scpCommand) handleRecursiveUpload() error {
}
} else {
// the destination dir is now the parent directory
destPath = filepath.Join(destPath, "..")
destPath = path.Join(destPath, "..")
}
} else {
sizeToRead, name, err := c.parseUploadMessage(command)
@ -120,7 +121,7 @@ func (c *scpCommand) handleCreateDir(dirPath string) error {
c.sendErrorMessage(err.Error())
return err
}
if !c.connection.User.HasPerm(dataprovider.PermCreateDirs, filepath.Dir(p)) {
if !c.connection.User.HasPerm(dataprovider.PermCreateDirs, path.Dir(dirPath)) {
err := fmt.Errorf("Permission denied")
c.connection.Log(logger.LevelWarn, logSenderSCP, "error creating dir: %#v, permission denied", dirPath)
c.sendErrorMessage(err.Error())
@ -234,7 +235,7 @@ func (c *scpCommand) handleUpload(uploadFilePath string, sizeToRead int64) error
}
stat, statErr := os.Stat(p)
if os.IsNotExist(statErr) {
if !c.connection.User.HasPerm(dataprovider.PermUpload, filepath.Dir(p)) {
if !c.connection.User.HasPerm(dataprovider.PermUpload, path.Dir(uploadFilePath)) {
err := fmt.Errorf("Permission denied")
c.connection.Log(logger.LevelWarn, logSenderSCP, "cannot upload file: %#v, permission denied", uploadFilePath)
c.sendErrorMessage(err.Error())
@ -256,7 +257,7 @@ func (c *scpCommand) handleUpload(uploadFilePath string, sizeToRead int64) error
return err
}
if !c.connection.User.HasPerm(dataprovider.PermOverwrite, filePath) {
if !c.connection.User.HasPerm(dataprovider.PermOverwrite, uploadFilePath) {
err := fmt.Errorf("Permission denied")
c.connection.Log(logger.LevelWarn, logSenderSCP, "cannot overwrite file: %#v, permission denied", uploadFilePath)
c.sendErrorMessage(err.Error())
@ -302,7 +303,7 @@ func (c *scpCommand) sendDownloadProtocolMessages(dirPath string, stat os.FileIn
return err
}
// we send first all the files in the roor directory and then the directories
// we send first all the files in the root directory and then the directories
// for each directory we recursively call this method again
func (c *scpCommand) handleRecursiveDownload(dirPath string, stat os.FileInfo) error {
var err error
@ -312,7 +313,7 @@ func (c *scpCommand) handleRecursiveDownload(dirPath string, stat os.FileInfo) e
if err != nil {
return err
}
files, err := getDirContents(dirPath)
files, err := ioutil.ReadDir(dirPath)
if err != nil {
c.sendErrorMessage(err.Error())
return err
@ -431,7 +432,7 @@ func (c *scpCommand) handleDownload(filePath string) error {
}
if stat.IsDir() {
if !c.connection.User.HasPerm(dataprovider.PermDownload, p) {
if !c.connection.User.HasPerm(dataprovider.PermDownload, filePath) {
err := fmt.Errorf("Permission denied")
c.connection.Log(logger.LevelWarn, logSenderSCP, "error downloading dir: %#v, permission denied", filePath)
c.sendErrorMessage(err.Error())
@ -441,7 +442,7 @@ func (c *scpCommand) handleDownload(filePath string) error {
return err
}
if !c.connection.User.HasPerm(dataprovider.PermDownload, filepath.Dir(p)) {
if !c.connection.User.HasPerm(dataprovider.PermDownload, path.Dir(filePath)) {
err := fmt.Errorf("Permission denied")
c.connection.Log(logger.LevelWarn, logSenderSCP, "error downloading dir: %#v, permission denied", filePath)
c.sendErrorMessage(err.Error())
@ -732,14 +733,3 @@ func getFileModeAsString(fileMode os.FileMode, isDir bool) string {
}
return fmt.Sprintf("%v%v%v%v", s, u, g, o)
}
func getDirContents(path string) ([]os.FileInfo, error) {
var files []os.FileInfo
f, err := os.Open(path)
if err != nil {
return files, err
}
files, err = f.Readdir(-1)
f.Close()
return files, err
}

View file

@ -2589,48 +2589,48 @@ func TestUserPerms(t *testing.T) {
user.Permissions["/p/3"] = []string{dataprovider.PermChmod}
user.Permissions["/p/3/4"] = []string{dataprovider.PermChtimes}
user.Permissions["/tmp"] = []string{dataprovider.PermRename}
if !user.HasPerm(dataprovider.PermListItems, filepath.Join(user.HomeDir, "/")) {
if !user.HasPerm(dataprovider.PermListItems, "/") {
t.Error("expected permission not found")
}
if !user.HasPerm(dataprovider.PermListItems, filepath.Join(user.HomeDir, ".")) {
if !user.HasPerm(dataprovider.PermListItems, ".") {
t.Error("expected permission not found")
}
if !user.HasPerm(dataprovider.PermListItems, filepath.Join(user.HomeDir, "")) {
if !user.HasPerm(dataprovider.PermListItems, "") {
t.Error("expected permission not found")
}
if !user.HasPerm(dataprovider.PermListItems, filepath.Join(user.HomeDir, "../")) {
if !user.HasPerm(dataprovider.PermListItems, "../") {
t.Error("expected permission not found")
}
// path p and /p are the same
if !user.HasPerm(dataprovider.PermDelete, filepath.Join(user.HomeDir, "/p")) {
if !user.HasPerm(dataprovider.PermDelete, "/p") {
t.Error("expected permission not found")
}
if !user.HasPerm(dataprovider.PermDownload, filepath.Join(user.HomeDir, "/p/1")) {
if !user.HasPerm(dataprovider.PermDownload, "/p/1") {
t.Error("expected permission not found")
}
if !user.HasPerm(dataprovider.PermCreateDirs, filepath.Join(user.HomeDir, "p/2")) {
if !user.HasPerm(dataprovider.PermCreateDirs, "p/2") {
t.Error("expected permission not found")
}
if !user.HasPerm(dataprovider.PermChmod, filepath.Join(user.HomeDir, "/p/3")) {
if !user.HasPerm(dataprovider.PermChmod, "/p/3") {
t.Error("expected permission not found")
}
if !user.HasPerm(dataprovider.PermChtimes, filepath.Join(user.HomeDir, "p/3/4")) {
if !user.HasPerm(dataprovider.PermChtimes, "p/3/4/") {
t.Error("expected permission not found")
}
if !user.HasPerm(dataprovider.PermChtimes, filepath.Join(user.HomeDir, "p/3/4/../4")) {
if !user.HasPerm(dataprovider.PermChtimes, "p/3/4/../4") {
t.Error("expected permission not found")
}
// undefined paths have permissions of the nearest path
if !user.HasPerm(dataprovider.PermListItems, filepath.Join(user.HomeDir, "/p34")) {
if !user.HasPerm(dataprovider.PermListItems, "/p34") {
t.Error("expected permission not found")
}
if !user.HasPerm(dataprovider.PermListItems, filepath.Join(user.HomeDir, "/p34/p1/file.dat")) {
if !user.HasPerm(dataprovider.PermListItems, "/p34/p1/file.dat") {
t.Error("expected permission not found")
}
if !user.HasPerm(dataprovider.PermChtimes, filepath.Join(user.HomeDir, "/p/3/4/5/6")) {
if !user.HasPerm(dataprovider.PermChtimes, "/p/3/4/5/6") {
t.Error("expected permission not found")
}
if !user.HasPerm(dataprovider.PermDownload, filepath.Join(user.HomeDir, "/p/1/test/file.dat")) {
if !user.HasPerm(dataprovider.PermDownload, "/p/1/test/file.dat") {
t.Error("expected permission not found")
}
}

View file

@ -129,7 +129,7 @@ func (c *sshCommand) handleHashCommands() error {
if err != nil {
return c.sendErrorResponse(err)
}
if !c.connection.User.HasPerm(dataprovider.PermListItems, path) {
if !c.connection.User.HasPerm(dataprovider.PermListItems, sshPath) {
return c.sendErrorResponse(errPermissionDenied)
}
hash, err := computeHashForFile(h, path)
@ -149,7 +149,7 @@ func (c *sshCommand) executeSystemCommand(command systemCommand) error {
}
perms := []string{dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermCreateDirs, dataprovider.PermListItems,
dataprovider.PermOverwrite, dataprovider.PermDelete, dataprovider.PermRename}
if !c.connection.User.HasPerms(perms, command.realPath) {
if !c.connection.User.HasPerms(perms, c.getDestPath()) {
return c.sendErrorResponse(errPermissionDenied)
}
@ -299,7 +299,7 @@ func (c *sshCommand) getSystemCommand() (systemCommand, error) {
// the home dir.
// If the user cannot create symlinks we add the option --munge-links, if it is not
// already set. This should make symlinks unusable (but manually recoverable)
if c.connection.User.HasPerm(dataprovider.PermCreateSymlinks, path) {
if c.connection.User.HasPerm(dataprovider.PermCreateSymlinks, c.getDestPath()) {
if !utils.IsStringInSlice("--safe-links", args) {
args = append([]string{"--safe-links"}, args...)
}