Polkit Notification – How to Send a Notification with Polkit 0.106

linuxnotify-sendpolkitshutdown

I am developing a application to don't forget the pendrive.

This app must lock the shutdown if a pendrive is connected to the machine. As this form, if the user wants to shutdown the system while a pendrive is connected, the system shows a notification to alert about it must disconnect the pendrive to unlock shutdown.

To detect the shutdown event, I set a polkit rule what call a script to check if any pendrive are connected to the system.

If there are any pendrive connected, the polkit rule calls to notify-send through the script send_notify.sh, which execute this command:

notify-send "Pendrive-Reminder" "Extract Pendrive to enable shutdown" -t 5000

The polkit rule is this:

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.consolekit.system.stop" ||
        action.id == "org.freedesktop.login1.power-off" ||
        action.id == "org.freedesktop.login1.power-off-multiple-sessions" || 
        action.id == "org.xfce.session.xfsm-shutdown-helper")  
    {

        try{    
            polkit.spawn(["/usr/bin/pendrive-reminder/check_pendrive.sh", subject.user]);        
            return polkit.Result.YES;

        }catch(error){
            polkit.spawn(["/usr/bin/pendrive-reminder/send_notify.sh", subject.user]);
        return polkit.Result.NO;
     }
   }
  }

But. after put this polkit rule and press shutdown button, my user don't receive any notification.

I debug the rule and I checked that second script It's executed, but the notify-send don't shows the notification to my user.

How can I solve this?

UPDATE:

I tried to modify the script as this:

#!/bin/bash

user=$1

XAUTHORITY="/home/$user/.Xauthority"
DISPLAY=$( who | grep -m1 $user.*\( | awk '{print $5}' | sed 's/[(|)]//g')

notify-send "Extract Pendrive to enable shutdown" -t 5000

exit 0

The user is passed as parameter by pòlkit

But the problem continues

UPDATE: I've just seen this bug https://bugs.launchpad.net/ubuntu/+source/libnotify/+bug/160598 that don't allows to send notifications as root.

Later I'll test to modify workaround changing user

UPDATE2: After change code to this. the problem continues:

#!/bin/bash

export XAUTHORITY="/home/$user/.Xauthority"
export DISPLAY=$(cat "/tmp/display.$user")

user=$1
su $user -c 'notify-send "Pendrive Reminder" "Shutdown lock enabled. Disconnect pendrive to enable shutdown" -u critical'

Best Answer

polkit (and pkexec) delete environment variables DISPLAY and XAUTHORITY that are needed for X access. notify-send fails because it cannot access the display.

From the pkexec manpage:

As a result, pkexec will not allow you to run X11 applications as another user since the $DISPLAY and $XAUTHORITY environment variables are not set. These two variables will be retained if the org.freedesktop.policykit.exec.allow_gui annotation on an action is set to a nonempty value

I am not familar with polkit; maybe you can set org.freedesktop.policykit.exec.allow_gui just for this rule, or there are other possibilities. Sorry that I can't provide a ready solution.

However, the core point is to provide DISPLAY and XAUTHORITY for notify-send.

(Don't hit me: a dirty solution would be hardcoding DISPLAY=:0 and XAUTHORITY=... in your notify script. Be aware that this can fail if something changes).


Edit: Based on above discussion a workaround that should work with multiple users and without XAUTHORITY:

On X login, a script should be automatically executed (maybe some .desktop setup in ~/.config/autostart):

#! /bin/bash
# allow polkitd access to X. 
# xhost is an alternative to XAUTHORITY authentication
xhost +SI:localuser:polkitd
# store DISPLAY for each user
echo $DISPLAY > /tmp/display.$USER

In your polkit script include

export DISPLAY=$(cat /tmp/display.$user)
Related Question