home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / c / cops_104.zip / cops_104 / checkacct / ca.src < prev    next >
Text File  |  1992-03-10  |  14KB  |  568 lines

  1. #!/bin/sh
  2. #
  3. # paths to some important programs
  4. #
  5.  
  6. #
  7. # This is the language used to parse the .rhosts file.  If you rewrite the
  8. # parser in a different language, you should change this.  If it doesn't
  9. # exist, that's "ok".  chkacct will notice that.
  10. #
  11. PERL=perlpath()
  12.  
  13. #
  14. # This is the program used to parse the .rhosts file.  If you rewrite it, you
  15. # should change PERL1 to be the location of your new program.  You should also
  16. # send me a copy because I'm a packrat for stuff like this.
  17. #
  18. PERL1=installpath()lib/chkacct/rhosts.pl
  19.  
  20. #
  21. # This directory contains the info and effect files that chkacct(1L) references.
  22. #
  23. DOCPATH=installpath()lib/chkacct
  24.  
  25. # default variable values prevent nasty surprises
  26. # (its good style, too)
  27. #
  28.  
  29. # The title of the guru to send customers to  (maybe your name if you work at a 
  30. #  small company..)
  31. GURU=gurudude()
  32.  
  33. #
  34. # The name of the security article
  35. #
  36. ARTICLE=Article
  37.  
  38. #
  39. # The name of the pager you want to use to display info files.  This is 
  40. # probably "more" or "less" at most sites, but never cat, because things
  41. # scroll off the screen too quickly.
  42. PAGER=pagerpath()
  43.  
  44. #
  45. # miscellaneous stuff
  46. #
  47. CAT=catpath()
  48. THISSHELL=$$
  49. EXITCOND=0
  50. UNIQUE=1
  51. trap 'echo "Exiting."; %eval^ $stop_dots; exit;' 0;
  52. trap 'echo "Exiting."; %eval^ $stop_dots; exit;' 1;
  53. trap 'echo "Exiting."; %eval^ $stop_dots; exit;' 2;
  54. trap 'echo "Exiting."; %eval^ $stop_dots; exit;' 3;
  55.  
  56. # an example shell command line parser that conforms to the getopt    (ksb)
  57. # standard, Kevin Braunsdorf, ksb@cc.purdue.edu
  58.  
  59. # our program name and usage message
  60. progname=`basename $0`
  61. usage="$progname: usage [-ehinqrv] [-f <startdir>] [-m <homedir>] [-s <username]"
  62.  
  63. # how to slide a single letter option off the beginning of a bundle
  64. # -barf -> -arf
  65. slide='P=$1; %shift^; set _ -`expr "$P" : '\''-.\(.*\)'\''` ${1+"$@"}; %shift^'
  66. param='if [ $# -lt 2 ]; then echo "$progname: missing value for $1" 1>&2 ; exit 1; fi'
  67.  
  68. # default values for all the flags, or leave unset for a ${flag-value) form
  69.  
  70. # verbose by default
  71. VERBOSE=1
  72. # interactive by default
  73. INTERACTIVE=1
  74. # cavalier by default
  75. HARMLESS=0
  76. # check .rhosts file by default
  77. RHOSTS=1
  78.  
  79. # read an environment variable as well as the command line options:
  80. # protect this script from leading -x's with a bogus underbar, then remove it
  81. set _ $ZZZ ${1+"$@"}
  82. %shift^
  83.  
  84. # get the options from the command line (+ any variables)
  85. while [ $# -gt 0 ]
  86. do
  87.     case "$1" in
  88.     -e)
  89.         INTERACTIVE=0
  90.         %shift^
  91.         ;;
  92.     -e*)
  93.         INTERACTIVE=0
  94.         %eval^ "$slide"
  95.         ;;
  96.     -f)
  97.         %eval^ "$param"
  98.                 START_DIR=$2
  99.                 %shift^ ; %shift^
  100.         ;;
  101.     -f*)
  102.         START_DIR=`expr "$1" : '-.\(.*\)'`
  103.                 %shift^
  104.         ;;
  105.     -i)
  106.         INTERACTIVE=1
  107.         %shift^
  108.         ;;
  109.     -i*)
  110.         INTERACTIVE=1
  111.         %eval^ "$slide"
  112.         ;;
  113.     -m)
  114.         %eval^ "$param"
  115.                 HOME=$2
  116.                 %shift^ ; %shift^
  117.         ;;
  118.     -m*)
  119.         HOME=`expr "$1" : '-.\(.*\)'`
  120.                 %shift^
  121.         ;;
  122.     -n)
  123.         HARMLESS=1
  124.         %shift^
  125.         ;;
  126.     -n*)
  127.         HARMLESS=1
  128.         %eval^ "$slide"
  129.         ;;
  130.     -q)
  131.         VERBOSE=0
  132.         %shift^
  133.         ;;
  134.     -q*)
  135.         VERBOSE=0
  136.         %eval^ "$slide"
  137.         ;;
  138.     -r)
  139.         RHOSTS=0
  140.         %shift^
  141.         ;;
  142.     -r*)
  143.         RHOSTS=0
  144.         %eval^ "$slide"
  145.         ;;
  146.     -s)
  147.         %eval^ "$param"
  148.         ME=$2
  149.         HOME=`echo "echo ~${ME}" | cshpath() `;
  150.         %shift^ ; %shift^
  151.         ;;
  152.     -s*)
  153.         ME=`expr "$1" : '-.\(.*\)'`
  154.         HOME=`echo "echo ~${ME}" | cshpath() `;
  155.         %shift^
  156.         ;;
  157.     -v)
  158.         VERBOSE=1
  159.         %shift^
  160.         ;;
  161.     -v*)
  162.         VERBOSE=1
  163.         %eval^ "$slide"
  164.         ;;
  165.     --)
  166.         %shift^
  167.         break
  168.         ;;
  169.     -h|-h*)
  170.         cat <<HERE
  171. $usage
  172. e        expert (non-interactive) do not ask the user any questions
  173. f <startdir>    specify the directory in which to begin the general file check
  174.             (\${HOME} is the default)
  175. h        print this help message
  176. i        interactive mode - ask the user about every file (default)
  177. m <home dir>    specify a home directory (\${HOME} is the default)
  178. n        do not actually alter any file permissions or files
  179. q        perform actions quietly
  180. r        do not check of \${HOME}/.rhosts file
  181. s <username>    run chkacct as if my userid were <username> (also sets \${HOME} to ~username)
  182. v        perform actions verbosely (this is the default)
  183. HERE
  184.         exit 0
  185.         ;;
  186.     -*)
  187.         echo "$usage" 1>&2 
  188.         exit 1
  189.         ;;
  190.     *)
  191.         # process and continue for intermixed options & args
  192.         break
  193.         ;;
  194.     esac
  195. done
  196.  
  197. # set my identity if it hasn't been done yet
  198. if [ -z "${ME}" ]; then
  199.  
  200.     ME=`whoami`;
  201.     if [ \( -z "${ME}" \) -o \( $? -ne 0 \) ]; then
  202.         echo "Cannot determine your identity - exiting, nothing checked.";
  203.         EXITCOND=1;
  204.         exit ${EXITCOND};
  205.     fi;
  206. fi;
  207.  
  208. # set my home directory if it hasn't been set yet
  209. if [ -z "${HOME}" ]; then
  210.  
  211.     HOME=`echo "echo ~${ME}" | cshpath() `;
  212.     if [ -z "${HOME}" ]; then
  213.         echo "Cannot determine your home directory - exiting, nothing checked.";
  214.         EXITCOND=1;
  215.         exit ${EXITCOND};
  216.     fi;
  217. fi;
  218.  
  219. # search only in the home dir by default
  220. if [ -z "${START_DIR}" ]; then
  221.  
  222.     START_DIR=${HOME};
  223. fi
  224.  
  225. #
  226. # For debugging, silly.
  227. #
  228. # echo "Performing account check with username = ${ME}, home dir = ${HOME}, and";
  229. # echo "starting directory ${START_DIR}";
  230.  
  231. #
  232. # Ok, this is actually checkacct.
  233. #
  234.  
  235. #
  236. # Define a routine which will display files.  If sites have their own favorite
  237. # pager or display method, it can be specified here.  If you just wanted
  238. # to use a simple pager, you would define PAGER to be equal to it, and then
  239. # you would change the line below that display it to be:
  240. #   ${PAGER} ${DOCPATH}/${DISPLAY};
  241. # REMEMBER!  Before you call this routine, you must set DISPLAYFILE to be
  242. # the file you want displayed
  243. #
  244. display_file='
  245. if [ -f ${DOCPATH}/${DISPLAYFILE} ]; then
  246.  
  247.     ${PAGER} ${DOCPATH}/${DISPLAYFILE};
  248. fi;'
  249.  
  250. #
  251. # Its crucial that we don't leave shell variables like $* set 
  252. # when we're not expecting it.  For that reason, here's a small routine
  253. # to clear the contents of $* by shift'ing.  For some reason, each set
  254. # successively lengthens $*.
  255. #
  256. clear_args='
  257. for i
  258. do
  259.     %shift^;
  260. done;'
  261.  
  262. #
  263. #  Before each situation where the user might be queried as to the action,
  264. #  one needs to remember to set the following shell variables:
  265. #
  266. #  FIX - the shell command to fix it with \$TARGET to be the file to
  267. #     be operated upon
  268. #  MANPAGES - a list of man pages it will tell you to look at
  269. #  INFO - The name of the info file in which more info is to be found (if any)
  270. #  EFFECT - The name of the file which describes the effect of the fix
  271. #  PROBLEM - This is the problem string -- it may be printed several times.
  272. #
  273. # define the prompt/decision routine which will make the fix if necessary, print
  274. # out specific info, refer someone to a manual page.
  275. prompt='
  276. FIXED=0;
  277. while [ ${FIXED} -eq 0 ]; do
  278.     echo "";
  279.     echo "${PROBLEM}";
  280.     echo "The output of the command \"ls -lsopt()ld ${PROBLEMFILE}\" is:";
  281.     /bin/ls -lsopt()ld ${PROBLEMFILE};
  282.     echo "";
  283.     echo "The suggested fix for this is to execute the command:";
  284.     echo "    ${FIX}";
  285.  
  286.     if [ ${VERBOSE} -eq 1 ]; then
  287.         if [ \( -f ${DOCPATH}/${EFFECT} \) -a \( ! -d  ${DOCPATH}/${EFFECT} \) ]; then
  288.             ${CAT} ${DOCPATH}/${EFFECT};
  289.         fi;
  290.     fi;
  291.  
  292.     if [ ${INTERACTIVE} -eq 1 ]; then
  293.         echo ""; 
  294.         echo "Press a letter (a) to enter automatic mode (no more questions), (f)ix problem,";
  295.         echo "(h)elp me out with this menu, (i)gnore problem, (m)ore info";
  296.         echownl(%Press RETURN/NEWLINE to fix the problem and go on> ^);
  297.         read input;
  298.     else
  299.         input="f";
  300.     fi;
  301.  
  302.     case $input in
  303.         a*)
  304.             echo "";
  305.             echo "This will put you into automatic mode.  No more questions will be asked,";
  306.             echo "and all problems will be automatically fixed unless you specified the";
  307.             echo "\"harmless(-n)\" option on startup.";
  308.             echo "";
  309.             echownl(%Press \"yes\" to enter automatic mode> ^);
  310.             read confirm;
  311.             if [ \( ! -z "$confirm" \) -a \( "$confirm" = "yes" \) ]; then
  312.                 echo "Beginning automatic mode.";
  313.                 INTERACTIVE=0;
  314.                 echo "";
  315.             fi;
  316.             ;;
  317.         h*)
  318.             DISPLAYFILE="prompt.help";
  319.             %eval^ $display_file;
  320.             ;;
  321.         m*)
  322.             DISPLAYFILE=${INFO};
  323.             %eval^ $display_file;
  324.             if [ -n "$MANPAGES" -a ${VERBOSE} -eq 1 ]; then
  325.                 echo "";
  326.                 echo "For additional information, read the manual page for the following";
  327.                 echo "program(s): ${MANPAGES}";
  328.                 echo "The command man <name of program> will show you the manual page.";
  329.                 echo "";
  330.             fi;
  331.             ;;
  332.         i*)
  333.             echo "Ignoring problem -- taking no action.";
  334.             FIXED=1;
  335.             ;;
  336.         *|f*) 
  337.             if [ ${HARMLESS} -eq 0 ]; then
  338.                 echownl(%Fixing problem...^);
  339.                 %eval^ ${FIX};
  340.                 echo "Done.";
  341.             else
  342.                 echo "In \"harmless\" (-n) mode, ignoring problem.";
  343.             fi;
  344.             FIXED=1;
  345.             ;;
  346.        esac;
  347. done;'
  348.  
  349. #
  350. # define the waiting routine that prints those neat dots
  351. #
  352. make_dots='
  353. if [ ${VERBOSE} -eq 1 ]; then
  354.     (touch /tmp/makedots${THISSHELL};while [ -f /tmp/makedots${THISSHELL} ]; do echownl(%.^); sleep 1; done)& 2>&1 >/dev/null;
  355. fi;'
  356.  
  357. stop_dots='sleep 1; /bin/rm -rf /tmp/makedots${THISSHELL};'
  358.  
  359. if [ 1 -eq $VERBOSE ]; then
  360.  
  361.     DISPLAYFILE="Intro";
  362.     %eval^ $display_file;
  363.  
  364. fi
  365.  
  366. if [ ${INTERACTIVE} -eq 1 ]; then
  367.     echownl(%Press RETURN/NEWLINE to begin> ^); read input;
  368. fi;
  369.  
  370. NO_WRITE="rhosts profile login logout cshrc bashrc bash_profile inputrc";
  371. NO_WRITE="$NO_WRITE screenrc kshrc tcshrc netrc forward dbxinit distfile";
  372. NO_WRITE="$NO_WRITE exrc emacsrc remote mh_profile xinitrc xsession Xdefaults";
  373. NO_WRITE="$NO_WRITE Xresources rninit mwmrc twmrc emacs rhosts";
  374. NO_READ="badpass netrc"
  375.  
  376. #
  377. # First, are any of the dot files writable & does the user own every dot file?
  378. #
  379. PERMLINE="FindPermWrite()";
  380.  
  381. if [ ${VERBOSE} -eq 1 ]; then
  382.     echo ""
  383.     echo "Step one (three total) - Evaluating your account's dot files."
  384. fi
  385.  
  386. %eval^ $make_dots;
  387. for i in ${NO_WRITE}
  388. do
  389.     TARGET=${HOME}/.$i;
  390.     if [ -f ${TARGET} -o -d ${TARGET} ]; then
  391.         while [ -f ${HOME}/dangerous.${i}.${UNIQUE} ];
  392.         do
  393.             UNIQUE=`echo "${UNIQUE} + 1" | bc -l`;
  394.         done;
  395.         FIX="/bin/mv -i ${TARGET} ${HOME}/dangerous.${i}.${UNIQUE}";
  396.         MANPAGES="chmod"
  397.         EFFECT="effect.owners"
  398.         INFO="owners"
  399.         RESULT=`/bin/ls -ld ${TARGET}`;
  400.         %eval^ $clear_args;
  401.         set $*=${RESULT};
  402.         if [ $3 != ${ME} ]; then
  403.             PROBLEM="File '${TARGET}' is owned by user $3.";
  404.             PROBLEMFILE=${TARGET};
  405.             EXITCOND=1;
  406.             %eval^ $stop_dots;
  407.             %eval^ $prompt;
  408.             %eval^ $make_dots;
  409.             continue;
  410.         fi
  411.         TEMP="`find ${TARGET} ! -type l \( ${PERMLINE} \) -print`"
  412.         EFFECT="dotwrite";
  413.         INFO="effect.dotwrit";
  414.         FIX="/bin/chmod ChmodPermSymbol()-w ${TARGET};"
  415.         if [ -n "${TEMP}" ]; then
  416.             PROBLEM="File '${TARGET}' is world or group writable.";
  417.             PROBLEMFILE=${TARGET};
  418.             EXITCOND=1;
  419.             %eval^ $stop_dots;
  420.             %eval^ $prompt;
  421.             %eval^ $make_dots;
  422.         fi
  423.     fi
  424. done
  425.  
  426. PERMLINE="FindPermRead()";
  427. EFFECT="effect.read";
  428. INFO="readable";
  429.  
  430. for i in ${NO_READ}
  431. do
  432.     TARGET=${HOME}/.${i};
  433.     if [ -f ${TARGET} ]; then
  434.         FIX="/bin/chmod ChmodPermSymbol()-r ${TARGET};"
  435.         if [ -n "`find ${TARGET} \( ${PERMLINE} \) -exec /bin/ls {} \;`" ]; then
  436.             PROBLEM="File '${TARGET}' is world or group readable.";
  437.             PROBLEMFILE=${TARGET};
  438.             EXITCOND=1;
  439.             %eval^ $stop_dots;
  440.             %eval^ $prompt;
  441.             %eval^ $make_dots;
  442.         fi
  443.     fi
  444. done
  445. %eval^ $stop_dots;
  446.  
  447. if [ ${VERBOSE} -eq 1 ]; then
  448.     echo "Step one complete."
  449.     echo ""
  450.     echo "Step two (three total) - Evaluating the file permissions in your account."
  451. fi
  452.  
  453. #
  454. # Second, do we have any writable files or directories?
  455. #
  456. %eval^ $make_dots
  457. PERMLINE="FindPermWrite()";
  458. RESULT=`(cd ${HOME}; find . -user ${ME} ! -type l \( ${PERMLINE} \) -print)`;
  459. EFFECT="effect.write";
  460. INFO="write";
  461. %eval^ $stop_dots
  462.  
  463. for i in ${RESULT}
  464. do
  465.     FIX="/bin/chmod ChmodPermSymbol()-w ${i};"
  466.     if [ -d $i ]; then
  467.         PROBLEM="Your directory $i is world or group writable.";
  468.         PROBLEMFILE=$i;
  469.         EXITCOND=1;
  470.         %eval^ $prompt;
  471.     else
  472.         PROBLEM="Your file $i is world or group writable.";
  473.         PROBLEMFILE=$i;
  474.         EXITCOND=1;
  475.         %eval^ $prompt;
  476.     fi
  477. done
  478.  
  479. %eval^ $make_dots
  480. PERMLINE="FindPermSuid()";
  481. RESULT=`(cd ${HOME} ; find . -user ${ME} ! \( -type l -o -type d \) \( ${PERMLINE} \) -print)`;
  482. EFFECT="effect.setuid";
  483. INFO="setuid";
  484.  
  485. for i in ${RESULT}
  486. do
  487.     FIX="/bin/chmod ChmodPermSuidSymbol()-s ${i};"
  488.     PROBLEM="Your file $i is user or group setuid.";
  489.     PROBLEMFILE=$i;
  490.     EXITCOND=1;
  491.     %eval^ $stop_dots
  492.     %eval^ $prompt;
  493.     %eval^ $make_dots
  494. done
  495.  
  496. sleep 1
  497. %eval^ $stop_dots
  498.  
  499. if [ ${VERBOSE} -eq 1 ]; then
  500.     echo "Step two complete."
  501.     echo ""
  502.     echo "Step three (three total) - Checking the contents of your rhosts file."
  503. fi
  504.  
  505. FIX="/bin/mv -i ${HOME}/.rhosts ${HOME}/rhosts.$$;"
  506. EFFECT="effect.rhosts";
  507. INFO="rhosts";
  508. MANPAGES="hosts.equiv rlogin";
  509. #
  510. # Third, does our rhost file contain any glaring dangers?
  511. # see "man hosts.equiv"
  512. #
  513. if [ ${RHOSTS} -eq 0 ]; then
  514.  
  515.     echo "The file ${HOME}/.rhosts will not be checked (as requested).";
  516.  
  517. elif [ -f ${HOME}/.rhosts ]; then
  518.     if [ ! -x ${PERL} ]; then
  519.         echo "${PERL} does not exist on your system -- skipping .rhosts check.";
  520.         echo "If you are unfamiliar with the uses of a .rhosts file, you should";
  521.         echo "definately have a ${GURU} take a look at it.";
  522.     else
  523.         ${PERL1} ${HOME}/.rhosts;
  524.         if [ $? -ne 0 ]; then
  525.             PROBLEM="Your .rhosts file is unsafe.";
  526.             PROBLEMFILE=${HOME}/.rhosts;
  527.             EXITCOND=1;
  528.             %eval^ $prompt;
  529.         else
  530.             if [ ${VERBOSE} -eq 1 ]; then
  531.                 echo "Your .rhosts file doesn't appear to be a security hole.";
  532.             fi;
  533.         fi;
  534.     fi;
  535. else
  536.     if [ ${VERBOSE} -eq 1 ]; then
  537.         echo "Congratulations!  You don't have a .rhosts file!";
  538.         echo "(If I had a cookie, I would give you one.)";
  539.     fi;
  540. fi;
  541.  
  542. %eval^ $stop_dots
  543.  
  544. if [ ${VERBOSE} -eq 1 ]; then
  545.     echo "Step 3 complete."
  546.     echo "";
  547.     echo "Checkacct is complete.  If you still have questions about this program,";
  548.     echo "please see a ${GURU}." ;
  549.     echo "";
  550.     if [ ${INTERACTIVE} -eq 1 ]; then
  551.         echo "If you are interested in reading an article on Unix";
  552.         echo "security, type \"yes\" and hit RETURN/NEWLINE now.";
  553.         echownl(%If not, simply hit RETURN/NEWLINE and checkacct will exit.> ^);
  554.         read input;
  555.         if [ \( ! -z "$input" \) -a \( "$input" = "yes" \) ]; then
  556.             DISPLAYFILE=${ARTICLE};
  557.             %eval^ $display_file;
  558.         fi;
  559.     fi;
  560. fi;
  561. if [ \( ${EXITCOND} -eq 0 \) -a \( ${VERBOSE} -eq 1 \) ]; then
  562.     echo "There were no obvious problems with your Unix account.";
  563.     echo "(I owe you a cookie.)";
  564. fi;
  565. exit ${EXITCOND};
  566.