Shutdown not working from daemonized service

I have a remote machine that I want to be able to shutdown remotely. The remote machine is running fetchmail as a daemon service which is started automatically and run under the user ‘fetchmail’. It periodically polls a POP3 account and when the suitable email is retrieved the command is run from a script file called by fetchmail:

sudo shutdown +1

is run. But it does not shutdown. The code is the script file is defiantly run as I can put in debug code around it to prove it.

The /etc/sudoers.d/incommingmail file has the following in it to allow shutdown to be run by fetchmail:

fetchmail  ALL=(ALL) NOPASSWD: /sbin/service, /usr/bin/wg-quick, /sbin/shutdown

The stanage thing is that if I run fetchmail in foreground as user fetchmail it works (note this is from a standard user not root)!

julian@skylab:~> sudo -u fetchmail fetchmail -f /etc/fetchmailrc
fetchmail: warning: multidrop for 192.168.100.1 requires envelope option!
fetchmail: warning: Do not ask for support if all mail goes to postmaster!
1 message for skylab at 192.168.100.1 (2681 octets).
Shutdown scheduled for Wed 2022-05-18 11:35:31 BST, use 'shutdown -c' to cancel.
reading message skylab@192.168.100.1:1 of 1 (2681 octets) flushed
julian@skylab:~>  

Any ideas?

The other strange thing is that this used to work.

@JulinaB:

And there’s nothing in the systemd Journal indicating why the call to shutdown via sudo failed?

Not that I can see. I am just looking at the last 50 lines and nothing is added when fetchmail picks up the email via POP3.

/var/log/fetchmail has this at the end:

fetchmail: Query status=2 (SOCKET)fetchmail: 1 message for skylab at 192.168.100.1 (2547 octets).
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?fetchmail: reading message skylab@192.168.100.1:1 of 1 (2547 octets) flushed

I guess the line:

sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root

Is trying to tell me something but not sure what.

ls -al /usr/bin/sudo
-rwsr-xr-x 1 root root 184728 Mar  9 07:35 /usr/bin/sudo
skylab:~ # 

And the whole file system is in a single ext4 filesystem.

I actually have several commands that are triggered by emails. All those that require elevated privileges (i.e. use sudo) fail but work from the command line.

As such I think it’s an issue with ‘sudo’ not working from the daemonised fetchmail service.

Just a shot in the dark.

henk@boven:~> l /sbin/shutdown
lrwxrwxrwx 1 root root 18 May  6 14:33 /sbin/shutdown -> /usr/bin/systemctl*
henk@boven:~> l /sbin/service
lrwxrwxrwx 1 root root 17 Mar 14 10:48 /sbin/service -> /usr/sbin/service*
henk@boven:~>

(I do not have a /usr/bin/wg-*)

They are symlinks. I do not know much of sudo, but shouldn’t the real executable be allowed instead of the symlink?

No, but PATH in service environment may be different from PATH in user session …

Post full unit definition that is used to start fetchmail service.

If I kill the daemon started by systemd and then manually start it as follows (using the same command arguments), but do so by sudoing to the same fetchmail user:

skylab:~ # ps -ef | grep fetch
fetchma+  1492     1  0 12:48 ?        00:00:00 /usr/bin/fetchmail -d 60 -a -L /var/log/fetchmail -f /etc/fetchmailrc
root      7951  7902  0 14:06 pts/0    00:00:00 grep --color=auto fetch
skylab:~ # kill 1492
skylab:~ # ps -ef | grep fetch
root      7977  7902  0 14:06 pts/0    00:00:00 grep --color=auto fetch
skylab:~ # sudo -u fetchmail /usr/bin/fetchmail -d 60 -a -L /var/log/fetchmail -f /etc/fetchmailrc
fetchmail: warning: multidrop for 192.168.100.1 requires envelope option!
fetchmail: warning: Do not ask for support if all mail goes to postmaster!
skylab:~ # ps -ef | grep fetch
fetchma+  7981     1  0 14:07 ?        00:00:00 /usr/bin/fetchmail -d 60 -a -L /var/log/fetchmail -f /etc/fetchmailrc
root      7983  7902  0 14:07 pts/0    00:00:00 grep --color=auto fetch

It works! So there is something about the service that is started by systemd that prevents sudo working.

This is the /etc/systemd/system/multi-user.target.wants/fetchmail.service file.


[Unit]
Description=A remote-mail retrieval utility
After=network.target


[Service]
# added automatically, for details please see
# https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort
PrivateDevices=true
ProtectHostname=true
ProtectClock=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
RestrictRealtime=true
# end of automatic additions
EnvironmentFile=-/etc/sysconfig/fetchmail
User=fetchmail
ExecStart=/usr/lib/fetchmail-systemd-exec
RestartSec=1


[Install]
WantedBy=multi-user.target



