Skip to content

Provide SHELL for sudo -s invocation of activation script#3040

Merged
rycee merged 2 commits intonix-community:masterfrom
toonn:sudo-s-activate
Sep 19, 2022
Merged

Provide SHELL for sudo -s invocation of activation script#3040
rycee merged 2 commits intonix-community:masterfrom
toonn:sudo-s-activate

Conversation

@toonn
Copy link
Copy Markdown
Contributor

@toonn toonn commented Jun 19, 2022

Description

In #807 I changed the flag passed to sudo from -i to -s so sudo
wouldn't use a non-existent shell defined in the passwd file. kalbasit
also reported in that PR that -i didn't work for them anymore on an M1
Mac, presumably because Apple changed something in newer versions of
macOS.

Some users reported that this broke the behavior for them because
SHELL was set to a path that didn't even exist on their system. It's
unclear how this came to be but it shows that my assumption that SHELL
would be set to a reasonable shell by Home-Manager at this point in the
activation is false.

As a way around this problem we can explicitly set SHELL when running
the activation script to a value that we know will be good, like
${pkgs.bash}.

One change in behavior this causes is that the activation script will
always be run by bash, not the user's shell. If the script is generated
by Home-Manager this is fine since it can be generated taking into
account the supported set of functions and behaviors. If the intent is
for the activation script to possibly be run by non-bash and even
non-POSIX shells, like tcsh, ksh or Xonsh, then this fix will not
suffice.

Fixes #2900

Note: I'm not sure how to test this properly, advice appreciated.

Checklist

  • Change is backwards compatible.

  • [] Code formatted with ./format.
    Couldn't do this because of a hash mismatch:

    error: ca hash mismatch importing path '/nix/store/rqc038b0jxgifl017wbmqanlp8ybk0k0-source';
          specified: sha256:0rbh9d0fskapgyzy812yxrzd87wj1jlzn46wi7ymyls2bpnbkw1g
          got:       sha256:19kaagb3ljgzhcyxcinqiskjbcasikfdbrrhvy8rj2wrxygcphmz
    

