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