From f00d519dd073659e3a079be65c57d5b64cb60a69 Mon Sep 17 00:00:00 2001 From: Iain Patterson Date: Fri, 5 Feb 2010 13:53:00 +0000 Subject: [PATCH] become overhaul. Pass commands to sudo through stdin. Use these commands to set the environment for the destination user. Replace all $HOME paths with $PROFILE_HOME, set when becoming. Make .become/all optional as its functionality has been moved. --- .bash_profile | 2 +- .become/all | 13 ------------- .profile.d/BECOME.bashrc | 27 +++++++++++++++++++++++++++ .profile.d/PATH.bashrc | 26 ++++++++++++++++++++------ .profile.d/TERM.bashrc | 2 +- .profile.d/completion.bashrc | 6 +++--- .profile.d/p4.bashrc | 15 ++++++++------- .profile.d/prompt.bashrc | 4 ++-- .profile.d/screen.bashrc | 2 +- .profile.d/vim.bashrc | 9 ++++++++- opt/bin/became | 11 +++++++++++ opt/bin/become | 30 ++++++++++++++++++++++++++++-- 12 files changed, 110 insertions(+), 37 deletions(-) delete mode 100644 .become/all create mode 100644 .profile.d/BECOME.bashrc create mode 100755 opt/bin/became diff --git a/.bash_profile b/.bash_profile index 6c93ffe..61a04b5 100644 --- a/.bash_profile +++ b/.bash_profile @@ -11,7 +11,7 @@ if $(tty -s) || [ "${0:0:1}" = "-" -o "$1" = "force" ]; then LC_ALL=C # Source all scripts. - for i in ~/.profile.d/*.bashrc; do . "$i"; done; unset i + for i in ${PROFILE_HOME:-~}/.profile.d/*.bashrc; do . "$i"; done; unset i # Maybe turn nocaseglob back on. [ $nocg = 0 ] && shopt -s nocaseglob diff --git a/.become/all b/.become/all deleted file mode 100644 index 239dca0..0000000 --- a/.become/all +++ /dev/null @@ -1,13 +0,0 @@ -cd -export TERMINFO=$BECOME_HOME/.terminfo -. $BECOME_HOME/.profile.d/ps1.bashrc -. $BECOME_HOME/.profile.d/krb5.bashrc -__ps1 -vim=$($BECOME_HOME/opt/bin/find_working vim 2>/dev/null) -if [ -n "$vim" ]; then - vim="$vim --cmd ':se rtp=$BECOME_HOME/.vim,\$VIMRUNTIME' -u $BECOME_HOME/.vimrc" - alias vim="$vim" - alias vi=vim -fi -unset vim -set -o vi diff --git a/.profile.d/BECOME.bashrc b/.profile.d/BECOME.bashrc new file mode 100644 index 0000000..32a69ed --- /dev/null +++ b/.profile.d/BECOME.bashrc @@ -0,0 +1,27 @@ +# Find a path, preferring the target user's version. +function find_target_profile() { + local path="$1"; shift + + for dir in $HOME $PROFILE_HOME; do + if [ -e "$dir/$path" ]; then + echo "$dir/$path" + break + fi + done + + unset dir +} + +# Find a path, preferring the source user's version. +function find_source_profile() { + local path="$1"; shift + + for dir in $PROFILE_HOME $HOME; do + if [ -e "$dir/$path" ]; then + echo "$dir/$path" + break + fi + done + + unset dir +} diff --git a/.profile.d/PATH.bashrc b/.profile.d/PATH.bashrc index ab57aaa..0b82245 100644 --- a/.profile.d/PATH.bashrc +++ b/.profile.d/PATH.bashrc @@ -6,7 +6,7 @@ # # Location of the XXXdirs files. -DIR="$HOME/.PATH" +DIR=${PROFILE_HOME:-~}/.PATH # Paths to set and the file to get them from @variable to copy from. PATHS=" @@ -49,6 +49,19 @@ function copypath() { [ -z "$path" ] || eval "export $newpath='$path'" } +# Helper. +function addpath() { + local path="$1"; shift + local dir="$1"; shift + + dir=$(eval echo "$dir") + if [ -d "$dir" ]; then + echo "$path:$dir" + else + echo "$path" + fi +} + # Set a path from directories. function makepath() { local newpath="$1"; shift @@ -61,10 +74,11 @@ function makepath() { # Read them. local path= while read dir; do - local dir=$(eval echo "$dir") - [ -d "$dir" ] || continue - - path="$path:$dir" + path=$(addpath "$path" "$dir") + if [ -n "$PROFILE_HOME" -a ! "${dir#\$HOME}" = "$dir" ]; then + dir="$PROFILE_HOME${dir#\$HOME}" + path=$(addpath "$path" "$dir") + fi done < "$dirs" # Restore IFS. @@ -115,4 +129,4 @@ for path in $PATHS; do done -unset DIR PATHS dir dirs path var source sanitisepath copypath makepath newpath setpaths +unset DIR PATHS dir dirs path var source sanitisepath copypath makepath newpath addpath diff --git a/.profile.d/TERM.bashrc b/.profile.d/TERM.bashrc index 1c92469..5bb800c 100644 --- a/.profile.d/TERM.bashrc +++ b/.profile.d/TERM.bashrc @@ -1 +1 @@ -export TERMINFO=~/.terminfo +export TERMINFO=${PROFILE_HOME:-~}/.terminfo diff --git a/.profile.d/completion.bashrc b/.profile.d/completion.bashrc index 3c3ec33..8ff324d 100644 --- a/.profile.d/completion.bashrc +++ b/.profile.d/completion.bashrc @@ -2,9 +2,9 @@ if ! builtin complete 2>&1 | grep 'not a shell builtin' >/dev/null; then # Helper! -COMPLETION_DIR_SSH=~/.ssh/hosts -COMPLETION_DIR_TELNET=~/.telnet/hosts -COMPLETION_DIR_RDP=~/.rdp/hosts +COMPLETION_DIR_SSH=${PROFILE_HOME:-~}/.ssh/hosts +COMPLETION_DIR_TELNET=${PROFILE_HOME:-~}/.telnet/hosts +COMPLETION_DIR_RDP=${PROFILE_HOME:-~}/.rdp/hosts COMPLETION_DIR_PING="$COMPLETION_DIR_SSH $COMPLETION_DIR_TELNET $COMPLETION_DIR_RDP" function _generic_completion() { diff --git a/.profile.d/p4.bashrc b/.profile.d/p4.bashrc index b4134c0..c44932a 100644 --- a/.profile.d/p4.bashrc +++ b/.profile.d/p4.bashrc @@ -7,17 +7,18 @@ fi export P4CONFIG=.p4config eval $(alias diff 2>/dev/null | sed 's/^alias diff/P4DIFF/') export P4DIFF="${P4DIFF:-diff} -u" -if [ -e "$HOME/.vim/script/p4" ]; then - export P4EDITOR="vim -S '$HOME/.vim/script/p4'" -else - export P4EDITOR=vim -fi +P4EDITOR=vim +p4script=$(find_target_profile ".vim/script/p4") +[ -n "$p4script" ] && P4EDITOR="vim -S '$p4script'" +export P4EDITOR if [ -z "$DISPLAY" ]; then - if [ -e "$HOME/.vim/script/p4" ]; then - export P4MERGE="vim -S '$HOME/.vim/script/p4'" + p4script=$(find_target_profile ".vim/script/merge") + if [ -n "$p4script" ]; then + export P4MERGE="vim -S '$p4script'" else export P4MERGE="vim -o -c '3wincmd j' -c 'wincmd L'" fi else export P4MERGE="p4merge" fi +unset p4script diff --git a/.profile.d/prompt.bashrc b/.profile.d/prompt.bashrc index 44773fc..2145c22 100644 --- a/.profile.d/prompt.bashrc +++ b/.profile.d/prompt.bashrc @@ -4,8 +4,8 @@ SSH_FORWARDED=$(get_remote_ip) if [ ! -z "$SSH_FORWARDED" ]; then if [ "$SSH_FORWARDED" = "localhost" ]; then SSH_FORWARDED= - elif [ -f ~/.ssh/forwarded ]; then - for forwarded in $(< ~/.ssh/forwarded); do + elif [ -f ${PROFILE_HOME:-~}/.ssh/forwarded ]; then + for forwarded in $(< ${PROFILE_HOME:-~}/.ssh/forwarded); do if echo "$SSH_FORWARDED" | grep "$forwarded" &>/dev/null; then SSH_FORWARDED= fi diff --git a/.profile.d/screen.bashrc b/.profile.d/screen.bashrc index 02026cd..440395e 100644 --- a/.profile.d/screen.bashrc +++ b/.profile.d/screen.bashrc @@ -6,7 +6,7 @@ if [ $? = 0 ]; then if [ -n "$SUDO_USER" ]; then unset SCREENDIR else - export SCREENDIR="$HOME/.screen/$HOSTNAME" + export SCREENDIR="${PROFILE_HOME:-~}/.screen/$HOSTNAME" fi fi diff --git a/.profile.d/vim.bashrc b/.profile.d/vim.bashrc index 4ee1bc0..bd9c826 100644 --- a/.profile.d/vim.bashrc +++ b/.profile.d/vim.bashrc @@ -1,3 +1,10 @@ vim=$(find_working vim 2>/dev/null) -[ $? = 0 ] && alias vi="$vim" +if [ $? = 0 ]; then + if [ -n "$PROFILE_HOME" ]; then + alias vim="$vim --cmd ':se rtp=$PROFILE_HOME/.vim,\$VIMRUNTIME' -u $PROFILE_HOME/.vimrc" + else + alias vim="$vim" + fi + alias vi="vim" +fi unset vim diff --git a/opt/bin/became b/opt/bin/became new file mode 100755 index 0000000..245f75b --- /dev/null +++ b/opt/bin/became @@ -0,0 +1,11 @@ +#!/bin/bash + +file="$(mktemp)" +if [ -n "$file" ]; then + ( umask 077; cat > "$file"; echo "/bin/rm -f '$file'" >> "$file" ) + exec &2 "Usage: become " exit 1 fi PRINCIPAL=$(klist 2>/dev/null | sed -n 's/^Default principal: //p') +if [ -n "$DISPLAY" -a "${DISPLAY##localhost:}" = "$DISPLAY" ]; then + COOKIE="$(xauth list $DISPLAY)" +fi BECOME="$HOME/.become" profile="$BECOME/$user" [ -f "$profile" ] || profile="$BECOME/all" -exec sudo -H -u "$user" env BECOME_HOME="$HOME" PRINCIPAL=$PRINCIPAL /bin/bash --rcfile "$profile" +file="$(mktemp)" +if [ -n "$file" ]; then + exec 3>"$file" + exec <"$file" + rm "$file" + + echo >&3 "cd" + echo >&3 "PROFILE_HOME='$HOME'" + [ -n "$PRINCIPAL" ] && echo >&3 "PRINCIPAL='$PRINCIPAL'" + if [ -n "$DISPLAY" -a -n "$COOKIE" ]; then + echo >&3 "xauth add $COOKIE" + else + echo >&3 "unset DISPLAY" + fi + + echo >&3 2>/dev/null ". $HOME/.bash_profile" + [ -f "$BECOME/all" ] && cat >&3 2>/dev/null "$BECOME/all" + [ -f "$BECOME/$user" ] && cat >&3 2>/dev/null "$BECOME/$user" +fi + +dir=$(dirname "$0") +[ "$dir" = "." ] && dir="$PWD" +exec sudo -H -u "$user" "$dir/became" +exit 111 -- 2.20.1