If the required command is not within a block (eg loop or conditional), then you can split the script into three: the preceding commands run as myuser
, the protected command run with sudo
(which doesn't prompt when already root
) and the remaining commands, also run as myuser
:-
su - myuser -c myscript-preamble
sudo myscript-protected-command
su - myuser -c myscript-postamble
More generally, there is a trick that you can use with sudo
, using the saved credentials:-
sudo -u myuser sudo -S true <<< password 2>/dev/null
su - myuser -c myscript
sudo -u myuser sudo -k
There are a number of considerations - these are the first that come to mind:-
- The script (or at least the first line) must be executed in a read-protected file (
-rwx------
) or an execution-protected directory (drwx------
), both owned by root
.
- The trick requires that
sudo
credentials are remembered for a defined time (a normal default) and that sudo
in myscript
runs within that time.
- If
myuser
runs myscript
while root
is simultaneously running it, the remembered credentials will be used if the sudo
command is reached before root
runs sudo -k
.
As you can see, it is not an ideal solution from a security standpoint, but it may be workable in your environment.
Otherwise, you will need to use sudo -A
, as described in this extract from the sudo
manual:-
-A, --askpass
Normally, if sudo requires a password, it will read it from the user's
terminal. If the -A (askpass) option is specified, a (possibly graphical)
helper program is executed to read the user's password and output the password
to the standard output. If the SUDO_ASKPASS environment variable is set, it
specifies the path to the helper program. Otherwise, if sudo.conf(5) contains
a line specifying the askpass program, that value will be used. For example:
# Path to askpass helper program
Path askpass /usr/X11R6/bin/ssh-askpass
If no askpass program is available, sudo will exit with an error.
To implement this you will need to write a program which checks if it's running as root
: if so, it outputs the password for myuser
(from obfuscated data, of course); otherwise, it prompts for the password as normal and outputs the user's response.
So yes, it is possible to do what you want, but may involve a fair amount of work, depending on the level of security you require.
Doesn’t sound like it. You want the user to be able to do something that requires a password without providing a password. Alternatively, you want the user to do something without a password while requiring the user to use a password. Clearly there is a better way to do whatever it is you are trying to do. XY Problem?
– Appleoddity – 2018-10-06T14:34:05.427