Problems using libnotify for User to User Notifications

There are several methods that can be used for text message exchanging between different non-privileged users. Usually, when the sender of such a message is a service and the recipient, who is supposed to see the message, is a human, that message is called a “notification“. The method used by many services that run within the scope of a desktop session in order to send notifications to the desktop session owners involves the use of DBus and libnotify. But, would it be possible to use libnotify to send notification messages from a system service to one or more desktop users?

Despite my last post’s overwhelming optimism, it is sometimes impossible to find a solution for a problem, because one does not exist. It turns out that the above task cannot be accomplished, at least at the moment of writing, as it is impossible for one user (system account or other non-privileged user) to send a notification through libnotify to another user that runs a desktop session. The easiest way to test this is with a cron job in the system’s crontab:

*/1 * * * * root /usr/bin/notify-send "lala" "test message"

No notification appears on the desktop, no matter how long I wait. After doing some research it turns out that notify-send cannot automatically send notifications to all users that run a desktop session. It can only send notifications only to one user at a time provided that the user’s D-Bus session address is available to notify-send.

So, I decided to set the cron job to send a notification to my own user account by providing notify-send with my DBUS_SESSION_BUS_ADDRESS.

The following is a method a system user (or any user except me) would use to retrieve my DBUS_SESSION_BUS_ADDRESS address. These steps are actually taken from this GNOME-Hack, which is supposed to send notifications from a cronjob.

In order to retrieve this address, my gnome-session’s PID number is needed.

$ ps axu | grep gnome-session | grep -v grep
gnot      2602  0.0  1.3  33432  7064 ?        Ssl  16:56   0:00 /usr/bin/gnome-session

The needed PID number is 2602. The D-BUS session’s address exists as an environment variable (DBUS_SESSION_BUS_ADDRESS) of that process (2602). This can be retrieved with the following:

$ grep -z DBUS_SESSION_BUS_ADDRESS /proc/2602/environ
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-vKzOHyaDdi,guid=f45436454463d8df2f8d265447405220

Notice that the PID number has been used in the /proc/2602/environ path.

Adding this information to the initial cronjob one would expect that the notification would appear on the desktop.

*/1 * * * * root DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-vKzOHyaDdi,guid=f45436454463d8df2f8d265447405220 /usr/bin/notify-send "lala" "test message"

Unfortunately, it didn’t. I also retrieved my desktop session’s display number and added it to the cron job.

*/1 * * * * root DISPLAY=:0.0 DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-vKzOHyaDdi,guid=f45436454463d8df2f8d265447405220 /usr/bin/notify-send "lala" "test message"

Unfortunately, nothing happened.

It seems that not only notify-send can send a notification to only one desktop session owner at a time, but also it is that desktop session owner who must issue the notify-send command. So, as long as most system services drop privileges and run as processes of non-privileged system users, they cannot send notifications to desktop users.

This is probably because of one or more of the following reasons:

  1. either D-Bus is incomplete when it comes to message exchanging between non-privileged users
  2. or there is some kind of security mechanism that prevents the above from happening. Unfortunately, I haven’t found any information about such a mechanism.
  3. or I miss something way too important.
  4. or I make a mistake in one of the steps.

If I miss anything, please let me know.

Problems using libnotify for User to User Notifications by George Notaras is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Copyright © 2007 - Some Rights Reserved

George Notaras avatar

About George Notaras

George Notaras is the editor of the G-Loaded Journal, a technical blog about Free and Open-Source Software. George, among other things, is an enthusiast self-taught GNU/Linux system administrator. He has created this web site to share the IT knowledge and experience he has gained over the years with other people. George primarily uses CentOS and Fedora. He has also developed some open-source software projects in his spare time.

6 responses on “Problems using libnotify for User to User Notifications

  1. George Notaras Post authorPermalink →

    Hi Aleksei, thanks for this tip. Using sudo should work, but I am not able to test it right now. I’ll post any good news :)

  2. George Notaras Post authorPermalink →

    Henning, please make sure you leave a link to that blog post here in the comments when it’s published, so other readers can easily locate it. Thanks for your work! :)

  3. Henning Permalink →

    Hi,

    This post is not that new, but newsworthy and in some parts unsolved anyway…

    I wrote a small script to be used to send a broadcast-message via notify-send. It should have been quite easy, but I could not find any ready-to-use-stuff on google, so i wrote it by myself.

    Henning

  4. edrusb Permalink →

    Thanks you for this information. I could thus built a script to automate my need to report some kind of system messages to user based on their UID. May this be useful to anyone wanting to branch certain syslog-ng messages (messages corresponding to output network packets dropped by netfilter, have the UID field in them) to the corresponding user.

    Regards,
    Edrusb.


    #!/bin/sh

    if [ -z "$1" -o -z "$2" ] ; then
    echo "usage: $0 "
    exit 1
    fi

    UID="$1"
    MESSAGE="$2"

    #DEBUG=no
    DEBUG=yes

    ####################################################
    # looking for user name from UID
    USERNAME=`cut -f 1,3 -d ':' /etc/passwd | grep ":$1" | cut -f 1 -d ':'`

    if [ "$DEBUG" = "yes" ] ; then
    echo "username = $USERNAME"
    fi

    ####################################################
    # looking for the session process
    LEADER=`ps -e -o pid,user,comm | grep gnome-session | grep "$USERNAME" | sed -r -e 's/\s+/ /g' -e 's/^\s+//' | cut -f 1 -d ' '`

    if [ "$DEBUG" = "yes" ] ; then
    echo "leader = $LEADER"
    fi

    if [ -z "$LEADER" ] ; then
    echo "user = $USERNAME\nUID = $UID\nmessage = $MESSAGE" | mail -s "user absent for notification !" root
    exit 0
    fi

    ####################################################
    # fetching environnement variables

    VARIABLES=`egrep -z 'DBUS_SESSION_BUS_ADDRESS|DISPLAY' /proc/$LEADER/environ | sed -r -e 's/(.)DBUS_/\1 DBUS_/' -e 's/(.)DISPLAY/\1 DISPLAY/'`

    if [ "$DEBUG" = "yes" ] ; then
    echo "variables = $VARIABLES"
    fi

    ####################################################
    # final !

    su $USERNAME -s /bin/sh -c "$VARIABLES notify-send -t 2000 -u critical 'Attention !' '""$MESSAGE""'"

  5. edrusb Permalink →

    well, the “greater than” “lower than” symbols have been dropped in the copy/past . So you can replace line 4 of the script by :

    echo “usage: $0 [UID] [message]”