non-root users and ACPI

In my experience dealing with ACPI events as a non-root user is a pain in the backside. Firstly, let’s say for arguments sake (even though this isn’t that often) multiple people use a laptop, and want to deal with the “external monitor on/off” button in different ways? Currently there is no simply way to do that AFAIK. So … enters a little script to deal with that particular gripe.

UPDATE 2011/01/22: Add extra code to convert slashes to underscores because it’s counter intuitive to create additional subdirectories under ~/.acpi/ to deal with events such as button/lid.

Not a particular big setup, but basically what this does is allow a user to create a .acpi directory in his home directory, and to then create an executable in that folder with the name of the event (eg, button.lid, video etc …) that will then be executed if, and only if, the user is logged in when that event triggers. The executable will be run as that user at all times to prevent obvious root escalation attacks. This is probably a security risk anyway considering that (currently anyway) there is no event filtering of any kind.

There are two components to this particular “hack”, firstly, a script that figures out who the logged in users are and fires the appropriate user executables and an events file for acpid that informs acpid to run that script.

/etc/acpi/useracpi.sh

#! /bin/bash

logged_users=($(who | awk '{ print $1 }' | sort -u))

ev="${1//\//_}"

for u in "${logged_users[@]}"; do
        h=$(getent passwd $u | awk -F: '{ print $6 }')
        exe="${h}/.acpi/${ev}"
        [ -x "${exe}" ] && su - $u -c "${exe} $*" 2>&1 | logger -t "acpi.$u/$ev"
done

The script is simple enough, I hope. Basically it uses the who command to figure out who’s logged in, sets ev to the first and only parameter (converting slashes to underscores, so an event like button/lid gets converted to button_lid) and then for each user it figures out their home directory, calculates the executable name, and if that executable exist, use the su command to trigger it. Also log any output (this is pointless for most setups, except it allows the root user to go dig out log data out of /var/log/messages for users when they inevitably ask “why doesn’t my script want to work?!?”).

The second component is much simpler, and just informs acpid to always run the above script whenever any acpi event fires:

/etc/acpi/events/useracpi

event=.*
action=/etc/acpi/useracpi.sh %e

And that concludes this particular hack.

One Response to “non-root users and ACPI”

  1. […] Sunday evening and Quintin just made an entry about send-notify. This immediately made me think of non-root users and ACPI and how I had a script on my previous laptop that popped up notifications when battery state […]