/usr/bin/sudo is, of course and you show it elsewhere, a SUID file. But for some reason it thinks that it is not running “as root”. Which could be the case when the sudo file is on a file system that is mounted with the option nosuid. Something that one, out of security reasons, often does with file systems that not normally are part of the system, including NFS. That though are only suggestions given to you because it seems not to be SUID.

But it is very strange because we all see it is and you can use sudo normally from the shell.

Show “systemctl cat fetchmail.service”.

skylab:~ # systemctl cat fetchmail.service
# /usr/lib/systemd/system/fetchmail.service
[Unit]
Description=A remote-mail retrieval utility
After=network.target


[Service]
# added automatically, for details please see
# https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort
PrivateDevices=true
ProtectHostname=true
ProtectClock=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
RestrictRealtime=true
# end of automatic additions 
EnvironmentFile=-/etc/sysconfig/fetchmail
User=fetchmail
ExecStart=/usr/lib/fetchmail-systemd-exec
RestartSec=1


[Install]
WantedBy=multi-user.target
skylab:~ # 

I have found that commenting out all the Protect & Restrict lines gets it working. Just need to find out which line is the critical one.

FYI: I am using fetchmail.service for many years and it never showed unexpected behavior you are claiming to observe.

**erlangen:~ #** systemctl cat fetchmail.service                                                      
**# /usr/lib/systemd/system/fetchmail.service**
[Unit] 
Description=A remote-mail retrieval utility 
After=network.target 

[Service] 
# added automatically, for details please see 
# https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort 
PrivateDevices=true 
ProtectHostname=true 
ProtectClock=true 
ProtectKernelTunables=true 
ProtectKernelModules=true 
ProtectKernelLogs=true 
ProtectControlGroups=true 
RestrictRealtime=true 
# end of automatic additions  
EnvironmentFile=-/etc/sysconfig/fetchmail 
User=fetchmail 
ExecStart=/usr/libexec/fetchmail-systemd-exec 
RestartSec=1 

[Install] 
WantedBy=multi-user.target 
**erlangen:~ #**

I suggest you first check whether a direct invocation works:

**erlangen:~ #** systemctl stop fetchmail.service        
Warning: Stopping fetchmail.service, but it can still be activated by: 
  fetchmail.timer 
**erlangen:~ #** systemctl status fetchmail.service  
**×** fetchmail.service - A remote-mail retrieval utility 
     Loaded: loaded (/etc/systemd/system/fetchmail.service; static) 
     Active: **failed** (Result: exit-code) since Wed 2022-05-18 16:05:37 CEST; 13s ago 
TriggeredBy: **●** fetchmail.timer 
    Process: 26340 ExecStart=/usr/libexec/fetchmail-systemd-exec **(code=exited, status=1/FAILURE)** 
   Main PID: 26340 (code=exited, status=1/FAILURE) 
        CPU: 209ms 

May 18 16:01:05 erlangen systemd[1]: Started A remote-mail retrieval utility. 
May 18 16:01:05 erlangen fetchmail[26340]: fetchmail 6.4.30 Dämon wird gestartet 
May 18 16:05:37 erlangen systemd[1]: Stopping A remote-mail retrieval utility... 
May 18 16:05:37 erlangen fetchmail[26340]: beendet mit Signal 15 
May 18 16:05:37 erlangen systemd[1]: **fetchmail.service: Main process exited, code=exited, status=1/FAILURE** 
May 18 16:05:37 erlangen systemd[1]: **fetchmail.service: Failed with result 'exit-code'.** 
May 18 16:05:37 erlangen systemd[1]: Stopped A remote-mail retrieval utility. 
**erlangen:~ #** 

This is RestrictRealtime which implies NoNewPrivileges which sets no_new_privs flag on all processes started as part fo this service. no_new_privs ignores suid bit (it does not allow privilege elevation) and cannot be undone.

leap15:/run/systemd/system # systemctl cat testsuid.service | grep Real
RestrictRealtime=true
leap15:/run/systemd/system # systemctl status testsuid.service
● testsuid.service - A remote-mail retrieval utility
     Loaded: loaded (/run/systemd/system/testsuid.service; static)
     Active: active (running) since Wed 2022-05-18 16:40:16 MSK; 37min ago
   Main PID: 13224 (sleep)
      Tasks: 1 (limit: 1133)
     CGroup: /system.slice/testsuid.service
             └─13224 /usr/bin/sleep 100000000


May 18 16:40:16 leap15 systemd[1]: Started A remote-mail retrieval utility.
leap15:/run/systemd/system # grep NoNew /proc/13224/status
NoNewPrivs:    1
leap15:/run/systemd/system # 

Many thanks for the explanation. I think I need to do some more reading up on systemd at some point.

Sorry, I was wrong. Almost every other Protect* or Restrict* option used here implies NoNewPrivileges. See also “man systemd.exec”. And as far as I can tell it cannot be overridden by explicit NoNewPrivileges=false.

You may consider writing PolicyKit rule to allow “systemctl shutdown” for user fetchmail instead …