From 1b764199b58b0602d4a1495c5d25c64036d8c0b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 7 Jul 2022 07:35:20 +0000 Subject: [PATCH] prevent cross storage move (#3035) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- .../unreleased/prevent-cross-storage-move.md | 5 ++++ internal/http/services/owncloud/ocdav/move.go | 24 ++++++++++++++----- pkg/storage/utils/decomposedfs/tree/tree.go | 9 +++++++ 3 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 changelog/unreleased/prevent-cross-storage-move.md diff --git a/changelog/unreleased/prevent-cross-storage-move.md b/changelog/unreleased/prevent-cross-storage-move.md new file mode 100644 index 00000000000..5e96f4ae71d --- /dev/null +++ b/changelog/unreleased/prevent-cross-storage-move.md @@ -0,0 +1,5 @@ +Bugfix: Prevent cross space move + +decomposedfs now prevents moving across space boundaries + +https://github.com/cs3org/reva/pull/3035 diff --git a/internal/http/services/owncloud/ocdav/move.go b/internal/http/services/owncloud/ocdav/move.go index 283e11ee388..ac5a6285d20 100644 --- a/internal/http/services/owncloud/ocdav/move.go +++ b/internal/http/services/owncloud/ocdav/move.go @@ -31,6 +31,7 @@ import ( "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spacelookup" "github.com/cs3org/reva/v2/pkg/appctx" "github.com/cs3org/reva/v2/pkg/errtypes" + rstatus "github.com/cs3org/reva/v2/pkg/rgrpc/status" "github.com/cs3org/reva/v2/pkg/rhttp/router" "github.com/cs3org/reva/v2/pkg/storagespace" "github.com/cs3org/reva/v2/pkg/utils" @@ -256,13 +257,24 @@ func (s *svc) handleMove(ctx context.Context, w http.ResponseWriter, r *http.Req } if mRes.Status.Code != rpc.Code_CODE_OK { - if mRes.Status.Code == rpc.Code_CODE_PERMISSION_DENIED { - w.WriteHeader(http.StatusForbidden) - m := fmt.Sprintf("Permission denied to move %v", src.Path) - b, err := errors.Marshal(http.StatusForbidden, m, "") - errors.HandleWebdavError(&log, w, b, err) + status := rstatus.HTTPStatusFromCode(mRes.Status.Code) + m := mRes.Status.Message + switch mRes.Status.Code { + case rpc.Code_CODE_ABORTED: + status = http.StatusPreconditionFailed + case rpc.Code_CODE_UNIMPLEMENTED: + // We translate this into a Bad Gateway error as per https://www.rfc-editor.org/rfc/rfc4918#section-9.9.4 + // > 502 (Bad Gateway) - This may occur when the destination is on another + // > server and the destination server refuses to accept the resource. + // > This could also occur when the destination is on another sub-section + // > of the same server namespace. + status = http.StatusBadGateway } - errors.HandleErrorStatus(&log, w, mRes.Status) + + w.WriteHeader(status) + + b, err := errors.Marshal(status, m, "") + errors.HandleWebdavError(&log, w, b, err) return } diff --git a/pkg/storage/utils/decomposedfs/tree/tree.go b/pkg/storage/utils/decomposedfs/tree/tree.go index 2e21b77d06c..de5dfb9f939 100644 --- a/pkg/storage/utils/decomposedfs/tree/tree.go +++ b/pkg/storage/utils/decomposedfs/tree/tree.go @@ -310,6 +310,15 @@ func (t *Tree) CreateDir(ctx context.Context, n *node.Node) (err error) { // Move replaces the target with the source func (t *Tree) Move(ctx context.Context, oldNode *node.Node, newNode *node.Node) (err error) { + if oldNode.SpaceID != newNode.SpaceID { + // WebDAV RFC https://www.rfc-editor.org/rfc/rfc4918#section-9.9.4 says to use + // > 502 (Bad Gateway) - This may occur when the destination is on another + // > server and the destination server refuses to accept the resource. + // > This could also occur when the destination is on another sub-section + // > of the same server namespace. + // but we only have a not supported error + return errtypes.NotSupported("cannot move across spaces") + } // if target exists delete it without trashing it if newNode.Exists { // TODO make sure all children are deleted