2

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'
  • Are you trying to achieve this to be sure the pendrive is properly unmounted? Or are you trying to achieve something else? Because even if the pendrive is mounted, the shutdown sequence should ensure that it's properly unmounted – Bigon Feb 19 '18 at 19:34
  • I added a line in script that write a file during the pendrive disconnection and, after disconnect the pendrive, the file has been created and writed correctly. So, the second script is called correctly – AlmuHS Feb 19 '18 at 20:49
  • Add export DISPLAY XAUTHORITY before notify-send. – mviereck Feb 19 '18 at 22:10
  • ok, I'll try it – AlmuHS Feb 19 '18 at 22:10
  • Added. Unsucessfull yet – AlmuHS Feb 19 '18 at 22:13
0

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)
  • I try to add user=$1 XAUTHORITY="/home/$user/.Xauthority" DISPLAY=$( who | grep -m1 $user.*( | awk '{print $5}' | sed 's/[(|)]//g') before call notify-send, but don't result – AlmuHS Feb 19 '18 at 21:05
  • @AlmuHS Are you sure that is right? Your who ... for DISPLAY does not work here, and XAUTHORITY is in my case /run/user/1000/gdm/Xauthority. Maybe output them into a file and check if they are right? – mviereck Feb 19 '18 at 21:20
  • added in main post – AlmuHS Feb 19 '18 at 21:59
  • I test this command in the command line, and runs well – AlmuHS Feb 19 '18 at 22:04
  • @AlmuHS I've added a workaround that stores DISPLAY in /tmp and uses xhost instead of XAUTHORITY for X authentication. – mviereck Feb 19 '18 at 23:37
0

@mviereck

I tried to create a polkit policy file to notify-send, with this contents

<policyconfig>
<action id="org.freedesktop.notify-send">
<description>Launch notify-send command</description>
<message>Authentication is required to run the gedit</message>
<icon_name>accessories-text-editor</icon_name>
<defaults>
    <allow_any>yes</allow_any>
    <allow_inactive>yes</allow_inactive>
    <allow_active>yes</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/bin/notify-send</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>

I put this file in /usr/share/polkit-1/actions/org.freedesktop.policykit.notify-send.policy

But, after press shutdown button, the shutdown menu took a long time to be showed, and notification didn't appeared

  • I cannot provide help with polkit rules, I am not familar with them. But I don't see an attempt to allow running notify-send as anther user. Or does <allow_any>yes</allow_any> do this? Sorry, can't really help here. Maybe ask a new question like "How to allow running notify-send as another user with pkexec". – mviereck Feb 25 '18 at 19:33
  • ok, I'll try it – AlmuHS Feb 25 '18 at 19:35
0

Finally, I created a dbus client, launched as user, which receives signal from systembus and shows notification to user.

The dbus client code is in https://github.com/AlmuHS/Pendrive_Reminder/blob/work-in-progress/dbus-client/client.py

In the send-notify.sh script, I only added

 dbus-send --system /org/preminder/mensaje org.preminder.App

Executing the dbus client as user, the notification is showed correctly

Now I'm try that the client can be launched automatically when user connect pendrive

Continue in How to launch a dbus client from a script?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.