(use '--show-trace' to show detailed location information)
```

  • Code tested through nix-shell --pure tests -A run.all.

  • Test cases updated/added. See example.

  • Commit messages are formatted like

    {component}: {description}
    
    {long description}
    

    See CONTRIBUTING for more information and recent commit messages for examples.

  • If this PR adds a new module

    • Added myself as module maintainer. See example.

    • Added myself and the module files to .github/CODEOWNERS.

@toonn toonn requested a review from rycee as a code owner June 19, 2022 17:34
Comment thread nix-darwin/default.nix
@rycee
Copy link
Copy Markdown
Member

rycee commented Jun 19, 2022

LGTM but I think some nix-darwin users should give it a try before merging.

I only have a minor comments about the commit message, could you make the first line a bit shorter? I think something like

nix-darwin: improve invocation of activation script

should suffice since the rest of the excellent commit message explains things quite clearly.

Also "Home-Manager" should be "Home Manager".

About using bash for the activation script, this is an absolute requirement. We use quite a few bash specific features in the activation script. The writeShellScript function should generate a script that will get executed by bash from Nixpkgs. If SHELL is set to some odd value at this point, wouldn't it be a problem with the nix-darwin activation script?

@toonn toonn force-pushed the sudo-s-activate branch from 3c06fd5 to 0ced6d6 Compare June 20, 2022 08:58
toonn added a commit to toonn/home-manager that referenced this pull request Jun 20, 2022
In nix-community#587, kalbasit introduce the `-i` flag so the sudo invocation would
run in an environment with `HOME` set to the correct value for the
target user. This was necessary to be able to set up multiple users
without interfering with the invoking user's `HOME`.

In nix-community#807, I switched to `-s` instead because I managed to get an invalid
shell set for my user by switching `useUserPackages` from `true` to
`false` which changes the location where packages are installed and
`~/.nix-profile/bin/<my-shell>` was no longer valid. This was based on
the assumption that `SHELL` would be set to some sensible value by Home
Manager at this point. This turned out to be false as reported in nix-community#2900.

In 0ced6d6 (this commit's parent at this time), I explicitly set
`SHELL` to `${pkgs.bash}` so it is definitely set to a good shell when
invoking the activation script.

However, nix-community#807 broke activation for multiple users, the original
motivation for `-i`, as reported in nix-community#2856. I fixed this in nix-community#2857 by
additionally passing `--set-home`.

Further discussion with rycee in nix-community#3040 made me realize that the
activation script already has a good Nix store bash shebang. So all the
problems have been caused, not by the shell used for the activation
script but by sudo trying to use a different shell at all. `-i` uses the
shell set in the `passwd` file for the target user, but this can become
invalid as happened to me. `-s` uses either `SHELL` if it's defined or
the invoking user's shell as set in the `passwd` file. By explicitly
setting this to a shell provided by Nix we make sure we're not trying to
launch a non-existent shell. However, we're clearly already running in
an existing shell and because of `--set-home` we can activate other
users properly so there's not actually any need to try to have sudo
start a different shell first, it just adds an extra process that then
goes on to run the activation script with a good bash because of the
shebang.

Dropping `-s` altogether and keeping `--set-home` should avoid all of
these issues.
@toonn
Copy link
Copy Markdown
Contributor Author

toonn commented Jun 20, 2022

@rycee, thanks for the rubber ducking, you made me realize that both -i and -s were misguided and the only crucial part of -i was --set-home.

I would indeed welcome ample testing because I've made a mess of things trying to conserve the wrong part of -i's functionality.

@stale
Copy link
Copy Markdown

stale bot commented Sep 18, 2022

Thank you for your contribution! I marked this pull request as stale due to inactivity. Please read the relevant sections below before commenting.

If you are the original author of the PR

  • GitHub sometimes doesn't notify people who commented / reviewed a PR previously when you (force) push commits. If you have addressed the reviews you can officially ask for a review from those who commented to you or anyone else.
  • If it is unfinished but you plan to finish it, please mark it as a draft.
  • If you don't expect to work on it any time soon, please consider closing it with a short comment encouraging someone else to pick up your work.
  • To get things rolling again, rebase the PR against the target branch and address valid comments.

If you are not the original author of the PR

  • If you want to pick up the work on this PR, please create a new PR and indicate that it supercedes and closes this PR.

@stale stale bot added the status: stale label Sep 18, 2022
@toonn
Copy link
Copy Markdown
Contributor Author

toonn commented Sep 19, 2022

As far as I'm concerned this is ready for merge. I have no way to test this because I can't reproduce the issue from #2900 but I'm fairly confident this is the proper fix.

@stale stale bot removed the status: stale label Sep 19, 2022
In nix-community#807 I changed the flag passed to `sudo` from `-i` to `-s` so
`sudo` wouldn't use a non-existent shell defined in the `passwd` file.
kalbasit also reported in that PR that `-i` didn't work for them
anymore on an M1 Mac, presumably because Apple changed something in
newer versions of macOS.

Some users reported that this broke the behavior for them because
`SHELL` was set to a path that didn't even exist on their system. It's
unclear how this came to be but it shows that my assumption that
`SHELL` would be set to a reasonable shell by Home Manager at this
point in the activation is false.

As a way around this problem we can explicitly set `SHELL` when
running the activation script to a value that we know will be good,
like `${pkgs.bash}`.

One change in behavior this causes is that the activation script will
always be run by bash, not the user's shell. If the script is
generated by Home Manager this is fine since it can be generated
taking into account the supported set of functions and behaviors. If
the intent is for the activation script to possibly be run by non-bash
and even non-POSIX shells, like tcsh, ksh or Xonsh, then this fix will
not suffice. Turns out this is indeed an assumption made by Home
Manager, so this is the proper behavior.

Fixes nix-community#2900
In nix-community#587, kalbasit introduce the `-i` flag so the sudo invocation would
run in an environment with `HOME` set to the correct value for the
target user. This was necessary to be able to set up multiple users
without interfering with the invoking user's `HOME`.

In nix-community#807, I switched to `-s` instead because I managed to get an
invalid shell set for my user by switching `useUserPackages` from
`true` to `false` which changes the location where packages are
installed and `~/.nix-profile/bin/<my-shell>` was no longer valid.
This was based on the assumption that `SHELL` would be set to some
sensible value by Home Manager at this point. This turned out to be
false as reported in nix-community#2900.

In 0ced6d6 (this commit's parent at this time), I explicitly set
`SHELL` to `${pkgs.bash}` so it is definitely set to a good shell when
invoking the activation script.

However, nix-community#807 broke activation for multiple users, the original
motivation for `-i`, as reported in nix-community#2856. I fixed this in nix-community#2857 by
additionally passing `--set-home`.

Further discussion with rycee in nix-community#3040 made me realize that the
activation script already has a good Nix store bash shebang. So all
the problems have been caused, not by the shell used for the
activation script but by sudo trying to use a different shell at all.
`-i` uses the shell set in the `passwd` file for the target user, but
this can become invalid as happened to me. `-s` uses either `SHELL` if
it's defined or the invoking user's shell as set in the `passwd` file.
By explicitly setting this to a shell provided by Nix we make sure
we're not trying to launch a non-existent shell. However, we're
clearly already running in an existing shell and because of
`--set-home` we can activate other users properly so there's not
actually any need to try to have sudo start a different shell first,
it just adds an extra process that then goes on to run the activation
script with a good bash because of the shebang.

Dropping `-s` altogether and keeping `--set-home` should avoid all of
these issues.
@rycee rycee merged commit 9555918 into nix-community:master Sep 19, 2022
@rycee
Copy link
Copy Markdown
Member

rycee commented Sep 19, 2022

Yeah, I think enough time has passed. I've merged to master now and we'll see if that produces any additional feedback. Thanks a lot for the fixing!

austinharris pushed a commit to austinharris/home-manager that referenced this pull request Dec 23, 2022
In nix-community#587, kalbasit introduce the `-i` flag so the sudo invocation would
run in an environment with `HOME` set to the correct value for the
target user. This was necessary to be able to set up multiple users
without interfering with the invoking user's `HOME`.

In nix-community#807, I switched to `-s` instead because I managed to get an
invalid shell set for my user by switching `useUserPackages` from
`true` to `false` which changes the location where packages are
installed and `~/.nix-profile/bin/<my-shell>` was no longer valid.
This was based on the assumption that `SHELL` would be set to some
sensible value by Home Manager at this point. This turned out to be
false as reported in nix-community#2900.

In 0ced6d6 (this commit's parent at this time), I explicitly set
`SHELL` to `${pkgs.bash}` so it is definitely set to a good shell when
invoking the activation script.

However, nix-community#807 broke activation for multiple users, the original
motivation for `-i`, as reported in nix-community#2856. I fixed this in nix-community#2857 by
additionally passing `--set-home`.

Further discussion with rycee in nix-community#3040 made me realize that the
activation script already has a good Nix store bash shebang. So all
the problems have been caused, not by the shell used for the
activation script but by sudo trying to use a different shell at all.
`-i` uses the shell set in the `passwd` file for the target user, but
this can become invalid as happened to me. `-s` uses either `SHELL` if
it's defined or the invoking user's shell as set in the `passwd` file.
By explicitly setting this to a shell provided by Nix we make sure
we're not trying to launch a non-existent shell. However, we're
clearly already running in an existing shell and because of
`--set-home` we can activate other users properly so there's not
actually any need to try to have sudo start a different shell first,
it just adds an extra process that then goes on to run the activation
script with a good bash because of the shebang.

Dropping `-s` altogether and keeping `--set-home` should avoid all of
these issues.
spacekookie pushed a commit to spacekookie/home-manager that referenced this pull request Feb 10, 2023
In nix-community#587, kalbasit introduce the `-i` flag so the sudo invocation would
run in an environment with `HOME` set to the correct value for the
target user. This was necessary to be able to set up multiple users
without interfering with the invoking user's `HOME`.

In nix-community#807, I switched to `-s` instead because I managed to get an
invalid shell set for my user by switching `useUserPackages` from
`true` to `false` which changes the location where packages are
installed and `~/.nix-profile/bin/<my-shell>` was no longer valid.
This was based on the assumption that `SHELL` would be set to some
sensible value by Home Manager at this point. This turned out to be
false as reported in nix-community#2900.

In 0ced6d6 (this commit's parent at this time), I explicitly set
`SHELL` to `${pkgs.bash}` so it is definitely set to a good shell when
invoking the activation script.

However, nix-community#807 broke activation for multiple users, the original
motivation for `-i`, as reported in nix-community#2856. I fixed this in nix-community#2857 by
additionally passing `--set-home`.

Further discussion with rycee in nix-community#3040 made me realize that the
activation script already has a good Nix store bash shebang. So all
the problems have been caused, not by the shell used for the
activation script but by sudo trying to use a different shell at all.
`-i` uses the shell set in the `passwd` file for the target user, but
this can become invalid as happened to me. `-s` uses either `SHELL` if
it's defined or the invoking user's shell as set in the `passwd` file.
By explicitly setting this to a shell provided by Nix we make sure
we're not trying to launch a non-existent shell. However, we're
clearly already running in an existing shell and because of
`--set-home` we can activate other users properly so there's not
actually any need to try to have sudo start a different shell first,
it just adds an extra process that then goes on to run the activation
script with a good bash because of the shebang.

Dropping `-s` altogether and keeping `--set-home` should avoid all of
these issues.
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.

bug: Activation script fails after sudo attempts to use an invalid shell

2 participants