Skip to content
This repository was archived by the owner on Feb 18, 2025. It is now read-only.
This repository was archived by the owner on Feb 18, 2025. It is now read-only.

sudo and $HOME #29

Open
Open

Description

@zertosh

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"?

Activity

  1. soc commented on Sep 12, 2021

    @soc
    Collaborator

    A very good observation, thanks @zertosh! I'm trying to think of a solution that "just works" but haven't found anything yet ...

  2. ClementNerma commented on May 20, 2022

    @ClementNerma

    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.

  3. hulxv commented on Jul 5, 2022

    @hulxv

    Hey, Was this issue solved or not yet?
    I have the same problem, So, Is there any solution?

  4. Kyllingene commented on Oct 3, 2023

    @Kyllingene

    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?

  5. mrjackwills commented on Jan 21, 2024

    @mrjackwills

    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.

  6. Kyllingene commented on Jan 21, 2024

    @Kyllingene

    Can I ask which OS you were running with this behaviour?

    I was testing using Fish and Arch Linux. I can test again later using bash, perhaps?

  7. mrjackwills commented on Jan 21, 2024

    @mrjackwills

    Ah ok, I'm only using bash.

    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>

  8. Kyllingene commented on Jan 23, 2024

    @Kyllingene
    <currently on fish>
    kyllingene@kyllingene ~> sudo echo $SUDO_USER
    
    kyllingene@kyllingene ~> bash
    [kyllingene@kyllingene ~]$ sudo echo $SUDO_USER
    
    [kyllingene@kyllingene ~]$
    

    I'm not getting SUDO_USER on either shell, odd.

    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.

  9. mrjackwills commented on Jan 23, 2024

    @mrjackwills

    I have the same result with sudo echo $SUDO_USER, but try sudo printenv, that should - well it does for me - list a correct SUDO_USER

  10. Kyllingene commented on Jan 26, 2024

    @Kyllingene

    You are correct. It's quite odd, because even using su gives me nothing:

    [kyllingene@kyllingene ~]$ su
    [kyllingene kyllingene]# echo $SUDO_USER
    
    [kyllingene kyllingene]#
    

    EDIT: A small test project using std::env::var also returns the proper value.

  11. soc commented on Jan 26, 2024

    @soc
    Collaborator

    So based on your observations y'all, is there any change that should be discussed?

  12. mrjackwills commented on Jan 26, 2024

    @mrjackwills

    This issue I was having was that running an application via sudo would return the wrong home dir.

    This program is called example

    fn main() {
    	let home = dirs::home_dir();
    	println!("{home:?}")
    }

    Running ./example, this it prints Some("/home/jack"), but running sudo ./example it instead prints Some("/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_USER env could help implement this.

  13. soc commented on Jan 26, 2024

    @soc
    Collaborator

    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?

  14. mrjackwills commented on Jan 26, 2024

    @mrjackwills

    I thought SUDO_USER was set as expected? It just only gets printed by printenv, rather than echo $SUDO_USER

    But if not, maybe it could try to use SUDO_USER, and if this fails, fall back to the current implementation?

  15. soc commented on Jan 26, 2024

    @soc
    Collaborator

    I wonder where the different behavior comes from ...

  16. mrjackwills commented on Jan 26, 2024

    @mrjackwills

    That I'm not sure, something about variable expansion happening before sudo is executed - which then doesn't inherit the expanded values?

  17. Kyllingene commented on Jan 26, 2024

    @Kyllingene

    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.

  18. mrjackwills commented on Jan 26, 2024

    @mrjackwills

    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

  19. Kyllingene commented on Jan 26, 2024

    @Kyllingene

    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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions