How to run some commands in my installations scripts of deb-package (preinst, postinst, prerm, postrm) not from root but from current user (user that invoked the installation)?
root is the current user. You should never expect that the installation of the package is performed by sudo
You can check the SUDO_USER environment variable for the user that may have invoked the script, if the installation was performed from the context of a simple sudo dpkg -i - sudo may not have been installed, so the installation may have been performed by su, which means that the environment variable will not be set.
If you want to invoke scripts as that user you just invert the sudo - viz:
sudo -u $SUDO_USER -c <command to invoke>
but you need to ensure that you properly know the user that invoked the script - i.e. SUDO_USER could be root!
Typically, though, because you can have an arbitrary number of users on a Linux system, you should not do something like this, as it will leave the system in a state where only one user can use the package. You should create state/configuration on first invocation as the ordinary user.
Finally, don't expect a GUI, don't expect a terminal on the installation if it's just being shipped as a dpkg.
You need to be root in order to install something. If you install per-user configurations, they should normally be installed for all users.
Having said that, look into real vs effective uid.
Related
I need to run a command as a different user in the %post section of an RPM.
At the moment I am using a bit of a hack via python but it can't be the best way (it does feel a little dirty) ...
%post -p /usr/bin/python
import os, pwd, subprocess
os.setuid(pwd.getpwnam('apache')[2])
subprocess.call(['/usr/bin/something', 'an arg'])
Is there a proper way to do this?
If /usr/bin/something is something you are installing as part of the package, install it with something like
attr(4755, apache, apache) /usr/bin/something
When installed like this, /usr/bin/something will always run as user apache, regardless of what user actually runs it.
The accepted answer here is wrong IMO. It is not often at all you want to set attributes to allow anyone execute something as the owner.
If you want to run something as a specific user, and that user doesn't have a shell set, you can use su -s to set the shell to use.
For example: su -s /bin/bash apache -c "/usr/bin/something an arg"
I have a use case where I don't want the user executing the ansible commands to become root but I do want them to use sudo to do the commands.
probably not possible but i can't find anything that says one way or the other
sudo allows you to specify which commands a given user or group of users is allowed to run as root . For example, my backuppc account can only run two commands as root:
backuppc ALL=(root) /usr/bin/rsync,/sbin/e2label
There are two ways this script can be run: When the user opens the pkg file and goes through the normal GUI setup, or when an admin (or savvy user) runs sudo installer -pkg /path/to/Installer.pkg -target /. For the second one, I want to know when the script was run in this mode so I can make more admin-friendly decisions like not opening another GUI. How do I know when my pkg is installed via the command line?
I'm hoping for some environment variable or something similar.
Running the script via sudo will change the values of certain variables and add others in. Your script could check for the existence of those variables (or their values) to make a determination as to whether the installer was run via sudo.
Values that would get updated:
HOME
LOGNAME
MAIL
Values that would get set:
SUDO_COMMAND -- the command that was run via sudo
SUDO_GID -- the GID of the user that ran sudo
SUDO_UID -- the UID of the user that ran sudo
SUDO_USER -- the username of the user that ran sudo
My recommendation would be to check for the existence of the SUDO_COMMAND environment variable; it is unlikely to be set for a non-sudo installation, and would be set for a sudo-based installation.
Reference: sudo 1.8.20 manual - ENVIRONMENT section
Since this was being run by the installer command, the COMMAND_LINE_INSTALL environment variable is set to 1. When opening the pkg normally, this variable is not set at all.
So:
if [ $COMMAND_LINE_INSTALL ]; then
# Do stuff for CLI land
else
# Do stuff for GUI land
fi
I need to run a command as a different user in the %post section of an RPM.
At the moment I am using a bit of a hack via python but it can't be the best way (it does feel a little dirty) ...
%post -p /usr/bin/python
import os, pwd, subprocess
os.setuid(pwd.getpwnam('apache')[2])
subprocess.call(['/usr/bin/something', 'an arg'])
Is there a proper way to do this?
If /usr/bin/something is something you are installing as part of the package, install it with something like
attr(4755, apache, apache) /usr/bin/something
When installed like this, /usr/bin/something will always run as user apache, regardless of what user actually runs it.
The accepted answer here is wrong IMO. It is not often at all you want to set attributes to allow anyone execute something as the owner.
If you want to run something as a specific user, and that user doesn't have a shell set, you can use su -s to set the shell to use.
For example: su -s /bin/bash apache -c "/usr/bin/something an arg"
I often need to run at jobs as a different user. I've always done something like
$ echo "$PWD/batchToRun -parameters" | sudo su - otheruser -c "at now"
batchToRun is also scheduled to run via otheruser's crontab. This works out well until batchToRun starts depending on subtle side-effects of settings of environmental variables -- like LANG (sort anyone?) -- that are passed in from the environment of the user running sudo.
I typically don't want to log in as otheruser; it's a semi-privileged account and I would like a "paper trail" of its associated activity so that I can go back and see exactly what was done, by whom, when, etc.
Besides the obvious rewriting batchToRun to be independent of such settings, what's a good way to ensure that the sudoer's environment doesn't contaminate the target environment?
Note: this is on FC7 (sudo version 1.6.8p12) and other old distros, so any shiny new features of sudo/su/at (notably, the ability to pass an argument with -i to sudo) are outside my grasp.
Update: it turns out that the su - otheruser is actually a sufficient firewall between the users and that my contamination is coming from something in the interactive startup sequence. I still like the env edit capability, though.
You could strip the environment before you run at:
echo "command ..." | env - PATH="$PATH" sudo su - otheruser -c "at now"
You can also arrange for sudo to do this for you by setting the env_reset option. For example, you could give your user access to run the at command as otheruser directly (rather than sudo to root and then to the other user) and then set env_reset with a Defaults command for that user or that command (see the sudoers man page).
But the above is probably the easiest solution without changing how you're generally doing things today.
Any "contamination" of otheruser's environment should be limited to the at command's environment. When it actually comes time to run batchToRun, it will be run by otheruser using its typical default environment. That is, only at now is run in the shell spawned by the su sudo command.