Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 28 additions & 50 deletions xuserrun
Original file line number Diff line number Diff line change
@@ -1,56 +1,34 @@
#!/bin/bash

#
# Run a command as the currently active X11 user
#
# Run a command as the currently active X.org server user

seat="seat0"

# determine location of loginctl
LOGINCTL=$(command -v loginctl || command -v systemd-loginctl)
if [[ -e LOGINCTL ]]; then
echo "Error: Unable to find loginctl executable"
exit 1
fi

get_session_info() {
local session="$1"
local varname="$2"
local IFS=$'\n'
eval declare -Ag $varname
for row in $(loginctl show-session "$session"); do
key="$(echo "${row}"|cut -d= -f1)"
val="$(echo "${row}"|cut -d= -f2-)"
eval ${varname}[\"${key}\"]=\"${val}\"
done
}

escape() {
for arg in "$@" ; do
printf "%q " "$arg";
done;
}

active_session="$(loginctl show-seat ${seat}|grep ActiveSession|cut -d= -f2)"
if [[ $? -ne 0 || -z $active_session ]]; then
echo "Error: Unable to determine active session"
exit 1
fi

get_session_info $active_session session_info

if [[ ${session_info[Type]} != "x11" ]]; then
echo "Error: Active session is not x11"
exit 2
fi

current_user="$(id -u -n)"

if [[ ${current_user} == ${session_info[Name]} ]]; then
# already correct user, no need to su
DISPLAY="${session_info[Display]}" "$@"
# Program required check
hash loginctl 2>&- || { echo >&2 " Program \"loginctl\" not installed"; exit; }

# Input parameter(s) are executable check
hash "$1" 2>&- || \
{ echo >&2 " The specified \"$1\" is not a valid executable"; exit 1; }

# Search through active sessions for one that has the Display (X.org) value
avail_sessions=$(loginctl show-seat $seat -p Sessions| cut -d= -f2)
for session in $avail_sessions; do
session_disp=$(loginctl show-session $session -p Display | cut -d= -f2)
session_name=$(loginctl show-session $session -p Name | cut -d= -f2)
if [ -z $session_disp ]; then continue
else break
fi
done

# Exit if no X.org server is running
[ -z "$session_disp" ] && echo " No X.org server appears to be running" && exit 2

# Run command as X.org server user
if [ $(whoami) = root ]; then
XAUTHORITY=/home/$session_name/.Xauthority DISPLAY="$session_disp" \
su -c - $session_name "$(printf "%q " "$@")" &
elif [ $(whoami) = $session_name ]; then
eval XAUTHORITY=/home/$session_name/.Xauthority DISPLAY="$session_disp" "$@" &
else
# run command as user
DISPLAY="${session_info[Display]}" su -c - "${session_info[Name]}" "$(escape "$@")"
echo " User does not have X.org server permissions" && exit
fi