Why start-stop-daemon needs privileges? - linux

I am writing a Daemon and I want to use start-stop-daemon command to do it but, when I use it in the command line I get :
The command could not be located because '/sbin' is not included in the PATH environment variable.
This is most likely caused by the lack of administrative privileges associated with your user account.
start-stop-daemon: command not found
but when i use it with sudo it run perfect but i need it to run in daemon and i think it is not good to use sudo in bash script in daemon something like :
sudo start-stop-daemon --start --background ...
Isn't it? When I deleted sudo from it it gave me command not found. How can i fix it? if it is wrong to use sudo in daemon.

start-stop-daemon can also set the user ID for the daemon process.
That said, you'd generally use start-stop-daemon from a script in /etc/rc.d, which is run with root privileges either from the init system that is being used this week (sysvinit, upstart, systemd, ...) and/or from the service(8) command.
So, if a user should be able to start/stop the service (which is a rather uncommon scenario), you'd use the sudoers file to grant them access to the service command, with the name of your service as a mandatory first argument.
In general though, write your service so it can be simply started at boot or during installation, and used by users as long as it's running. If the user needs to be able to start and stop instances of the service, then your daemon is in the business of managing instances, and the instance manager should be continually running, and users then contact this service via a socket (so users don't need sudo at all, which would make the lives of many administrators who don't install sudo quite a bit easier).

That depends on your settings in '/etc/sudoers'.
If the environment is reset (default),
the following path definition 'secure_path' contains /sbin (excerpt from Ubuntu '/etc/sudoers'):
Defaults env_reset
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Otherwise you need to provide the full program path
/sbin/start-stop-daemon

Related

systemd session below user session

Is it possible to run a systemd session below the user session with unit files in a subdirectory and not installed in ~/.config/systemd? I'm developing a system consisting of different services (implemented in C++), some of which depend on each other. Currently, they're run from a bash script and all write to stdout. I would love to be able to start them from the build directory, e.g.
# enter build directory
cd /path/to/project/build
# start services
systemd --root ./systemd-units &
# check status of services
systemctl --root ./systemd-units status
# check log output of services
journalctl --root ./systemd-units
Unfortunately no such option exists and I couldn't find any alternative. I don't want to use docker because it makes debugging unnecessarily difficult.
Is there a way to do what I want with systemd? I looked into other systems and runit seems to be able to do what I want but is unlikely to be used in the final product.
It sounds like you may want to use the link feature of systemctl, so you can link units that are not the search path into the search path.

How can non sudo user shutdown using command line interface?

All the below command needs to be run as root:
poweroff
halt
shutdown
telinit
reboot
but still a user who is not a sudoer can shutdown by clicking on the shutdown button in GUI. What happens when we click shutdown button in GUI? How to replicate in cmd?
Sudo is just a one way for a regular user to execute commands as root. The other ways include:
processes with SETUID/SETGID bit set, which are executed under other privileges than the original caller - https://en.wikipedia.org/wiki/Setuid ('sudo' executable has also this bit set)
processes that already run under root privileges and accept external commands (via API, for example), and then call the command on behalf of the original caller (also, same thing that sudo basically does)

disable sudo/root privilege from node.js script

I need in my node.js application sudo privileges to run server on port 80, or run some others startup administration stuff.
But when I will do that I don't want this privileges anymore because then I will run some external libraries from node_modules.
So, how can I disable my administration privileges from node.js script?
You need to use:
process.setgid('somegroup');
process.setuid('someuser');
See the docs:
https://nodejs.org/api/process.html#process_process_setgid_id
https://nodejs.org/api/process.html#process_process_setuid_id
See this article for more info:
https://thomashunter.name/blog/drop-root-privileges-in-node-js/
Other options
Another way to bind to low ports without running as root would be to give a capability to bind to low ports if your system supports it - using e.g. CAP_NET_BIND_SERVICE on Linux with something like:
sudo setcap 'cap_net_bind_service=+ep' /path/to/your/program
That way you will not have to run it as root and you will not have to change to a different user later.

Systemd service unit file as user

I'm new to the concept of systemd unit files in Centos 7 but need to start up the MATLAB license manager at boot. MATLAB doesn't offer a specific solution on how to do this, and the following seems to work but asks for a password when typing systemctl start license-manager and systemctl stop license-manager. Is that expected?
Note this does need to run as a specific user and not as root.
Here is my /etc/systemd/system/license-manager.servicefile:
[Unit]
Description=MATLAB FlexLM license manager
[Service]
Type=forking
ExecStart=/usr/local/MATLAB/R2016a/etc/lmstart
ExecStop=/usr/local/MATLAB/R2016a/etc/lmdown
KillMode=none
Restart=on-failure
RestartSec=90
User=lmlicenseuser
[Install]
WantedBy=multi-user.target
You can try Crontab
bash$ crontab -e
then add the following line
#reboot /usr/local/MATLAB/R201Xx/etc/lmstart
This should resolve your issue.
Traditionally it is always expected for non-root users to be asked for a password when running commands as other users, yes.
However, because you have specified that it is a dependency of multi-user.target, it should always be started automatically whenever you reboot in future, so you shouldn't need to enter the password in future.
If for some reason you do still need to control it manually in future, you can use sudo and edit /etc/sudoers to allow those two particular commands to be run without a password, using NOPASSWD.

Can I control a user systemd using 'systemctl --user' after sudo su - myuser?

I have a service that I want to start with system startup. I have built a ap#.service definition for it as a template, because there could be many instances.
Defined in the root systemd, this works well, and starts and stops the service with the system. The service instance is installed with systemctl enable ap#inst1 as would be expected. Root is also able to start and stop the service without problems. The service runs in its own account (myuser), not root, controlled by User=myuser in the ap#.service template.
But I want user 'myuser' to be able to start and stop their own service, without compromising system security.
I switched to using a user systemd, and enabled lingering with loginctl enable-linger myuser. I then enable the service defined in the ~myuser/.config/systemd/user directory. The service now starts and stops cleanly with the system, as designed. If I log in to a terminal as 'myuser', systemctl --user start ap#inst1, and systemctl --user stop ap#inst1 both work perfectly.
However, if I log in as a different user (user2) and perform sudo su - myuser in a terminal, then systemctl --user commands now fail with error message "Failed to get D-Bus connection: no such file or directory".
How do I enable systemctl --user to work after a sudo su - myuser command to switch the user?
I found the answer on another site with further searches using different terms.
The solutions needed was to provide the shell with information to reach the correct DBUS for the user.
By adding the following environment variables to the shell before running systemctl --user, the DBUS problem is eliminated, and systemctl operates correctly.
export XDG_RUNTIME_DIR="/run/user/$UID"
export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"
To ensure that the DBUS_SESSION_BUS_ADDRESS is available in the sudo shell, I added the environment variables to ~/.bash_profile of the target userid. This requires that a login shell ( sudo su - myuser or sudo -l myuser) is created in order to create the correct environment.
Alternatively, add the creation of the environment variables to ~/.bashrc (or equivalent for other shells). The environment will then be established anew for all shell creations.
systemd 248 (released March 2021) introduced support for the syntax -M myuser# for specifying another user.
$ sudo systemctl --user -M myuser# start ap#inst1
A side-note:
If you want to get an interactive login shell for the user myuser
$ sudo machinectl shell myuser#

Resources