Can I use pkexec in a python script or a .desktop file?
From the following questions
- Why is gksu no longer installed by default?
- When to use pkexec vs. gksu/gksudo?
we see that gksu will no longer be supported in the long term, and it will not be installed by default from >= 13.04. Instead we should use pkexec which does its job fine for non-graphical applications but not for apllications on the GUI:
pkexec gedit
when replacing gksu in a .desktop file
EXEC=pkexec /usr/bin/gedit
or when I run a python script to run a graphical application with root permissions I get the following error:
>>>subprocess.Popen(['pkexec','gedit'])
** (gedit:3203): WARNING **: Could not open X display
How would I have to re-write my scripts or my .desktop files to support an authentication dialog and run an application as root if I should not have it depend on gksu?
First create a .policy
action file in /usr/share/polkit-1/actions/
. It's conventional to name action files in a "vendor hierarchical" way, such as com.ubuntu.pkexec.gparted.policy
or org.debian.apt.policy
Then paste the following content:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<action id="org.freedesktop.policykit.pkexec.run-[Short Program Name]">
<description>Run [Full Program Name]</description>
<message>Authentication is required to run [Full Program Name]</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">[Full Program Path]</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">TRUE</annotate>
</action>
</policyconfig>
Replace [Short/Full Program Name/Path]
with appropriate values, for example gedit
, gedit Text Editor
and /usr/bin/gedit
. <action id>
value does not need to match the chosen filename (and a single file can contain multiple actions), but conventionally filename is the prefix for all its actions.
After saving the file the specific program would run with X and GUI and such.
Another fix seems to be: Add the following line in /etc/pam.d/polkit-1:
session optional pam_xauth.so
Yet another fix for user scripts: Determine the appropriate environment variables inside your script.
You could use a snippet like the following one to do this:
getXuser() {
user=`pinky -fw | awk '{ if ($2 == ":'$displaynum'" || $(NF) == ":'$displaynum'" ) { print $1; exit; } }'`
if [ x"$user" = x"" ]; then
startx=`pgrep -n startx`
if [ x"$startx" != x"" ]; then
user=`ps -o user --no-headers $startx`
fi
fi
if [ x"$user" = x"" ]; then
user=$(pinky -fw | awk '{ print $1; exit; }')
fi
if [ x"$user" != x"" ]; then
userhome=`getent passwd $user | cut -d: -f6`
export XAUTHORITY=$userhome/.Xauthority
else
export XAUTHORITY=""
fi
export XUSER=$user
}
for x in /tmp/.X11-unix/*; do
displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`
getXuser;
if [ x"$XAUTHORITY" != x"" ]; then
export DISPLAY=":$displaynum"
fi
done
(based on the ACPI getXuser
function)
If you find your .desktop
file still not working you could try wrapping your pkexec commandline
in a sh
snippet, e.g.:
Exec=sh -c "pkexec --user root script_that_needs_root.sh"
The last problem is a known bug, apparently:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=690339
https://bugzilla.xfce.org/show_bug.cgi?id=9373
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=650038
https://bugzilla.gnome.org/show_bug.cgi?id=686059