home *** CD-ROM | disk | FTP | other *** search
/ linuxmafia.com 2016 / linuxmafia.com.tar / linuxmafia.com / pub / linux / security / sux < prev    next >
Text File  |  2001-08-21  |  9KB  |  338 lines

  1. #!/bin/sh
  2.  
  3. # Written by Francois Gouget, fgouget@free.fr
  4. # With many thanks to Daniel Martin and Falk Hueffner for their help
  5. # Sux is released under the terms of the following license (X11 license)
  6.  
  7. # Copyright (c) 2001 Francois Gouget
  8. #
  9. # Permission is hereby granted, free of charge, to any person obtaining a copy
  10. # of this software and associated documentation files (the "Software"), to deal
  11. # in the Software without restriction, including without limitation the rights
  12. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. # copies of the Software, and to permit persons to whom the Software is
  14. # furnished to do so, subject to the following conditions:
  15. #
  16. # The above copyright notice and this permission notice shall be included in
  17. # all copies or substantial portions of the Software.
  18. #
  19. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
  22. # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
  23. # WHETHERIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 
  24. # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  
  26.  
  27. # How to transfer cookies for root. See the sux_cookie_transfer variable
  28. # for options. Note that use-xauthority may not work if home directories
  29. # are on NFS. In such a case, change the default to copy-cookies.
  30. sux_root_cookie_transfer="c"
  31.  
  32.  
  33. usage()
  34. {
  35.   echo "usage: `basename $0` [-m|-p|--preserve-environment]" >&2
  36.   echo "           [--display display]" >&2
  37.   echo "           [--no-cookies|--copy-cookies|--use-xauthority]" >&2
  38.   echo "           [--untrusted] [--timeout x]" >&2
  39.   echo "           [-] [username [command]]" >&2
  40.   exit 2
  41. }
  42.  
  43.  
  44. ##
  45. # Process the sux options
  46. sux_su_opts=""
  47. sux_preserve=""
  48. sux_got_minus=0
  49. # "" -> default, n -> no-cookies, c -> copy-cookies, x -> use-xauthority
  50. sux_cookie_transfer=""
  51. sux_username=""
  52. sux_untrusted=""
  53. sux_timeout=""
  54. while [ $# -gt 0 ]
  55. do
  56.   if [ "$sux_got_minus" = "1" ]
  57.   then
  58.     # Username follows "-"
  59.     sux_username="$1"
  60.     sux_su_opts="$sux_su_opts $1"
  61.     shift
  62.     # The remainder is the command to be executed
  63.     break
  64.   elif [ "$1" = "-" ]
  65.   then
  66.     # Last option before the username
  67.     sux_su_opts="$sux_su_opts $1"
  68.     sux_got_minus=1
  69.     shift
  70.   elif [ "$1" = "-m" -o "$1" = "-p" -o "$1" = "--preserve-environment" ]
  71.   then
  72.     sux_preserve="1"
  73.     sux_su_opts="$sux_su_opts $1"
  74.     shift
  75.   elif [ "$1" = "--display" ]
  76.   then
  77.     if [ $# -lt 2 ]
  78.     then
  79.       echo "--display takes a display name as an argument" >&2
  80.       usage # exits
  81.     fi
  82.     export DISPLAY="$2"
  83.     shift 2
  84.   elif [ "$1" = "--no-cookies" ]
  85.   then
  86.     if [ -n "$sux_cookie_transfer" -a "$sux_cookie_transfer" != "n" ]
  87.     then
  88.       echo "--no-cookies is incompatible with --copy-cookies and --use-xauthority" >&2
  89.       usage # exits
  90.     fi
  91.     sux_cookie_transfer="n"
  92.     shift
  93.   elif [ "$1" = "--copy-cookies" ]
  94.   then
  95.     if [ -n "$sux_cookie_transfer" -a "$sux_cookie_transfer" != "c" ]
  96.     then
  97.       echo "--copy-cookies is incompatible with --no-cookies and --use-xauthority" >&2
  98.       usage # exits
  99.     fi
  100.     sux_cookie_transfer="c"
  101.     shift
  102.   elif [ "$1" = "--use-xauthority" ]
  103.   then
  104.     if [ -n "$sux_cookie_transfer" -a "$sux_cookie_transfer" != "x" ]
  105.     then
  106.       echo "--use-xauthority is incompatible with --no-cookies and --copy-cookies" >&2
  107.       usage # exits
  108.     fi
  109.     sux_cookie_transfer="x"
  110.     shift
  111.   elif [ "$1" = "--untrusted" ]
  112.   then
  113.     sux_untrusted="untrusted"
  114.     shift
  115.   elif [ "$1" = "--timeout" ]
  116.   then
  117.     if [ $# -lt 2 ]
  118.     then
  119.       echo "--timeout takes a timeout in seconds" >&2
  120.       usage # exits
  121.     fi
  122.     sux_timeout="timeout $2"
  123.     shift 2
  124.   elif [ "$1" = "-?" ]
  125.   then
  126.     usage # exits
  127.   else
  128.     # First non-option is the username
  129.     sux_username="$1"
  130.     sux_su_opts="$sux_su_opts $1"
  131.     shift
  132.     # The remainder is the command to be executed
  133.     break
  134.   fi
  135. done
  136.  
  137.  
  138. ##
  139. # Get rid of the simple case
  140. if [ -z "$DISPLAY" ]
  141. then
  142.   # If DISPLAY is not set we can take a shortcut...
  143.   if [ -n "$sux_untrusted" -o -n "$sux_timeout" ]
  144.   then
  145.     echo "--untrusted and --timeout are only supported if DISPLAY is set" >&2
  146.     usage #exits
  147.   fi
  148.   exec su $sux_su_opts "$@"
  149. fi
  150.  
  151.  
  152. ##
  153. # Do some option checking
  154. if [ -z "$sux_username" ]
  155. then
  156.   sux_username="root"
  157. fi
  158. if [ -z "$sux_cookie_transfer" ]
  159. then
  160.   if [ "$sux_username" = "root" ]
  161.   then
  162.     sux_cookie_transfer="$sux_root_cookie_transfer"
  163.   else
  164.     sux_cookie_transfer="c"
  165.   fi
  166. fi
  167. if [ "$sux_cookie_transfer" = "x" -a "$sux_username" != "root" ]
  168. then
  169.   echo "Only root can use --use-xauthority" >&2
  170.   usage # exits
  171. fi
  172.  
  173.  
  174. ##
  175. # Create new cookies / retrieve the existing ones if necessary
  176. if [ -n "$sux_untrusted" -o -n "$sux_timeout" ]
  177. then
  178.   if [ "$sux_cookie_transfer" != "c" ]
  179.   then
  180.     echo "--no-cookies/--use-xauthority are incompatible with --untrusted/--timeout" >&2
  181.     usage #exits
  182.   fi
  183.  
  184.   # Yeah, tempfile is a debian-specific command.  Workarounds exist for
  185.   # other machines.  If you do use a workaround, be certain that said
  186.   # workaround actually creates the new file, (via touch or similar) or
  187.   # xauth (below) will produce a pointless warning message.
  188.   sux_tmpfile=`tempfile -p sux`
  189.   xauth -q -f $sux_tmpfile generate $DISPLAY . $sux_untrusted $sux_timeout
  190.   sux_xauth_data=`xauth -f $sux_tmpfile nlist $DISPLAY`
  191.   rm -f $sux_tmpfile
  192. fi
  193.  
  194.  
  195. ## 
  196. # Build the command to restore the cookies in the su
  197. if [ "$sux_cookie_transfer" = "c" ]
  198. then
  199.   # --copy-cookies case. We copy the cookie(s) using the xauth command.
  200.  
  201.   # If display is of the form "host:x.y" we may also need to get the 
  202.   # cookies for "host/unix:x.y".
  203.   sux_unix_display=`echo $DISPLAY | sed -e 's#^\([a-zA-Z_.][a-zA-Z_.]*\):#\1/unix:#'`
  204.   if [ "$DISPLAY" = "$sux_unix_display" ]
  205.   then
  206.     sux_unix_display=""
  207.   fi
  208.  
  209.   # Get the cookies if we don't have them already
  210.   if [ -z "$sux_xauth_data" ]
  211.   then
  212.     # Get the cookies. Note that we may need to 
  213.     sux_xauth_data=`xauth -q nlist $DISPLAY`
  214.     if [ -n "$sux_unix_display" ]
  215.     then
  216.       sux_xauth_data="$sux_xauth_data `xauth -q nlist $sux_unix_display`"
  217.     fi
  218.   fi
  219.  
  220.   # We highjack the TERM environment variable to transfer the cookies to the 
  221.   # other user. We do this so that they never appear on any command line, and 
  222.   # because TERM appears to be the only environment variable that is not 
  223.   # reset by su. Then, as long as 'echo' is a shell builtin, these cookies 
  224.   # will never appear as command line arguments which means noone will be 
  225.   # able to intercept them (assuming they were safe in the first place).
  226.   sux_term="TERM='$TERM'"
  227.   # now we can store the script that will restore the cookies on the other 
  228.   # side of the su, in TERM!
  229.  
  230.   # Remove the old cookies. They may cause trouble if we transfer only one 
  231.   # cookie, e.g. an MIT cookie, and there's still a stale XDM cookie hanging 
  232.   # around.
  233.   export TERM="xauth -q remove $DISPLAY 2>/dev/null;"
  234.   if [ -n "$sux_unix_display" ]
  235.   then
  236.     TERM="$TERM xauth -q remove $sux_unix_display;"
  237.   fi
  238.  
  239.   # Note that there may be more than one cookie to transfer, hence 
  240.   # this loop
  241.   sux_i=0
  242.   for sux_str in $sux_xauth_data
  243.   do
  244.     if [ $sux_i -eq 0 ]
  245.     then
  246.       TERM="$TERM echo $sux_str"
  247.     else
  248.       TERM="$TERM $sux_str"
  249.     fi
  250.     sux_i=`expr $sux_i + 1`
  251.     if [ $sux_i -eq 9 ]
  252.     then
  253.       TERM="$TERM | xauth nmerge - ;"
  254.       sux_i=0
  255.     fi
  256.   done
  257.   sux_xauth_cmd="eval \$TERM;"
  258.   sux_xauthority=""
  259. elif [ "$sux_cookie_transfer" = "x" ]
  260. then
  261.   # --use-xauthority case. For root we can simplify things and simply 
  262.   # access the original user's .Xauthority file.
  263.   sux_term=""
  264.   sux_xauth_cmd=""
  265.   if [ -n "$XAUTHORITY" ]
  266.   then
  267.     sux_xauthority="XAUTHORITY='$XAUTHORITY'"
  268.   else
  269.     sux_xauthority="XAUTHORITY='$HOME/.Xauthority'"
  270.   fi
  271. else
  272.   # --no-cookies case. We just transfer $DISPLAY and assume the 
  273.   # target user already has the necessary cookies
  274.   sux_term=""
  275.   sux_xauth_cmd=""
  276.   sux_xauthority=""
  277. fi
  278.  
  279.  
  280. ##
  281. # Marshall the specified command in an effort to support parameters that 
  282. # contain spaces. This should be enough to get commands like 
  283. # 'xterm -title "My XTerm"' to work.
  284. sux_cmd=""
  285. if [ $# -gt 0 ]
  286. then
  287.   while [ $# -gt 0 ]
  288.   do
  289.     sux_cmd="$sux_cmd \"$1\""
  290.     shift
  291.   done
  292. elif [ "`basename $0`" = "suxterm" ]
  293. then
  294.   # Start an xterm, useful for temporary cookies
  295.   sux_cmd=`which x-terminal-emulator`
  296.   if [ -z "$sux_cmd" ]
  297.   then
  298.     sux_cmd="xterm"
  299.   fi
  300. else
  301.   # If no command is specified, start a shell
  302.   if [ $# -eq 0 ]
  303.   then
  304.     if [ "$sux_got_minus" = "1" ]
  305.     then
  306.       sux_cmd="sh -c \"exec -l \$SHELL\""
  307.     else
  308.       sux_cmd="\$SHELL"
  309.     fi
  310.   fi
  311. fi
  312.  
  313.  
  314. ##
  315. # We would not want the other user to try and use our XAUTHORITY file. He 
  316. # wouldn't have the proper access rights anyway...
  317. unset XAUTHORITY
  318.  
  319.  
  320. ##
  321. # --preserve-environment special case
  322. if [ -n "$sux_preserve" -a -n "$sux_xauth_cmd" ]
  323. then
  324.   sux_home=`egrep "^$sux_username:" /etc/passwd | cut -d: -f6`
  325.   if [ -z "$sux_home" ]
  326.   then
  327.     echo "WARNING: --preserve-environment has been set, but no good value was found for XAUTHORITY, expect trouble" >&2
  328.   else
  329.     export XAUTHORITY="$sux_home/.Xauthority"
  330.   fi
  331. fi
  332.  
  333.  
  334. ##
  335. # Execute su
  336. exec su $sux_su_opts -c "$sux_xauth_cmd \
  337.      exec env $sux_xauthority $sux_term DISPLAY='$DISPLAY' $sux_cmd;"
  338.