You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Feb 18, 2025. It is now read-only.
Repository navigation
This repository was archived by the owner on Feb 18, 2025. It is now read-only.
When running with sudo, dirs-rs returns directories for the user calling sudo and not the user that's running under sudo.
On the surface this can seem like expected behavior but it becomes a real problem when a tool is run with sudo, uses dirs::cache_dir, and ends up creating that directory when it doesn't exist.
Unsetting $HOME before using dirs-rs causes dirs-sys-rs's home_dir to use getpwuid_r in the "fallback" logic. This ends up returning the home dir for the user running under sudo. But it's a really ugly workaround. Although sudo has an -H flag to replace $HOME, you don't tend to expect a tool to end up creating a ~/.cache owned by say root when you don't use -H.
I'm not sure if it's a good idea to never trust $HOME, but would it be possible to offer another set of methods that use the "real home dir"?
There isn't an universal solution, but you can take a look at the SUDO_USER variable. It is defined by default when running sudo and contains the user that called sudo itself. AFAIK it is either defined with the correct user name, or not defined at all, it should never contain root unless the calling user was root itself.
I was looking at solving this, but the sudo manual describes SUDO_USER as "Set to the login name of the user who invoked sudo," although for me it remains unset. That seems like the bad behavior we're trying to avoid.
Would simply using the fallback function be an acceptable solution?
I was looking at solving this, but the sudo manual describes SUDO_USER as "Set to the login name of the user who invoked sudo," although for me it remains unset. That seems like the bad behavior we're trying to avoid.
Would simply using the fallback function be an acceptable solution?
Can I ask which OS you were running with this behaviour?
I have just run into this sudo issue with an application I am working on, and on all the systems I've tested on (albeit on a couple of Ubuntu systems, and a couple or raspberry pi's running PiOs), the SUDO_USER is set, and could help solve this issue.
Could a potential fix for this first check for SUDO_USER, and then fall back to USER? That's basically what I've implemented for my application, using the std::env::var("SUDO_USER") method, to return an Option<String>
Could a potential fix for this first check for SUDO_USER, and then fall back to USER?
Perhaps I'm misunderstanding, but I thought the goal was to make dirs::cache_dir et. al. return /root/* (or the equivalent) when running as root? Otherwise the behavior matches what we currently have, which leads to permissions issues.
And now it seems that SUDO_USER is not set as expected?
Which, if we used SUDO_USER would lead to different results based on it being there, as far as I understand?
SUDO_USER is set properly when using std::env::var, which is all that really matters for this issue.
I'm thoroughly confused at this point. I tested with dirs{,_sys}::{home,cache}_dir, and I got /root and /root/.cache respectively (regardless of whether or not HOME was set). This differs from the behavior in the issue, and seems to me to be the expected behavior?
I, although this may be a mistaken belief, think that both of these executions should return the same result, i.e. Some("/home/jack").
This seems like something dirs-rs should support, but I disagree that it should be the default. If it were, it would lead to problems as described in the original issue (even if I can't reproduce them myself). However, something like user_home_dir could be useful, with documentation clarifying the difference. The trick would be making such a method cross-platform, to which I haven't given much thought yet.
Yeah probably a good idea not to replace current behavior, and instead have a new function.
What cross platform issues do you envision? Running the aforementioned example application in Windows, as a normal user, and then as an elevated admin user, results in the same, correct, result each time Some("C:\\Users\\jack").
I don't currently have access to macOS, so sadly can't test on there
That's true, Windows doesn't really have the same concepts so the two functions would essentially alias. I don't know what the behavior on Mac would be, perhaps someone here has one they could test on?
Activity
soc commentedon Sep 12, 2021
A very good observation, thanks @zertosh! I'm trying to think of a solution that "just works" but haven't found anything yet ...
ClementNerma commentedon May 20, 2022
There isn't an universal solution, but you can take a look at the
SUDO_USERvariable. It is defined by default when runningsudoand contains the user that calledsudoitself. AFAIK it is either defined with the correct user name, or not defined at all, it should never containrootunless the calling user wasrootitself.hulxv commentedon Jul 5, 2022
Hey, Was this issue solved or not yet?
I have the same problem, So, Is there any solution?
Kyllingene commentedon Oct 3, 2023
I was looking at solving this, but the sudo manual describes
SUDO_USERas "Set to the login name of the user who invoked sudo," although for me it remains unset. That seems like the bad behavior we're trying to avoid.Would simply using the
fallbackfunction be an acceptable solution?mrjackwills commentedon Jan 21, 2024
Can I ask which OS you were running with this behaviour?
I have just run into this sudo issue with an application I am working on, and on all the systems I've tested on (albeit on a couple of Ubuntu systems, and a couple or raspberry pi's running PiOs), the
SUDO_USERis set, and could help solve this issue.Kyllingene commentedon Jan 21, 2024
I was testing using Fish and Arch Linux. I can test again later using bash, perhaps?
mrjackwills commentedon Jan 21, 2024
Ah ok, I'm only using bash.
Could a potential fix for this first check for
SUDO_USER, and then fall back toUSER? That's basically what I've implemented for my application, using thestd::env::var("SUDO_USER")method, to return anOption<String>Kyllingene commentedon Jan 23, 2024
I'm not getting
SUDO_USERon either shell, odd.Perhaps I'm misunderstanding, but I thought the goal was to make
dirs::cache_diret. al. return/root/*(or the equivalent) when running as root? Otherwise the behavior matches what we currently have, which leads to permissions issues.mrjackwills commentedon Jan 23, 2024
I have the same result with
sudo echo $SUDO_USER, but trysudo printenv, that should - well it does for me - list a correctSUDO_USERKyllingene commentedon Jan 26, 2024
You are correct. It's quite odd, because even using
sugives me nothing:EDIT: A small test project using
std::env::varalso returns the proper value.soc commentedon Jan 26, 2024
So based on your observations y'all, is there any change that should be discussed?
mrjackwills commentedon Jan 26, 2024
This issue I was having was that running an application via sudo would return the wrong home dir.
This program is called
exampleRunning
./example, this it printsSome("/home/jack"), but runningsudo ./exampleit instead printsSome("/root").I, although this may be a mistaken belief, think that both of these executions should return the same result, i.e.
Some("/home/jack").I haven't delved into the code properly, but my assumption was that the
SUDO_USERenv could help implement this.soc commentedon Jan 26, 2024
And now it seems that
SUDO_USERis not set as expected?Which, if we used
SUDO_USERwould lead to different results based on it being there, as far as I understand?mrjackwills commentedon Jan 26, 2024
I thought
SUDO_USERwas set as expected? It just only gets printed byprintenv, rather thanecho $SUDO_USERBut if not, maybe it could try to use
SUDO_USER, and if this fails, fall back to the current implementation?soc commentedon Jan 26, 2024
I wonder where the different behavior comes from ...
mrjackwills commentedon Jan 26, 2024
That I'm not sure, something about variable expansion happening before sudo is executed - which then doesn't inherit the expanded values?
Kyllingene commentedon Jan 26, 2024
SUDO_USERis set properly when usingstd::env::var, which is all that really matters for this issue.I'm thoroughly confused at this point. I tested with
dirs{,_sys}::{home,cache}_dir, and I got/rootand/root/.cacherespectively (regardless of whether or notHOMEwas set). This differs from the behavior in the issue, and seems to me to be the expected behavior?This seems like something
dirs-rsshould support, but I disagree that it should be the default. If it were, it would lead to problems as described in the original issue (even if I can't reproduce them myself). However, something likeuser_home_dircould be useful, with documentation clarifying the difference. The trick would be making such a method cross-platform, to which I haven't given much thought yet.mrjackwills commentedon Jan 26, 2024
Yeah probably a good idea not to replace current behavior, and instead have a new function.
What cross platform issues do you envision? Running the aforementioned
exampleapplication in Windows, as a normal user, and then as an elevated admin user, results in the same, correct, result each timeSome("C:\\Users\\jack").I don't currently have access to macOS, so sadly can't test on there
Kyllingene commentedon Jan 26, 2024
That's true, Windows doesn't really have the same concepts so the two functions would essentially alias. I don't know what the behavior on Mac would be, perhaps someone here has one they could test on?