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'
AlmuHS
  • 169
  • 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
  • Try echo $DISPLAY $XAUTHORITY > /home/$user/x.txt and check the content of x.txt. Also: Does the script run as user $user? There may be access restrictions to .Xauthority forbidding access for other users than $user. – mviereck Feb 19 '18 at 22:18
  • You can also try xmessage "yourtext" to make sure its not a problem with notify-send itself. – mviereck Feb 19 '18 at 22:20
  • ok, I'll try both – AlmuHS Feb 19 '18 at 22:21
  • After try echo $DISPLAY $XAUTHORITY > /home/$user/x.txt from my script, I check that x.txt file don't exists after press shutdown button. – AlmuHS Feb 19 '18 at 22:26
  • Either the script is not executed, or it cannot write to /home/$user. Try echo $DISPLAY $XAUTHORITY $user > /tmp/x.txt – mviereck Feb 19 '18 at 22:30
  • I did a echo $user > /tmp/user and this file was created correcly with the username in it.

    So feels the second problem

    – AlmuHS Feb 19 '18 at 22:32
  • This only works with a X session (and not wayland one) and might break if several users are connected to the machine. – Bigon Feb 19 '18 at 22:39
  • @Bigon what is your proposal to solve it? – AlmuHS Feb 19 '18 at 22:42
  • What gives echo $DISPLAY $XAUTHORITY $(id) > /tmp/x.txt? – mviereck Feb 19 '18 at 23:13
  • I'm not exactly sure. I would create a daemon that listen to udev events and that set systemd inhibitor to prevent the reboot/shutdown. But that doesn't solve the problem of the notification (maybe some desktop environment would display something). Note that there are discussion in polkit mailing lists to remove the javascript support for the rules in the future and also note that polkit in debian has an old version that doesn't support that either. I'm still wondering WHY you want to do that. – Bigon Feb 19 '18 at 23:15
  • @mviereck 15:30 /home/almu/.Xauthority uid=102(polkitd) gid=105(polkitd) groups=105(polkitd) – AlmuHS Feb 19 '18 at 23:20
  • @Bigon I have other version of same application that, instead use polkit javascript rules, use old polkit authoritization files (.pkga)

    In this version, I have two scripts linked to 2 udev events. The first script, furthermore creates the usb file, add the pkla polkit file; and the second, after remove id from file, if file is empty, also remove pkla polkit file.

    But this version don't allow show notifications

    – AlmuHS Feb 19 '18 at 23:23
  • Full code here: https://github.com/AlmuHS/Pendrive_Reminder – AlmuHS Feb 19 '18 at 23:25
  • One issue: 15:30 is not a valid value for DISPLAY. Most times it is :0 or :1. Another issue: most probably polkitd is not allowed to read .Xauthority. I'll add a workaround to my answer. – mviereck Feb 19 '18 at 23:25
  • Yes, I think is a permissions problem – AlmuHS Feb 19 '18 at 23:29
  • Your rule file is very strange. I think only one catch the shutdown. First at all, you must find the responsible program consolekit, login1 or xfce. Perhaps it's another one ? When I try for your previous ask, the shutdown button was disabled when the pendrive file exist. No need of notification because I can't shutdown. – ctac_ Feb 20 '18 at 19:34
  • @ctac_ This rule is part of a program, which will be distributed and used by users with differents desktop environments and distributions.

    By this reason, my rule file capture all possible shutdown events of each desktop environment and system.

    The program try to be a reminder, with objective that the user don't forget its pendrive. By this reason, furthermore to lock shutdown when user connect pendrive, is needed a notify when the user try to shutdown

    – AlmuHS Feb 20 '18 at 20:19
  • Your script in UPDATE 2 can only work if /tmp/display.$user exists. Therefore you need the autostart script provided in my answer. Instead of XAUTHORITY it works with xhost. You need to read and understand the script snippets to use them. – mviereck Feb 23 '18 at 13:21
  • @mviereck Well, It's a update based in your workaround. Previously, I put your script in my autostart, and execute it manually to be sure – AlmuHS Feb 23 '18 at 14:39
  • This may help: https://unix.stackexchange.com/a/429162/185747 – mviereck Mar 09 '18 at 09:02

3 Answers3

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)
mviereck
  • 2,467
  • 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
  • Don't runs yet :( – AlmuHS Feb 19 '18 at 23:56
  • Does /tmp/display.$USER have the right content? – mviereck Feb 19 '18 at 23:59
  • simply, /tmp/display.almu don't exists – AlmuHS Feb 20 '18 at 19:16
  • @AlmuHS Than you did not execute the autostart script. – mviereck Feb 20 '18 at 19:19
  • I executed it mannually – AlmuHS Feb 20 '18 at 20:23
  • ok, after execute autostart script manually, the /tmp/display.almu file has been created, and its content is ":0"

    But there isn't notify yet

    – AlmuHS Feb 20 '18 at 20:27
  • @AlmuHS Did you check with xmessage, too? – mviereck Feb 21 '18 at 17:24
  • Yes, I did this – AlmuHS Feb 21 '18 at 20:12
  • I've just seen this post. https://unix.stackexchange.com/questions/203136/how-do-i-run-gui-applications-as-root-by-using-pkexec

    Can I create a similar action file to launch notify-send?

    – AlmuHS Feb 24 '18 at 23:56
  • @AlmuHS Maybe. Quite important is the line with allow_gui, I assume. It seems to me notify-send must run as the user who gets notified. If you can set up a rule that allows to execute notify-send as desired user without a password prompt, it will probably work. You need to allow something like su $user -c 'notify-send message' – mviereck Feb 25 '18 at 08:49
  • Interestingly, I can successfully run notify-send from tty although there is no DISPLAY and no XAUTHORITY in the enviroment. It seems notify-send gets the value from somewhere else. – mviereck Feb 25 '18 at 08:53
  • I tried su $user -c 'notify-send message' in other time. but failed same.

    As I knows, notify-send takes DISPLAY and XAUTHORITY from DBus

    – AlmuHS Feb 25 '18 at 18:09
  • @AlmuHS su $user needs a user password (except root is doing this), otherwise it will fail. Your polkit script runs as user polkitd as seen with output of id. Maybe a polkit rule is possible to allow pkexec --user $user notify-send MESSAGE without a password for all $user. I'm not familar with polkit though and cannot provide a polkit/pkexec rule, but I assume it is possible. – mviereck Feb 25 '18 at 18:31
  • But, I think that polkit launch the script as root. Am I wrong? – AlmuHS Feb 25 '18 at 19:10
  • @AlmuHS You did echo $(id) > /tmp/user somewhere above, it showed user polkitd. – mviereck Feb 25 '18 at 19:28
  • ok, I didn't remember this – AlmuHS Feb 25 '18 at 19:29
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

AlmuHS
  • 169
  • 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?

AlmuHS
  • 169