0

Trying to run a systemd service with systemctl --user start foo.service which contains ExecStart=touch /bar/baz where /bar has permissions drwxrwxr-x 1 root storage. The user running the command belongs to the group storage and can run the touch command from the shell without issue, creating the file. The service, however, fails with a permission error.

I thought that the service's permissions would match the user running it - and indeed having the service use the ${USER} environment variable in its command does produce my user, and the service appears in my ps or pstree ${USER} lists.

foo.service does not contain ProtectSystem or any entry other than: Description, EnvironmentFile, Environment, ExecStart, KillSignal, Restart, RestartSec. The environment entries are to load non-permission-related configuration.

Does the service not actually use the calling user for permissions? And if not what would be the best approach to solve the issue? /bar is on a mounted drive, so I can just dmask 0000 in my fstab, but I'd rather avoid this approach.

2
  • Change your ExecStart= to point to an executable bash script that does (echo "=== id ===";id;echo "=== set ===";set;echo "=== env ===";env | sort;echo "=== alias ===";alias)>/tmp/foo.log Commented Oct 5, 2024 at 2:34
  • After a restart the service runs as expected and calling id from the service shows the storage group. My guess is that the group status wasn't propagated correctly somehow. Not sure how exactly - I logged out and it did work when ran manually. Maybe some lingering systemd state? Commented Oct 5, 2024 at 12:12

1 Answer 1

1

Does the service not actually use the calling user for permissions?

It does, but indirectly, because systemctl does not spawn processes on its own – it only contacts the systemd --user service manager, so the group membership of your user services will always be inherited from the service manager process, not from the caller which ran systemctl.

The --user service manager indeed runs under your own user account, but is actually started as a background service (user@<uid>.service) and its group membership is initialized separately from that of your logon session. There is only one instance per UID shared across all sessions, so it will keep the group membership from the time you first logged in to the system, even if you added yourself to other groups later.

If you log out from all sessions (and don't have the 'linger' flag in loginctl), the service manager exits after a ~10 second idle delay. So any change in group membership will only propagate if you a) log out and wait 10s for the service manager to exit, or b) manually restart your [email protected] instance (at risk of killing your entire GUI session with it).

1
  • This tracks to what I thought might have happened, thanks for the explainer. Commented Oct 6, 2024 at 19:12

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.