Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove paste into folder functionality, Check for the existence of a file or directory when pasting #457

Merged
merged 4 commits into from
Jun 3, 2024

Conversation

jelly
Copy link
Member

@jelly jelly commented May 16, 2024

When copy pasting pass the --archive flag to cp so permissions are retained. This also allows us to enable superuser try as permissions are now retained.

Related: #435

@jelly
Copy link
Member Author

jelly commented May 21, 2024

Let's add --interactive as well and .input() and fail if there is a conflict as we have no conflict handling.

@jelly
Copy link
Member Author

jelly commented May 23, 2024

conclusion from Matrix discussion with @allisonkarlitskaya , drop paste into folder and detect with fsinfo if we try to paste into an existing file or dir and then refuse.

Copy link
Member

@martinpitt martinpitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, but I put a very hard "no" on this. This has "exploit!" written all over it in big bold letters. The status quo is much preferable IMHO.

We keep running into these permission problems -- perhaps in version 1 we should restrict ourselves to files/dirs owned by the user (home dir) and run everything without superuser, or files/dirs owned by root and then do all copies as root. The rest would be a "sorry, not currently supported" thing.

Comment on lines 484 to 485
if (err.message.match(/cp: overwrite .*?/)) {
addAlert(_("Paste failed, not overwriting files"), "danger", new Date().getTime());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that's quite hackish, and the error message doesn't contain the conflicting file, so for large directories it may be hard to see what's wrong? If you parse error messages anyway, perhaps capture the .* in group and show it as "not overwriting $0"?

Not a blocker, but this feels like "we really should fix this" material.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This no longer exists? I am not sure where you found it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, my first review round only applied to the first commit, and I forgot to review the other commits. But let's sort out the central superuser question first.

Comment on lines 909 to 919
runuser -u admin echo "test_text" > /home/admin/newfile
runuser -u admin touch /home/admin/newfile
echo "test_text" > /home/admin/newfile
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does that change? If the file already exists, then echoing as root should not change the permissions. And if you do expect that, why touch it first?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I should just echo as runuser...

Comment on lines 933 to 945
b.wait_visible("[data-item='copyDir']")
b.click("[data-item='copyDir']")
b.wait_text("#description-list-owner dd", "admin")
b.wait_text("#description-list-group dd", "users")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this. The hunk above changes the copy source from 'newfile' to 'copyDir' -- but here you again loko at the copy source, not the pasted version in newdir? (This is a bit hard to read and could use some comment)

b.mouse("[data-item='newfile']", "contextmenu")
b.click(".contextMenu button:contains('Copy')")

b.click(".breadcrumb-button:nth-of-type(4)")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic numbers -- could use comments into which directory that changes.

Comment on lines 966 to 950
b.wait_visible("[data-item='newfile']")
b.wait_visible("[data-item='newfile2']")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point of this PR is to retain permissions, so this could check that the testdir/newfile* copies are still owned by admin:admin?

...sourcePath,
targetPath
]).catch(err => addAlert(err.message, "danger", new Date().getTime()));
], { superuser: "try", environ: ["LC_ALL=C"] }).input()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somehow GH ate my most important comment at all: This is a major security hole. If you copy a dir from e.g. /home/joe to /home/jane, or /tmp/download/ into /var/lib/postgresql, you give the source user a foot into the door of the target user. The CLI default is quite deliberately to copy files as root, to avoid this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And how about mv /home/joe/x /home/jane/x?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I mean to say is:

The CLI default is quite deliberately to copy files as root, to avoid this.

"citation needed".

I know you're very much allergic to this "different owner than parent directory" thing but other very common coreutils commands do exactly what you're suggesting is so evil, by default.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That creates the same problem of course, but indeed unfortunately there's no warning. Of course on the CLI you, shouldn't do that, but the CLI gives you all sorts of ways to shoot yourself into the foot.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, pasting something feels more like a clipboard, and it's not at all obvious during that operation what the source/target owner will be. mv /home/joe /home/jane is at least very explicit.

@martinpitt
Copy link
Member

we should restrict ourselves to files/dirs owned by the user (home dir) and run everything without superuser, or files/dirs owned by root and then do all copies as root.

I think we can generalize this: We only support copying files (or copy/paste etc.) if the source and target directories have the same owner. Then superuser and --archive should be safe.

@jelly
Copy link
Member Author

jelly commented May 28, 2024

