ftp -o - https://jcs.org/move_in | sh -
at master 123 lines 3.4 kB view raw
1#!/bin/sh -e 2# 3# xsudo 4# Run an X11 command via sudo (most likely as an unprivileged user) with 5# temporary, untrusted xauth forwarding and rc-file copying 6# 7# Copyright (c) 2017 joshua stein <jcs@jcs.org> 8# 9# Permission to use, copy, modify, and distribute this software for any 10# purpose with or without fee is hereby granted, provided that the above 11# copyright notice and this permission notice appear in all copies. 12# 13# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20# 21 22# 23# Example setup: 24# groupadd _firefox 25# usermod -G _firefox $USER 26# useradd -g _firefox -m _firefox 27# chmod 770 ~_firefox 28# cp -r ~/.mozilla ~_firefox/ 29# chown -R _firefox:_firefox ~_firefox/.mozilla 30# 31# Add to sudoers: 32# %wheel ALL=(_firefox) NOPASSWD: /usr/local/bin/firefox 33# 34# Example usage: 35# xsudo -u _firefox /usr/local/bin/firefox 36# 37# By default, ~/.fonts.conf and ~/.config/gtk-3.0 are copied into the 38# unprivileged user's home directory before running. Additional 39# files/directories can be specified with multiple -f flags. 40# 41# X11 connections are untrusted by default, but some programs (like firefox) 42# run much slower in this mode for some reason. Passing -t will mark these 43# temporary connections as trusted (see Xsecurity(7)). 44# 45 46usage() { 47 echo "usage: `basename $0` [-f file to copy] [-t] -u username command" 48 exit 1 49} 50 51UNPRIV_USER= 52CMD= 53TRUSTED="untrusted" 54RC_FILES=".fonts.conf .config/gtk-3.0/" 55 56while getopts "f:tu:" o; do 57 case "$o" in 58 f) 59 RC_FILES="${RC_FILES} ${OPTARG}" 60 ;; 61 t) 62 TRUSTED="trusted" 63 ;; 64 u) 65 UNPRIV_USER="$OPTARG" 66 ;; 67 *) 68 usage 69 ;; 70 esac 71done 72shift $((OPTIND-1)) 73 74if [ X"${1}" = X"" ]; then 75 usage 76fi 77 78CMD=$* 79 80# validate unprivileged user 81if [ X"$UNPRIV_USER" = X"" ]; then 82 usage 83fi 84PLINE="getent passwd ${UNPRIV_USER}" 85if [ X"`${PLINE}`" = X"" ]; then 86 echo "user \"${UNPRIV_USER}\" does not exist" > /dev/stderr 87 usage 88fi 89UNPRIV_HOME=`${PLINE} | awk '{ FS=":" }{ print $6 }'` 90if [ X"${UNPRIV_HOME}" = X"" -o ! -d $UNPRIV_HOME ]; then 91 echo "home of ${UNPRIV_USER} (${UNPRIV_HOME}) does not exist" > /dev/stderr 92 exit 1 93fi 94 95# validate unprivileged user's home directory permissions, which must 96# allow us to write to it, but noone else to read from it 97UNPRIV_HOME_P=`ls -l ${UNPRIV_HOME} | awk '{ print $1 }'` 98if [ X"$UNPRIV_HOME_P" = X"drwxrwx---" ]; then 99 echo "permissions on ${UNPRIV_HOME} must be 0770, are ${UNPRIV_HOME_P}" 100 exit 1 101fi 102 103# generate temporary untrusted authorization 104if [ -f $UNPRIV_HOME/.Xauthority ]; then 105 rm -f $UNPRIV_HOME/.Xauthority 106fi 107touch $UNPRIV_HOME/.Xauthority 108xauth -f $UNPRIV_HOME/.Xauthority generate $DISPLAY . $TRUSTED 109chmod 660 $UNPRIV_HOME/.Xauthority 110 111# copy files into the untrusted user's home 112(cd ~; tar -chf - $RC_FILES) | (cd $UNPRIV_HOME; tar xf -) 113for f in $RC_FILES; do 114 chgrp -R $UNPRIV_USER $UNPRIV_HOME/$f 115 chmod -R g=u $UNPRIV_HOME/$f 116done 117 118# run the actual command 119cd $UNPRIV_HOME 120sudo -u $UNPRIV_USER -H $CMD 121 122# remove auth 123rm -f $UNPRIV_HOME/.Xauthority