system wide crontab to notify any logged on user - GUI wise

I have found two other posts with relevant information, but not a solution that I can use:

Launch Terminal From Crontab - openSUSE Forums

and

Cron & Kdialog: Cannot Connect To X Server - openSUSE Forums

What I need to do is inform any users that are currently logged in and has an X Session running, that their compliance in security has dropped according to the Center for Internet Security (CIS) standards. I have all the necessary sub-routines built to determine the above but I have had little success with deploying a GTK+2 widget explaining their drop in CIS compliance.

I have had success using the notification daemon when obtaining the users DBUS_SESSION_BUS_ADDRESS. But due to the lack of usability of said daemon, I have had to build our own GTK application. Not to mention, this has to work across multiple platforms (Ubuntu, CentOS, Gentoo, etc). And I won’t comment on Ubuntu’s new implementation of the Notify-OSD… Which has forced us to build our own GTK application.

###What I have tried thus far###
Environment:
crontab is set to run a verification script as follows:

30 9 * * 1-5 root /usr/share/MSCs/verify_MSCs >/dev/null 2>&1

verify_MSCs script:
Once complete, and has determined there is a user logged into an X session:

Methods Tried:


export DISPLAY=:0.0
/some/long/path/./msc_compliance arg1 arg2 etc...


export DISPLAY=:0.0
export XAUTHORITY="/home/$user/.Xauthority"
/some/long/path/./msc_compliance arg1 arg2 etc...


su $user -c "/some/long/path/msc_compliance arg1 arg2 etc..."


su $user -c "DISPLAY=:0.0 /some/long/path/msc_compliance arg1 arg2 etc..."

Note* All the msc_compliance application does is displays a list of failing components and allows them to browse their compliance history (web based).

What does work with the notification_daemon (if anyone is interested and in the hopes that I have helped someone :slight_smile: ):

KDE folks:

su $user -c "DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(ps -au $user | grep -i "KDEINIT" | grep -v "START_KDEINIT" | awk '{ print $1 }')/environ | sed -e 's/DBUS_SESSION_BUS_ADDRESS=//') $(whereis notify-send | awk '{ print $2 }') -u normal -t 28800000 \"MSC compliance has changed due to a system change\" \"$TMPSCR\""

GNOME folks:

su $user -c "DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(ps -au $user | grep -i "gnome-session" | awk '{ print $1 }')/environ | sed -e 's/DBUS_SESSION_BUS_ADDRESS=//') $(whereis notify-send | awk '{ print $2 }') -i flag.png -u normal -t 28800000 \"MSC compliance has changed due to a system change\" \"$TMPSCR\""

$TMPSCR being the actual message.
$user being… well the user name of course.
-t 28800000 milliseconds to keep the display from building up multiple notifications on the users screen if the user is on vacation or the like. I don’t want them coming back to a storm of compliance drop messages on their screen :wink:

So… my question is basically, how do you start a GUI program for another user? Just like how the other platforms display a GUI program when updates are available… (like most do, so I know its possible)

Any suggestions are welcome! But please, keep in mind this needs to be done for around 5000 computers… And that the only control we have is through a crontab script. No possibility to go around and physically touch each computer.

I have toyed with the idea of having the verify script save a log file, text file or what-ever-file, and then have a users crontab run some kind of script to display the contents of this file… something like that… but can root modify a users crontab file? Because I see so many references about “DO NOT modify the users crontab directly” So I am reluctant to go that route.

Please excuse the lengthy POST! I wanted to be thorough :slight_smile:

I do not follow in depth what you are saying, but basicaly you want to write something on a users X-session.

Just a few thought that came to my mind.

You use

export DISPLAY=:0.0

That means that your assumption is that said user is loged in the first logical screen, but it does not provide for more logins using the Change User possibilities that are available in e.g. Kicker and on a locked session (screens can be reached with CNTRL-ALT-F7, CNTRL-ALT-F8, etc.), or remote login.

You (even root) can not write to an X-session when the user does not allow this (e.g. by using xhost from his session).

Unfortunately… I am relying on the user being on :0.0 I know that is not very robust but will suffice for most of our users. I suppose I could include a ‘for/while’ loop to obtain all active X sessions. But I am just lazy atm. Most of our PCs are single user desktops anyway. But you are absolutely right and I will eventually add sub-routines to solve that dilemma.

I did notice exporting the env variable DISPLAY=:0.0 works well on Ubuntu platforms, but does not yield the same results on SuSE. (our primary platform).

During the time this post has been active I have made discoveries in the xauth list/add that may yield some interesting results… If I do solve my own post I will be sure to include my results :slight_smile:

Thanks for your reply!

K… I have a fix somewhat, but its very ugly, and most certainly would go against the very reason to be applying CIS benchmarks… but its a start:


cat <<EOF > /etc/X11/xinit/xinit.d/xhost-local.sh
#!/bin/sh
xhost +local:root
EOF
chmod 755 /etc/X11/xinit/xinit.d/xhost-local.sh

will do the trick globally… The only other thing needed is to then export the DISPLAY=:0.0 variable before calling your program…

as root:


DISPLAY=:0.0 xclock

and it will display the graphical clock on who’s ever screen is currently using :0.0

Unfortunately ANY user can now export the display variable and have output display on the target device…

I thought adding the local:root <root> part would limit the exposure to only root generated commands, but I tested this with other accounts successfully. But I am posting this message prematurely :slight_smile: I haven’t fully explored the xhost options… Hope this helps somebody!

Solved:


xhost +si:localuser:root

will restrict only root being able to display GUI applications.

So if you can add the above code to globally fire for any/all users that log in, a system wide crontab will be able to display GUI based programs to the target user, as long as you supply the DISPLAY= environment variable first.

Then add this to /etc/profile.local. I think that will do it.

profile.local ftw. :slight_smile: Thanks hcw!

For Ubuntu/Debian it looks like /etc/profile. But like SuSE, it may be overwritten during updates. We will see.