ea4926dd85d0c08ec1b3b4188aa6328941234043
[profile.git] / opt / bin / become
1 #!/bin/bash
2
3 chdir=0
4 kerberos=0
5 x11=0
6 dir=
7 while getopts ":cd:kx" opt; do
8   case $opt in
9     c) chdir=1;;
10     d) dir=$OPTARG;;
11     k) kerberos=1;;
12     x) x11=1;;
13   esac
14 done
15 shift $((OPTIND-1))
16
17 if [ -z "$dir" ]; then
18   dir=${0%/*}
19   [ "$dir" = "$0" -o "$dir" = "." ] && dir=$PWD
20 fi
21
22 user="$1"; shift
23 if [ -z "$user" ]; then
24   echo >&2 "Usage: become [-c] [-d <dir>] [-k] [-x] <user>"
25   echo >&2 "Options: -c         Stay in current directory even if target user is not root."
26   echo >&2 "         -d <dir>   Look for \"became\" script in given directory."
27   echo >&2 "         -k         Delegate Kerberos credentials even if target user is not root."
28   echo >&2 "         -x         Delegate X11 cookie even if target user is not root."
29   exit 1
30 fi
31
32 uid=$(PATH=/usr/xpg4/bin:/usr/bin id -u "$user" 2>/dev/null)
33 if [ -z "$uid" ]; then
34   echo >&2 "Who is $user?"
35   exit 2
36 fi
37
38 if [ $uid = 0 ]; then
39   chdir=1
40   kerberos=1
41   x11=1
42 fi
43
44 PRINCIPAL=$(klist 2>/dev/null | sed -n 's/^Default principal: //p')
45 if [ $x11 = 1 -a -n "$DISPLAY" -a "${DISPLAY##localhost:}" = "$DISPLAY" ]; then
46   COOKIE="$(xauth list $DISPLAY)"
47 fi
48 ignore_profile_user=0
49 for candidate in "$HOME" "$PROFILE_HOME"; do
50   [ -n "$candidate" ] || continue
51   BECOME="$candidate/.become"
52   [ -d "$BECOME" ] || continue
53
54   # Script to run when becoming any user.
55   [ -z "$allusersprofile" ] && allusersprofile="$BECOME/all"
56   [ -f "$allusersprofile" ] || allusersprofile=
57
58   # Set $HOME/all sticky to ignore $PROFILE_HOME/$user.
59   if [ "$candidate" = "$HOME" ]; then
60     [ -k "$BECOME/all" ] && ignore_profile_user=1
61   else
62     [ $ignore_profile_user = 1 ] && continue
63   fi
64
65   # Script to run (after the one mentioned above) when becoming this user.
66   [ -z "$userprofile" ] && userprofile="$BECOME/$user"
67   [ -f "$userprofile" ] || userprofile=
68 done
69
70 # Preserve environment variables.
71 ignore_environment_user=0
72 for candidate in "$HOME" "$PROFILE_HOME"; do
73   [ -n "$candidate" ] || continue
74   BECOME="$candidate/.become/environment"
75   [ -d "$BECOME" ] || continue
76
77   # Script to run when becoming any user.
78   [ -z "$allusersenvironment" ] && allusersenvironment="$BECOME/all"
79   [ -f "$allusersenvironment" ] || allusersenvironment=
80
81   # Set $HOME/all sticky to ignore $PROFILE_HOME/$user.
82   if [ "$candidate" = "$HOME" ]; then
83     [ -k "$BECOME/all" ] && ignore_environment_user=1
84   else
85     [ $ignore_environment_user = 1 ] && continue
86   fi
87
88   # Environment variables to preserve when becomeing this user.
89   [ -z "$userenvironment" ] && userenvironment="$BECOME/$user"
90   [ -f "$userenvironment" ] || userenvironment=
91 done
92
93 file="${TMPDIR:-/tmp}/$USER.become.$user.$RANDOM.$$"
94 umask=$(builtin umask -p)
95 builtin umask 077
96 if exec 3>"$file" && exec <"$file" && rm "$file"; then
97   builtin $umask
98   echo >&3 "cd"
99   echo >&3 "PROFILE_HOME='${PROFILE_HOME:-$HOME}'"
100   if [ -n "$PRINCIPAL" ]; then
101     echo >&3 "PRINCIPAL='$PRINCIPAL'"
102     if [ $kerberos = 1 ]; then
103       ccname=$(klist 2>/dev/null | sed -n 's/^Ticket cache: [DF]I[LR][E:]://p')
104       if [ -f "$ccname" ]; then
105         echo >&3 "export KRB5CCNAME='$KRB5CCNAME'"
106         openssl=$(find_working openssl)
107         if [ -n "$openssl" ]; then
108           echo >&3 "KRB5OPENSSL='$openssl'"
109           echo >&3 "KRB5BASE64='$($openssl enc -a -in $ccname)'"
110         fi
111       fi
112     fi
113   fi
114   if [ -n "$DISPLAY" -a -n "$COOKIE" ]; then
115     echo >&3 "xauth add $COOKIE"
116   else
117     echo >&3 "unset DISPLAY"
118   fi
119   if [ ! "$PROFILE_HOME" = "$HOME" ]; then
120     echo >&3 "export SCREENRC=$PROFILE_HOME/.screenrc"
121   fi
122 else
123   exit 111
124 fi
125
126 echo >&3 ". ${PROFILE_HOME:-$HOME}/.bash_profile"
127 for profile in "$allusersprofile" "$userprofile"; do
128   [ -f "$profile" ] && cat >&3 2>/dev/null "$profile"
129 done
130 for environment in "$allusersenvironment" "$userenvironment"; do
131   [ -f "$environment" ] || continue
132   while read -d $'\n' variable; do
133     variable=${variable%%=*}
134     eval "[ -z \${$variable:+set} ] || echo >&3 \"$variable='\$$variable'\""
135   done < "$environment"
136 done
137 [ $chdir = 1 ] && echo >&3 2>/dev/null "cd - &>/dev/null"
138
139 exec 3>&-
140 exec sudo -H -u "$user" "$dir/became"
141 exit 111