From 969c992bfd1e17a3f7e6581894132f5a818ea842 Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Mon, 31 May 2021 22:40:47 +0200 Subject: [PATCH] pre-upload: execute the hook just before opening the target file --- docs/custom-actions.md | 2 +- ftpd/handler.go | 8 ++++---- sftpd/handler.go | 11 ++++++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/custom-actions.md b/docs/custom-actions.md index 70a67639..dbd9a85b 100644 --- a/docs/custom-actions.md +++ b/docs/custom-actions.md @@ -61,7 +61,7 @@ If the `hook` defines an HTTP URL then this URL will be invoked as HTTP POST. Th - `endpoint`, included for S3, SFTP and Azure backend if configured. For Azure this is the SAS URL, if configured, otherwise the endpoint - `status`, integer. Status for `upload`, `download` and `ssh_cmd` actions. 0 means a generic error occurred. 1 means no error, 2 means quota exceeded error - `protocol`, string. Possible values are `SSH`, `SFTP`, `SCP`, `FTP`, `DAV`, `HTTP` -- `open_flags`, integer, File open flags, can be non-zero for `pre-upload` action. If `file_size` is greater than zero and `file_size&512 == 0` the target file will not be truncated +- `open_flags`, integer. File open flags, can be non-zero for `pre-upload` action. If `file_size` is greater than zero and `file_size&512 == 0` the target file will not be truncated The HTTP hook will use the global configuration for HTTP clients and will respect the retry configurations. diff --git a/ftpd/handler.go b/ftpd/handler.go index 69f38a43..98abbe42 100644 --- a/ftpd/handler.go +++ b/ftpd/handler.go @@ -388,10 +388,6 @@ func (c *Connection) handleFTPUploadToExistingFile(fs vfs.Fs, flags int, resolve c.Log(logger.LevelInfo, "denying file write due to quota limits") return nil, common.ErrQuotaExceeded } - if err := common.ExecutePreAction(&c.User, common.OperationPreUpload, resolvedPath, requestPath, c.GetProtocol(), fileSize, flags); err != nil { - c.Log(logger.LevelDebug, "upload for file %#v denied by pre action: %v", requestPath, err) - return nil, c.GetPermissionDeniedError() - } minWriteOffset := int64(0) // ftpserverlib sets: // - os.O_WRONLY | os.O_APPEND for APPE and COMB @@ -406,6 +402,10 @@ func (c *Connection) handleFTPUploadToExistingFile(fs vfs.Fs, flags int, resolve c.Log(logger.LevelDebug, "unable to get max write size: %v", err) return nil, err } + if err := common.ExecutePreAction(&c.User, common.OperationPreUpload, resolvedPath, requestPath, c.GetProtocol(), fileSize, flags); err != nil { + c.Log(logger.LevelDebug, "upload for file %#v denied by pre action: %v", requestPath, err) + return nil, c.GetPermissionDeniedError() + } if common.Config.IsAtomicUploadEnabled() && fs.IsAtomicUploadSupported() { err = fs.Rename(resolvedPath, filePath) diff --git a/sftpd/handler.go b/sftpd/handler.go index bb689bcf..1417a498 100644 --- a/sftpd/handler.go +++ b/sftpd/handler.go @@ -361,12 +361,8 @@ func (c *Connection) handleSFTPUploadToExistingFile(fs vfs.Fs, pflags sftp.FileO c.Log(logger.LevelInfo, "denying file write due to quota limits") return nil, sftp.ErrSSHFxFailure } - osFlags := getOSOpenFlags(pflags) - if err := common.ExecutePreAction(&c.User, common.OperationPreUpload, resolvedPath, requestPath, c.GetProtocol(), fileSize, osFlags); err != nil { - c.Log(logger.LevelDebug, "upload for file %#v denied by pre action: %v", requestPath, err) - return nil, c.GetPermissionDeniedError() - } + osFlags := getOSOpenFlags(pflags) minWriteOffset := int64(0) isTruncate := osFlags&os.O_TRUNC != 0 // for upload resumes OpenSSH sets the APPEND flag while WinSCP does not set it, @@ -381,6 +377,11 @@ func (c *Connection) handleSFTPUploadToExistingFile(fs vfs.Fs, pflags sftp.FileO return nil, err } + if err := common.ExecutePreAction(&c.User, common.OperationPreUpload, resolvedPath, requestPath, c.GetProtocol(), fileSize, osFlags); err != nil { + c.Log(logger.LevelDebug, "upload for file %#v denied by pre action: %v", requestPath, err) + return nil, c.GetPermissionDeniedError() + } + if common.Config.IsAtomicUploadEnabled() && fs.IsAtomicUploadSupported() { err = fs.Rename(resolvedPath, filePath) if err != nil {