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 >
Wrap
Text File
|
1992-03-10
|
14KB
|
568 lines
#!/bin/sh
#
# paths to some important programs
#
#
# This is the language used to parse the .rhosts file. If you rewrite the
# parser in a different language, you should change this. If it doesn't
# exist, that's "ok". chkacct will notice that.
#
PERL=perlpath()
#
# This is the program used to parse the .rhosts file. If you rewrite it, you
# should change PERL1 to be the location of your new program. You should also
# send me a copy because I'm a packrat for stuff like this.
#
PERL1=installpath()lib/chkacct/rhosts.pl
#
# This directory contains the info and effect files that chkacct(1L) references.
#
DOCPATH=installpath()lib/chkacct
# default variable values prevent nasty surprises
# (its good style, too)
#
# The title of the guru to send customers to (maybe your name if you work at a
# small company..)
GURU=gurudude()
#
# The name of the security article
#
ARTICLE=Article
#
# The name of the pager you want to use to display info files. This is
# probably "more" or "less" at most sites, but never cat, because things
# scroll off the screen too quickly.
#
PAGER=pagerpath()
#
# miscellaneous stuff
#
CAT=catpath()
THISSHELL=$$
EXITCOND=0
UNIQUE=1
trap 'echo "Exiting."; %eval^ $stop_dots; exit;' 0;
trap 'echo "Exiting."; %eval^ $stop_dots; exit;' 1;
trap 'echo "Exiting."; %eval^ $stop_dots; exit;' 2;
trap 'echo "Exiting."; %eval^ $stop_dots; exit;' 3;
# an example shell command line parser that conforms to the getopt (ksb)
# standard, Kevin Braunsdorf, ksb@cc.purdue.edu
# our program name and usage message
progname=`basename $0`
usage="$progname: usage [-ehinqrv] [-f <startdir>] [-m <homedir>] [-s <username]"
# how to slide a single letter option off the beginning of a bundle
# -barf -> -arf
slide='P=$1; %shift^; set _ -`expr "$P" : '\''-.\(.*\)'\''` ${1+"$@"}; %shift^'
param='if [ $# -lt 2 ]; then echo "$progname: missing value for $1" 1>&2 ; exit 1; fi'
# default values for all the flags, or leave unset for a ${flag-value) form
# verbose by default
VERBOSE=1
# interactive by default
INTERACTIVE=1
# cavalier by default
HARMLESS=0
# check .rhosts file by default
RHOSTS=1
# read an environment variable as well as the command line options:
# protect this script from leading -x's with a bogus underbar, then remove it
set _ $ZZZ ${1+"$@"}
%shift^
# get the options from the command line (+ any variables)
while [ $# -gt 0 ]
do
case "$1" in
-e)
INTERACTIVE=0
%shift^
;;
-e*)
INTERACTIVE=0
%eval^ "$slide"
;;
-f)
%eval^ "$param"
START_DIR=$2
%shift^ ; %shift^
;;
-f*)
START_DIR=`expr "$1" : '-.\(.*\)'`
%shift^
;;
-i)
INTERACTIVE=1
%shift^
;;
-i*)
INTERACTIVE=1
%eval^ "$slide"
;;
-m)
%eval^ "$param"
HOME=$2
%shift^ ; %shift^
;;
-m*)
HOME=`expr "$1" : '-.\(.*\)'`
%shift^
;;
-n)
HARMLESS=1
%shift^
;;
-n*)
HARMLESS=1
%eval^ "$slide"
;;
-q)
VERBOSE=0
%shift^
;;
-q*)
VERBOSE=0
%eval^ "$slide"
;;
-r)
RHOSTS=0
%shift^
;;
-r*)
RHOSTS=0
%eval^ "$slide"
;;
-s)
%eval^ "$param"
ME=$2
HOME=`echo "echo ~${ME}" | cshpath() `;
%shift^ ; %shift^
;;
-s*)
ME=`expr "$1" : '-.\(.*\)'`
HOME=`echo "echo ~${ME}" | cshpath() `;
%shift^
;;
-v)
VERBOSE=1
%shift^
;;
-v*)
VERBOSE=1
%eval^ "$slide"
;;
--)
%shift^
break
;;
-h|-h*)
cat <<HERE
$usage
e expert (non-interactive) do not ask the user any questions
f <startdir> specify the directory in which to begin the general file check
(\${HOME} is the default)
h print this help message
i interactive mode - ask the user about every file (default)
m <home dir> specify a home directory (\${HOME} is the default)
n do not actually alter any file permissions or files
q perform actions quietly
r do not check of \${HOME}/.rhosts file
s <username> run chkacct as if my userid were <username> (also sets \${HOME} to ~username)
v perform actions verbosely (this is the default)
HERE
exit 0
;;
-*)
echo "$usage" 1>&2
exit 1
;;
*)
# process and continue for intermixed options & args
break
;;
esac
done
# set my identity if it hasn't been done yet
if [ -z "${ME}" ]; then
ME=`whoami`;
if [ \( -z "${ME}" \) -o \( $? -ne 0 \) ]; then
echo "Cannot determine your identity - exiting, nothing checked.";
EXITCOND=1;
exit ${EXITCOND};
fi;
fi;
# set my home directory if it hasn't been set yet
if [ -z "${HOME}" ]; then
HOME=`echo "echo ~${ME}" | cshpath() `;
if [ -z "${HOME}" ]; then
echo "Cannot determine your home directory - exiting, nothing checked.";
EXITCOND=1;
exit ${EXITCOND};
fi;
fi;
# search only in the home dir by default
if [ -z "${START_DIR}" ]; then
START_DIR=${HOME};
fi
#
# For debugging, silly.
#
# echo "Performing account check with username = ${ME}, home dir = ${HOME}, and";
# echo "starting directory ${START_DIR}";
#
# Ok, this is actually checkacct.
#
#
# Define a routine which will display files. If sites have their own favorite
# pager or display method, it can be specified here. If you just wanted
# to use a simple pager, you would define PAGER to be equal to it, and then
# you would change the line below that display it to be:
# ${PAGER} ${DOCPATH}/${DISPLAY};
#
# REMEMBER! Before you call this routine, you must set DISPLAYFILE to be
# the file you want displayed
#
display_file='
if [ -f ${DOCPATH}/${DISPLAYFILE} ]; then
${PAGER} ${DOCPATH}/${DISPLAYFILE};
fi;'
#
# Its crucial that we don't leave shell variables like $* set
# when we're not expecting it. For that reason, here's a small routine
# to clear the contents of $* by shift'ing. For some reason, each set
# successively lengthens $*.
#
clear_args='
for i
do
%shift^;
done;'
#
# Before each situation where the user might be queried as to the action,
# one needs to remember to set the following shell variables:
#
# FIX - the shell command to fix it with \$TARGET to be the file to
# be operated upon
# MANPAGES - a list of man pages it will tell you to look at
# INFO - The name of the info file in which more info is to be found (if any)
# EFFECT - The name of the file which describes the effect of the fix
# PROBLEM - This is the problem string -- it may be printed several times.
#
# define the prompt/decision routine which will make the fix if necessary, print
# out specific info, refer someone to a manual page.
prompt='
FIXED=0;
while [ ${FIXED} -eq 0 ]; do
echo "";
echo "${PROBLEM}";
echo "The output of the command \"ls -lsopt()ld ${PROBLEMFILE}\" is:";
/bin/ls -lsopt()ld ${PROBLEMFILE};
echo "";
echo "The suggested fix for this is to execute the command:";
echo " ${FIX}";
if [ ${VERBOSE} -eq 1 ]; then
if [ \( -f ${DOCPATH}/${EFFECT} \) -a \( ! -d ${DOCPATH}/${EFFECT} \) ]; then
${CAT} ${DOCPATH}/${EFFECT};
fi;
fi;
if [ ${INTERACTIVE} -eq 1 ]; then
echo "";
echo "Press a letter (a) to enter automatic mode (no more questions), (f)ix problem,";
echo "(h)elp me out with this menu, (i)gnore problem, (m)ore info";
echownl(%Press RETURN/NEWLINE to fix the problem and go on> ^);
read input;
else
input="f";
fi;
case $input in
a*)
echo "";
echo "This will put you into automatic mode. No more questions will be asked,";
echo "and all problems will be automatically fixed unless you specified the";
echo "\"harmless(-n)\" option on startup.";
echo "";
echownl(%Press \"yes\" to enter automatic mode> ^);
read confirm;
if [ \( ! -z "$confirm" \) -a \( "$confirm" = "yes" \) ]; then
echo "Beginning automatic mode.";
INTERACTIVE=0;
echo "";
fi;
;;
h*)
DISPLAYFILE="prompt.help";
%eval^ $display_file;
;;
m*)
DISPLAYFILE=${INFO};
%eval^ $display_file;
if [ -n "$MANPAGES" -a ${VERBOSE} -eq 1 ]; then
echo "";
echo "For additional information, read the manual page for the following";
echo "program(s): ${MANPAGES}";
echo "The command man <name of program> will show you the manual page.";
echo "";
fi;
;;
i*)
echo "Ignoring problem -- taking no action.";
FIXED=1;
;;
*|f*)
if [ ${HARMLESS} -eq 0 ]; then
echownl(%Fixing problem...^);
%eval^ ${FIX};
echo "Done.";
else
echo "In \"harmless\" (-n) mode, ignoring problem.";
fi;
FIXED=1;
;;
esac;
done;'
#
# define the waiting routine that prints those neat dots
#
make_dots='
if [ ${VERBOSE} -eq 1 ]; then
(touch /tmp/makedots${THISSHELL};while [ -f /tmp/makedots${THISSHELL} ]; do echownl(%.^); sleep 1; done)& 2>&1 >/dev/null;
fi;'
stop_dots='sleep 1; /bin/rm -rf /tmp/makedots${THISSHELL};'
if [ 1 -eq $VERBOSE ]; then
DISPLAYFILE="Intro";
%eval^ $display_file;
fi
if [ ${INTERACTIVE} -eq 1 ]; then
echownl(%Press RETURN/NEWLINE to begin> ^); read input;
fi;
NO_WRITE="rhosts profile login logout cshrc bashrc bash_profile inputrc";
NO_WRITE="$NO_WRITE screenrc kshrc tcshrc netrc forward dbxinit distfile";
NO_WRITE="$NO_WRITE exrc emacsrc remote mh_profile xinitrc xsession Xdefaults";
NO_WRITE="$NO_WRITE Xresources rninit mwmrc twmrc emacs rhosts";
NO_READ="badpass netrc"
#
# First, are any of the dot files writable & does the user own every dot file?
#
PERMLINE="FindPermWrite()";
if [ ${VERBOSE} -eq 1 ]; then
echo ""
echo "Step one (three total) - Evaluating your account's dot files."
fi
%eval^ $make_dots;
for i in ${NO_WRITE}
do
TARGET=${HOME}/.$i;
if [ -f ${TARGET} -o -d ${TARGET} ]; then
while [ -f ${HOME}/dangerous.${i}.${UNIQUE} ];
do
UNIQUE=`echo "${UNIQUE} + 1" | bc -l`;
done;
FIX="/bin/mv -i ${TARGET} ${HOME}/dangerous.${i}.${UNIQUE}";
MANPAGES="chmod"
EFFECT="effect.owners"
INFO="owners"
RESULT=`/bin/ls -ld ${TARGET}`;
%eval^ $clear_args;
set $*=${RESULT};
if [ $3 != ${ME} ]; then
PROBLEM="File '${TARGET}' is owned by user $3.";
PROBLEMFILE=${TARGET};
EXITCOND=1;
%eval^ $stop_dots;
%eval^ $prompt;
%eval^ $make_dots;
continue;
fi
TEMP="`find ${TARGET} ! -type l \( ${PERMLINE} \) -print`"
EFFECT="dotwrite";
INFO="effect.dotwrit";
FIX="/bin/chmod ChmodPermSymbol()-w ${TARGET};"
if [ -n "${TEMP}" ]; then
PROBLEM="File '${TARGET}' is world or group writable.";
PROBLEMFILE=${TARGET};
EXITCOND=1;
%eval^ $stop_dots;
%eval^ $prompt;
%eval^ $make_dots;
fi
fi
done
PERMLINE="FindPermRead()";
EFFECT="effect.read";
INFO="readable";
for i in ${NO_READ}
do
TARGET=${HOME}/.${i};
if [ -f ${TARGET} ]; then
FIX="/bin/chmod ChmodPermSymbol()-r ${TARGET};"
if [ -n "`find ${TARGET} \( ${PERMLINE} \) -exec /bin/ls {} \;`" ]; then
PROBLEM="File '${TARGET}' is world or group readable.";
PROBLEMFILE=${TARGET};
EXITCOND=1;
%eval^ $stop_dots;
%eval^ $prompt;
%eval^ $make_dots;
fi
fi
done
%eval^ $stop_dots;
if [ ${VERBOSE} -eq 1 ]; then
echo "Step one complete."
echo ""
echo "Step two (three total) - Evaluating the file permissions in your account."
fi
#
# Second, do we have any writable files or directories?
#
%eval^ $make_dots
PERMLINE="FindPermWrite()";
RESULT=`(cd ${HOME}; find . -user ${ME} ! -type l \( ${PERMLINE} \) -print)`;
EFFECT="effect.write";
INFO="write";
%eval^ $stop_dots
for i in ${RESULT}
do
FIX="/bin/chmod ChmodPermSymbol()-w ${i};"
if [ -d $i ]; then
PROBLEM="Your directory $i is world or group writable.";
PROBLEMFILE=$i;
EXITCOND=1;
%eval^ $prompt;
else
PROBLEM="Your file $i is world or group writable.";
PROBLEMFILE=$i;
EXITCOND=1;
%eval^ $prompt;
fi
done
%eval^ $make_dots
PERMLINE="FindPermSuid()";
RESULT=`(cd ${HOME} ; find . -user ${ME} ! \( -type l -o -type d \) \( ${PERMLINE} \) -print)`;
EFFECT="effect.setuid";
INFO="setuid";
for i in ${RESULT}
do
FIX="/bin/chmod ChmodPermSuidSymbol()-s ${i};"
PROBLEM="Your file $i is user or group setuid.";
PROBLEMFILE=$i;
EXITCOND=1;
%eval^ $stop_dots
%eval^ $prompt;
%eval^ $make_dots
done
sleep 1
%eval^ $stop_dots
if [ ${VERBOSE} -eq 1 ]; then
echo "Step two complete."
echo ""
echo "Step three (three total) - Checking the contents of your rhosts file."
fi
FIX="/bin/mv -i ${HOME}/.rhosts ${HOME}/rhosts.$$;"
EFFECT="effect.rhosts";
INFO="rhosts";
MANPAGES="hosts.equiv rlogin";
#
# Third, does our rhost file contain any glaring dangers?
# see "man hosts.equiv"
#
if [ ${RHOSTS} -eq 0 ]; then
echo "The file ${HOME}/.rhosts will not be checked (as requested).";
elif [ -f ${HOME}/.rhosts ]; then
if [ ! -x ${PERL} ]; then
echo "${PERL} does not exist on your system -- skipping .rhosts check.";
echo "If you are unfamiliar with the uses of a .rhosts file, you should";
echo "definately have a ${GURU} take a look at it.";
else
${PERL1} ${HOME}/.rhosts;
if [ $? -ne 0 ]; then
PROBLEM="Your .rhosts file is unsafe.";
PROBLEMFILE=${HOME}/.rhosts;
EXITCOND=1;
%eval^ $prompt;
else
if [ ${VERBOSE} -eq 1 ]; then
echo "Your .rhosts file doesn't appear to be a security hole.";
fi;
fi;
fi;
else
if [ ${VERBOSE} -eq 1 ]; then
echo "Congratulations! You don't have a .rhosts file!";
echo "(If I had a cookie, I would give you one.)";
fi;
fi;
%eval^ $stop_dots
if [ ${VERBOSE} -eq 1 ]; then
echo "Step 3 complete."
echo "";
echo "Checkacct is complete. If you still have questions about this program,";
echo "please see a ${GURU}." ;
echo "";
if [ ${INTERACTIVE} -eq 1 ]; then
echo "If you are interested in reading an article on Unix";
echo "security, type \"yes\" and hit RETURN/NEWLINE now.";
echownl(%If not, simply hit RETURN/NEWLINE and checkacct will exit.> ^);
read input;
if [ \( ! -z "$input" \) -a \( "$input" = "yes" \) ]; then
DISPLAYFILE=${ARTICLE};
%eval^ $display_file;
fi;
fi;
fi;
if [ \( ${EXITCOND} -eq 0 \) -a \( ${VERBOSE} -eq 1 \) ]; then
echo "There were no obvious problems with your Unix account.";
echo "(I owe you a cookie.)";
fi;
exit ${EXITCOND};