become overhaul.
authorIain Patterson <me@iain.cx>
Fri, 5 Feb 2010 13:53:00 +0000 (13:53 +0000)
committerIain Patterson <me@iain.cx>
Thu, 18 Feb 2010 17:44:49 +0000 (17:44 +0000)
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.

12 files changed:
.bash_profile
.become/all [deleted file]
.profile.d/BECOME.bashrc [new file with mode: 0644]
.profile.d/PATH.bashrc
.profile.d/TERM.bashrc
.profile.d/completion.bashrc
.profile.d/p4.bashrc
.profile.d/prompt.bashrc
.profile.d/screen.bashrc
.profile.d/vim.bashrc
opt/bin/became [new file with mode: 0755]
opt/bin/become

index 6c93ffe..61a04b5 100644 (file)
@@ -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 (file)
index 239dca0..0000000
+++ /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 (file)
index 0000000..32a69ed
--- /dev/null
@@ -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
+}
index ab57aaa..0b82245 100644 (file)
@@ -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
index 1c92469..5bb800c 100644 (file)
@@ -1 +1 @@
-export TERMINFO=~/.terminfo
+export TERMINFO=${PROFILE_HOME:-~}/.terminfo
index 3c3ec33..8ff324d 100644 (file)
@@ -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() {
index b4134c0..c44932a 100644 (file)
@@ -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
index 44773fc..2145c22 100644 (file)
@@ -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
index 02026cd..440395e 100644 (file)
@@ -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
 
index 4ee1bc0..bd9c826 100644 (file)
@@ -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 (executable)
index 0000000..245f75b
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+file="$(mktemp)"
+if [ -n "$file" ]; then
+  ( umask 077; cat > "$file"; echo "/bin/rm -f '$file'" >> "$file" )
+  exec </dev/tty /bin/bash --rcfile "$file"
+else
+# Fall back to the shell.
+  exec </dev/tty /bin/bash
+fi
+exit 111
index add9600..f7f037e 100755 (executable)
@@ -1,14 +1,40 @@
 #!/bin/bash
 
-user="$1"
+user="$1"; shift
 if [ -z "$user" ]; then
   echo >&2 "Usage: become <user>"
   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