diff --git a/changelog/unreleased/prevent-cross-storage-move.md b/changelog/unreleased/prevent-cross-storage-move.md new file mode 100644 index 0000000000..5e96f4ae71 --- /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 283e11ee38..ac5a6285d2 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 2e21b77d06..de5dfb9f93 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