Part of my python program needs administrator access. How can I gain root privileges using a GUI popup similar to the gksudo command?
I only need root privileges for a small part of my program so it would be preferable to only have the privileges for a particular function.
I'm hoping to be able to do something like:
gksudo(my_func, 'description of why password is needed')
gksudo can be used to launch programs running with administrator privileges. The part of your application that needs to run as root, must be able to be invoked as a separate process from the command line. If you need some form of communication between the two, you could use sockets or watch for a file, etc.
You have two options here:
You will need to make the part of the program that requires root privileges a separate file and then execute the file like this:
>>> import subprocess
>>> subprocess.call(['gksudo','python that_file.py'])
which will bring up the password prompt and run that_file.py as root
You could also require that a program be run as root from the start and just have the program user type "gksudo python your_program.py" in the command-line from the start which is obviously not the best idea if your program is normally launched from a menu.
Related
I am writing a python administrative daemon on linux that needs to start/stop other services. Following the principle of least privilege, I want to run this normally with regular user privileges but when it needs to start/stop other services, I want it to become root. Essentially I want to do what sudo would do from the command line. I cannot directly exec sudo from the daemon because it has no tty. I want to avoid running the daemon as root when it does not need to run as root. Is there any way to do this from python without needing to use sudo?
Thank you in advance.
Ranga.
In this case I have a flask back end that needed to do something privileged. I broke it up into two back ends - one unprivileged and another small privileged piece rather than use sudo.
It is also possible to run sudo in a pty but I decided against this approach as it does indeed have a security flaw.
I'm very inexperienced when it comes to UNIX privileges. I have a Python script that starts some other Python scripts and also other programs like tcpdump. All those processes are started via subprocess.Popen, some of the programs are opened in terminals (via the x-terminal-emulator -e option).
Some of the scripts/programs need to be started as root, however. I have tried to split up the whole functionality in smaller scripts and only use sudo when it's necessary. Now my problem is that my setup requires me to enter my root password like 3 or 4 times everytime I start up the whole thing.
What I am looking for is a way to enter my password once when I start the original script, but only grant actual root permissions at specified places in my scripts. Can anyone help me out? :)
One way of doing this is to start as root, fork all sub-processes and then drop your privileges in the (sub-)processes that don't need the privileges.
For an example, see here
There are some other suggestions as well in the same post.
I'm trying to code something in Python, making Apache stop and start with a GUI application.
Everything works ok, I mean I execute the command (service start or service stop) with subprocess.Popen and call for pkexec as first argument so the user is prompted and can start or stop apache
The problem is, pkexec is runned everytime the user clicks on start or stop apache which is quite normal.
I thought after the first identification, the user would be as root inside my application, but he's not, i'm testing before and after the pkexec command...
Do you think I can find another solution for it ? Should I stick with the password dialog for ever
I'm facing the same problem than you: My python GTK app needs to run commands as root, but using pkexec makes it asking each time for the root password, which is really annoying.
I see two ways to solve that "issue":
1. Run your app with pkexec
That solution would fit more for your case.
Write a shell script which runs your python app with pkexec. With that solution, the user is asked only once, and your app run as root, therefore it doesn't require to use pkexec anymore, and can run any commands.
The downside of this is that you could expect, after a while, that the password is again asked, just in the case an unauthorized person get access to the computer.
2. Split your app
My use case is an installer that ease the life of users by downloading, compiling and installing a software.
The previous solution would work, but I do prefer let the user run the installer, and get asked for the password when it actually hit the "Install" button.
The solution is then to split the app in 2 parts:
The GUI
The "engine" or command executor process
The GUI will run the "engine" using pkexec when it needs to start it (in your case, it would need to run with pkexec only the first time the user clicks the "Start/Stop" button), so that the GUI runs as the user, and the "engine" as root.
Now you need an inter-process communication so that the "engine" can report to the GUI, and the GUI can send commands to the "engine". To do so, the best option would be to use pipes like it is shown in this answer: https://stackoverflow.com/a/3806342/1996540.
Update
I have finally implemented my suggested answer in this project so you can have a look on a working example.
I have a python script which is performing some nagios configuration. The script is running as a user which has full sudo rights (the user can run any command with sudo, without password prompt). The final step in the configuration is this:
open(NAGIOS_COMMAND_FILE, 'a').write(cmdline)
The NAGIOS_COMMAND_FILE is only writable by root, so this command should be run by root. I can think of two ways of achieving this (both unsatisfactory):
Run the whole script as root. I do not like doing this, since any error in my script will be executed with full root rights.
Put the open(NAGIOS_COMMAND_FILE, 'a').write(cmdline) command in a separate script, and use the subprocess library to call that script, with sudo. I do not like creating an extra script just to run a single command.
I suppose there is no way of changing the running user just for a single command, in my current script, or am I wrong?
Why don't you give write permission on NAGIOS_COMMAND_FILE to your user who have all sudo rights?
Never, ever run a web server as root or as a user with full sudo privileges. This isn't a pythonic thing, it is a "keep my server from being pwned" thing.
Look at os.seteuid, the "principle of least privilege", and man sudoers and run your server as regular "httpd-server" where "httpd-server" has sudoer permission to write to NAGIOS_COMMAND_FILE. And then be sure that what you write to the command file is as clean as you can make it.
It is actually possible to change user for a single command.
Fabric provides a way to log in as any user to a server. It relies on ssh connections I believe. So you could connect to localhost with a different user in your python script and execute the desired command.
http://docs.fabfile.org/en/1.4.3/api/core/decorators.html
Anyway, as others have already precised, it is best to allow the user running the script permission to execute this one command and avoid relying on root for execution.
I would agree with the post above, either give your user write perms to the NAGIOS_COMMAND_FILE or add that use to a group that has those permissions, like nagcmd.
I have a program which uses python's cmd module for command line interfaces.
Now I want it to run on my Linux server whenever any normal user logs in to it,
in a way that user never gets the default Linux prompt (i.e he should not be able to kill the program or send it to background or any such stuff).
For security issues the program should never allow user to gain access of normal prompt. The user should always use program's cmdline to fire all commands. (The program has various filters built in it).
Tried putting the program execution command in /etc/password (replacing default bash shell with the program execution cmd) for the user & also tried to put it in users .bashrc file, but of no use; user can still gain access default prompt.
Any pointers for this can very helpful.
This probably belongs on superuser, but you should add it into /etc/shells file, and set a user's login shell to that one.
For example: sudo useradd -d /path/to/newuserhomedir -s /usr/sbin/nologin newusername would create a guy called newusername whose login shell would be the program /usr/sbin/nologin.