If the actions that need to be run as root can be separated into separate processes/scripts, then you can run these processes as setuid root. It is a very handy tool that in my opinion is used far too rarely.
What are setuid processes? Look for example at the passwd
command. It can be run by any user, but it needs to be run as root, as it needs to modify password stored in a file that only root can access (/etc/shadow
).
How it is done? Look at the permissions of the /usr/bin/passwd
binary:
-rwsr-xr-x 1 root root 68208 maj 28 2020 /usr/bin/passwd
The "s" instead of "x" in the owner field indicates that this binary will be run with the rights of its owner - that is root.
This way every binary can be made to run as root (or any other user), independent of who is calling it.
However, on scripts the setuid bit is ignored for security reasons. So to run a script as root you need to use a binary wrapper that will call the script from inside. You can use the following simple C program to create such a wrapper:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
int rc;
setuid( 0 );
rc=WEXITSTATUS(system( "/path/to/your/script" ));
exit(rc);
}
Compile the program and make the executable setuid root (assuming the executable is called wrapper
, do sudo chown root:root wrapper
followed by sudo chmod o+s wrapper
).
BTW. The script that is run from inside the wrapper does not have to be setuid; only the wrapper needs to.
Edit: from your explanation in the comments it looks that you want to run a particular rm -rf /some/path
command as root and are concerned to not accidentally remove anything else. In that case, I suggest just replacing the /path/to/your/script
part in the wrapper program above by this very command rm -rf /some/path
, and just run the wrapper
binary from your script in the place where you would run rm -rf /some/path
command. This seems to be the safest approach.