we should restrict ourselves to files/dirs owned by the user (home dir) and run everything without superuser, or files/dirs owned by root and then do all copies as root.

I think we can generalize this: We only support copying files (or copy/paste etc.) if the source and target directories have the same owner. Then superuser and --archive should be safe.

The goal of this PR is to get something releasable but we keep getting stuck on discussions around permissions. I am not saying they are important but I feel that we are missing the big picture here.

So this whole PR aims to:

  • Disallow paste into folder, so we don't have to deal with conflict files when pasting
  • Error out when pasting and the directory name already exists (This is really not a great UI but we can improve on it)
  • When copying retain permissions, because you for sure want to keep mode,ownership,timestamps properties.

So I am fine with dropping superuser: try and putting that on the $things to be figured out with permissions. As we did the same for upload.

@martinpitt
Copy link
Member

So this whole PR aims to:

Disallow paste into folder, so we don't have to deal with conflict files when pasting

Where else would you paste stuff if not a folder (directory)? Do you mean copying folders and pasting them? I.e. you only want to support copy&paste for individual files?

Error out when pasting and the directory name already exists (This is really not a great UI but we can improve on it)

Big 👍

When copying retain permissions, because you for sure want to keep mode,ownership,timestamps properties.

I for sure don't want that 😁 Keeping timestamps is also rather dubious -- I didn't think of that in my review, and I don't want it either, but I'd let that slide.

@jelly
Copy link
Member Author

jelly commented May 28, 2024

So this whole PR aims to:

Disallow paste into folder, so we don't have to deal with conflict files when pasting

Where else would you paste stuff if not a folder (directory)? Do you mean copying folders and pasting them? I.e. you only want to support copy&paste for individual files?

It does support that.

Error out when pasting and the directory name already exists (This is really not a great UI but we can improve on it)

Big 👍

When copying retain permissions, because you for sure want to keep mode,ownership,timestamps properties.

I for sure don't want that 😁 Keeping timestamps is also rather dubious -- I didn't think of that in my review, and I don't want it either, but I'd let that slide.

Uhhh, the more I read the more I want to nuke this feature.

cockpit.spawn([
"cp",
"-R",
...sourcePath,
"--archive",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This includes file permissions, which in particular means that it will happily copy suid/sgid binaries or world-writable directories. This also is not desirable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That no longer happens as superuser so is it ok then? Otherwise hmm we need to scrap the whole functionality.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, without superuser it seems fine to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have created #467 for most of the mentioned / issues with copy / pasting.

jelly added 2 commits May 29, 2024 11:41
This is brittle when we add new menu entries or change the order.
We want to disallow pasting into a folder until we have a good way to
detect if the folder contains something we are pasting into it. The plan
is to in the future handle conflicts when pasting, then we will revise
the paste into folder situation.
@jelly
Copy link
Member Author

jelly commented May 29, 2024

@martinpitt I've reworked the whole PR, so now the code and test changes are together and hopefully this addresses all your comments.

@jelly jelly requested a review from martinpitt May 29, 2024 10:20
@martinpitt martinpitt changed the title Retain permissions when copy/pasting Remove paste into folder functionality, Check for the existence of a file or directory when pasting May 29, 2024
Copy link
Member

@martinpitt martinpitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This is by and large ok now, and if you can't see it any more I'll change to +1.

src/fileActions.jsx Show resolved Hide resolved
test/check-application Show resolved Hide resolved
const currentPath = path.join("/") + "/";
const menuItems = [];

const spawnPaste = (sourcePaths, targetPath) => {
if (sourcePaths.some(sourcePath => cwdInfo?.entries[basename(sourcePath)])) {
addAlert(_("Paste not overwriting existing files"), "danger", "paste-error");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not the nicest English, and for many files it'd be good to give a hint -- perhaps "$0 exists, not overwriting with paste". Garrett may have a better idea.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworked too:

image

For now we don't have conflict resolution implemented yet for copy and
paste so disallow pasting when any of the targets exist.
Comment on lines +57 to +58
if (elements.length === 0) {
return '/';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 2 added lines are not executed by any test.

@jelly jelly requested a review from martinpitt June 3, 2024 08:02
Copy link
Member

@martinpitt martinpitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dankjewel!

@martinpitt martinpitt merged commit 95b76dd into cockpit-project:main Jun 3, 2024
12 checks passed
@jelly jelly deleted the cp-as-admin branch June 3, 2024 08:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants