[BACK]Return to security CVS log [TXT][DIR] Up to [local] / src / etc

Annotation of src/etc/security, Revision 1.2

1.1       deraadt     1: #!/bin/sh -
                      2: #
                      3: #      from: @(#)security      8.1 (Berkeley) 6/9/93
1.2     ! deraadt     4: #      $Id: security,v 1.1.1.1 1995/10/18 08:37:57 deraadt Exp $
1.1       deraadt     5: #
                      6:
                      7: PATH=/sbin:/usr/sbin:/bin:/usr/bin
                      8:
                      9: umask 077
                     10:
                     11: ERR=/tmp/_secure1.$$
                     12: TMP1=/tmp/_secure2.$$
                     13: TMP2=/tmp/_secure3.$$
                     14: TMP3=/tmp/_secure4.$$
                     15: LIST=/tmp/_secure5.$$
                     16: OUTPUT=/tmp/_secure6.$$
                     17:
                     18: trap 'rm -f $ERR $TMP1 $TMP2 $TMP3 $LIST $OUTPUT' 0
                     19:
                     20: # Check the master password file syntax.
                     21: MP=/etc/master.passwd
                     22: awk -F: '{
                     23:        if ($0 ~ /^[     ]*$/) {
                     24:                printf("Line %d is a blank line.\n", NR);
                     25:                next;
                     26:        }
                     27:        if (NF != 10)
                     28:                printf("Line %d has the wrong number of fields.\n", NR);
1.2     ! deraadt    29:        if ($1 ~ /^[+-].*$/)
        !            30:                next;
        !            31:        if ($1 == "")
        !            32:                printf("Line %d has an empty login field.\n",NR);
        !            33:        else if ($1 !~ /^[A-Za-z0-9][A-Za-z0-9_-]*$/)
1.1       deraadt    34:                printf("Login %s has non-alphanumeric characters.\n", $1);
                     35:        if (length($1) > 8)
                     36:                printf("Login %s has more than 8 characters.\n", $1);
                     37:        if ($2 == "")
                     38:                printf("Login %s has no password.\n", $1);
                     39:        if (length($2) != 13 && ($10 ~ /.*sh$/ || $10 == ""))
                     40:                printf("Login %s is off but still has a valid shell.\n", $1);
                     41:        if ($3 == 0 && $1 != "root" && $1 != "toor")
                     42:                printf("Login %s has a user id of 0.\n", $1);
                     43:        if ($3 < 0)
                     44:                printf("Login %s has a negative user id.\n", $1);
                     45:        if ($4 < 0)
                     46:                printf("Login %s has a negative group id.\n", $1);
                     47: }' < $MP > $OUTPUT
                     48: if [ -s $OUTPUT ] ; then
                     49:        printf "\nChecking the $MP file:\n"
                     50:        cat $OUTPUT
                     51: fi
                     52:
                     53: awk -F: '{ print $1 }' $MP | sort | uniq -d > $OUTPUT
                     54: if [ -s $OUTPUT ] ; then
                     55:        printf "\n$MP has duplicate user names.\n"
                     56:        column $OUTPUT
                     57: fi
                     58:
1.2     ! deraadt    59: awk -F: '$1 != "toor" { print $1 " " $3 }' $MP | sort -n +1 | tee $TMP1 |
1.1       deraadt    60: uniq -d -f 1 | awk '{ print $2 }' > $TMP2
                     61: if [ -s $TMP2 ] ; then
                     62:        printf "\n$MP has duplicate user id's.\n"
                     63:         while read uid; do
                     64:                 grep -w $uid $TMP1
                     65:         done < $TMP2 | column
                     66: fi
                     67:
                     68: # Backup the master password file; a special case, the normal backup
                     69: # mechanisms also print out file differences and we don't want to do
                     70: # that because this file has encrypted passwords in it.
1.2     ! deraadt    71: if [ ! -d /var/backups ] ; then
        !            72:        mkdir /var/backups
        !            73:        chmod 755 /var/backups
        !            74: fi
1.1       deraadt    75: CUR=/var/backups/`basename $MP`.current
                     76: BACK=/var/backups/`basename $MP`.backup
                     77: if [ -s $CUR ] ; then
                     78:        if cmp -s $CUR $MP; then
                     79:                :
                     80:        else
                     81:                cp -p $CUR $BACK
                     82:                cp -p $MP $CUR
                     83:                chown root.wheel $CUR
                     84:        fi
                     85: else
                     86:        cp -p $MP $CUR
                     87:        chown root.wheel $CUR
                     88: fi
                     89:
                     90: # Check the group file syntax.
                     91: GRP=/etc/group
                     92: awk -F: '{
                     93:        if ($0 ~ /^[     ]*$/) {
                     94:                printf("Line %d is a blank line.\n", NR);
                     95:                next;
                     96:        }
1.2     ! deraadt    97:        if ($1 ~ /^[+-].*$/)
        !            98:                next;
1.1       deraadt    99:        if (NF != 4)
                    100:                printf("Line %d has the wrong number of fields.\n", NR);
                    101:        if ($1 !~ /^[A-za-z0-9]*$/)
                    102:                printf("Group %s has non-alphanumeric characters.\n", $1);
                    103:        if (length($1) > 8)
                    104:                printf("Group %s has more than 8 characters.\n", $1);
                    105:        if ($3 !~ /[0-9]*/)
                    106:                printf("Login %s has a negative group id.\n", $1);
                    107: }' < $GRP > $OUTPUT
                    108: if [ -s $OUTPUT ] ; then
                    109:        printf "\nChecking the $GRP file:\n"
                    110:        cat $OUTPUT
                    111: fi
                    112:
                    113: awk -F: '{ print $1 }' $GRP | sort | uniq -d > $OUTPUT
                    114: if [ -s $OUTPUT ] ; then
                    115:        printf "\n$GRP has duplicate group names.\n"
                    116:        column $OUTPUT
                    117: fi
                    118:
                    119: # Check for root paths, umask values in startup files.
                    120: # The check for the root paths is problematical -- it's likely to fail
                    121: # in other environments.  Once the shells have been modified to warn
                    122: # of '.' in the path, the path tests should go away.
                    123: > $OUTPUT
                    124: rhome=/root
                    125: umaskset=no
                    126: list="/etc/csh.cshrc /etc/csh.login ${rhome}/.cshrc ${rhome}/.login"
                    127: for i in $list ; do
                    128:        if [ -f $i ] ; then
                    129:                if egrep umask $i > /dev/null ; then
                    130:                        umaskset=yes
                    131:                fi
                    132:                egrep umask $i |
                    133:                awk '$2 % 100 < 20 \
                    134:                        { print "Root umask is group writeable" }
                    135:                     $2 % 10 < 2 \
                    136:                        { print "Root umask is other writeable" }' >> $OUTPUT
                    137:                /bin/csh -f -s << end-of-csh > /dev/null 2>&1
                    138:                        unset path
                    139:                        source $i
                    140:                        /bin/ls -ldgT \$path > $TMP1
                    141: end-of-csh
                    142:                awk '{
                    143:                        if ($10 ~ /^\.$/) {
                    144:                                print "The root path includes .";
                    145:                                next;
                    146:                        }
                    147:                     }
                    148:                     $1 ~ /^d....w/ \
                    149:         { print "Root path directory " $10 " is group writeable." } \
                    150:                     $1 ~ /^d.......w/ \
                    151:         { print "Root path directory " $10 " is other writeable." }' \
                    152:                < $TMP1 >> $OUTPUT
                    153:        fi
                    154: done
                    155: if [ $umaskset = "no" -o -s $OUTPUT ] ; then
                    156:        printf "\nChecking root csh paths, umask values:\n$list\n"
                    157:        if [ -s $OUTPUT ]; then
                    158:                cat $OUTPUT
                    159:        fi
                    160:        if [ $umaskset = "no" ] ; then
                    161:                printf "\nRoot csh startup files do not set the umask.\n"
                    162:        fi
                    163: fi
                    164:
                    165: > $OUTPUT
                    166: rhome=/root
                    167: umaskset=no
                    168: list="${rhome}/.profile"
                    169: for i in $list; do
                    170:        if [ -f $i ] ; then
                    171:                if egrep umask $i > /dev/null ; then
                    172:                        umaskset=yes
                    173:                fi
                    174:                egrep umask $i |
                    175:                awk '$2 % 100 < 20 \
                    176:                        { print "Root umask is group writeable" } \
                    177:                     $2 % 10 < 2 \
                    178:                        { print "Root umask is other writeable" }' >> $OUTPUT
                    179:                /bin/sh << end-of-sh > /dev/null 2>&1
                    180:                        PATH=
                    181:                        . $i
                    182:                        list=\`echo \$PATH | /usr/bin/sed -e 's/:/ /g'\`
                    183:                        /bin/ls -ldgT \$list > $TMP1
                    184: end-of-sh
                    185:                awk '{
                    186:                        if ($10 ~ /^\.$/) {
                    187:                                print "The root path includes .";
                    188:                                next;
                    189:                        }
                    190:                     }
                    191:                     $1 ~ /^d....w/ \
                    192:         { print "Root path directory " $10 " is group writeable." } \
                    193:                     $1 ~ /^d.......w/ \
                    194:         { print "Root path directory " $10 " is other writeable." }' \
                    195:                < $TMP1 >> $OUTPUT
                    196:
                    197:        fi
                    198: done
                    199: if [ $umaskset = "no" -o -s $OUTPUT ] ; then
                    200:        printf "\nChecking root sh paths, umask values:\n$list\n"
                    201:        if [ -s $OUTPUT ]; then
                    202:                cat $OUTPUT
                    203:        fi
                    204:        if [ $umaskset = "no" ] ; then
                    205:                printf "\nRoot sh startup files do not set the umask.\n"
                    206:        fi
                    207: fi
                    208:
                    209: # Root and uucp should both be in /etc/ftpusers.
                    210: if egrep root /etc/ftpusers > /dev/null ; then
                    211:        :
                    212: else
                    213:        printf "\nRoot not listed in /etc/ftpusers file.\n"
                    214: fi
                    215: if egrep uucp /etc/ftpusers > /dev/null ; then
                    216:        :
                    217: else
                    218:        printf "\nUucp not listed in /etc/ftpusers file.\n"
                    219: fi
                    220:
                    221: # Uudecode should not be in the /etc/aliases file.
                    222: if egrep 'uudecode|decode' /etc/aliases; then
                    223:        printf "\nThere is an entry for uudecode in the /etc/aliases file.\n"
                    224: fi
                    225:
                    226: # Files that should not have + signs.
1.2     ! deraadt   227: list="/etc/hosts.equiv /etc/shosts.equiv /etc/hosts.lpd"
1.1       deraadt   228: for f in $list ; do
1.2     ! deraadt   229:        if [ -f $f ] ; then
        !           230:                awk '{
        !           231:                        if ($0 ~ /^+@.*$/ )
        !           232:                                next;
        !           233:                        if ($0 ~ /^+.*$/ )
        !           234:                                printf("\nPlus sign in %s file.\n", FILENAME);
        !           235:                }' $f
1.1       deraadt   236:        fi
                    237: done
                    238:
1.2     ! deraadt   239: # Check for special users with .rhosts/.shosts files.  Only root and
        !           240: # toor should have .rhosts/.shosts files.  Also, .rhosts/.shosts files
        !           241: # should not have plus signs.
        !           242: awk -F: '$1 != "root" && $1 != "toor" && $1 !~ /^[+-].*$/ && \
1.1       deraadt   243:        ($3 < 100 || $1 == "ftp" || $1 == "uucp") \
                    244:                { print $1 " " $6 }' /etc/passwd |
                    245: while read uid homedir; do
1.2     ! deraadt   246:        for j in .rhosts .shosts; do
        !           247:                if [ -f ${homedir}/$j ] ; then
        !           248:                        rhost=`ls -ldgT ${homedir}/$j`
        !           249:                        printf "$uid: $rhost\n"
        !           250:                fi
        !           251:        done
1.1       deraadt   252: done > $OUTPUT
                    253: if [ -s $OUTPUT ] ; then
1.2     ! deraadt   254:        printf "\nChecking for special users with .rhosts/.shosts files.\n"
1.1       deraadt   255:        cat $OUTPUT
                    256: fi
                    257:
                    258: awk -F: '{ print $1 " " $6 }' /etc/passwd | \
                    259: while read uid homedir; do
1.2     ! deraadt   260:        for j in .rhosts .shosts; do
        !           261:                if [ -f ${homedir}/$j ] ; then
        !           262:                        awk '{
        !           263:                                if ($0 ~ /^+@.*$/ )
        !           264:                                        next;
        !           265:                                if ($0 ~ /^+.*$/ )
        !           266:                                        printf("%s has + sign in it.\n",
        !           267:                                            FILENAME);
        !           268:                        }' ${homedir}/$j
        !           269:                fi
        !           270:        done
1.1       deraadt   271: done > $OUTPUT
                    272: if [ -s $OUTPUT ] ; then
1.2     ! deraadt   273:        printf "\nChecking .rhosts/.shosts files syntax.\n"
1.1       deraadt   274:        cat $OUTPUT
                    275: fi
                    276:
                    277: # Check home directories.  Directories should not be owned by someone else
                    278: # or writeable.
1.2     ! deraadt   279: awk -F: '{ if ( $1 !~ /^[+-].*$/ ) print $1 " " $6 }' /etc/passwd | \
1.1       deraadt   280: while read uid homedir; do
                    281:        if [ -d ${homedir}/ ] ; then
                    282:                file=`ls -ldgT ${homedir}`
                    283:                printf "$uid $file\n"
                    284:        fi
                    285: done |
                    286: awk '$1 != $4 && $4 != "root" \
                    287:        { print "user " $1 " home directory is owned by " $4 }
                    288:      $2 ~ /^-....w/ \
                    289:        { print "user " $1 " home directory is group writeable" }
                    290:      $2 ~ /^-.......w/ \
                    291:        { print "user " $1 " home directory is other writeable" }' > $OUTPUT
                    292: if [ -s $OUTPUT ] ; then
                    293:        printf "\nChecking home directories.\n"
                    294:        cat $OUTPUT
                    295: fi
                    296:
                    297: # Files that should not be owned by someone else or readable.
1.2     ! deraadt   298: list=".netrc .rhosts .shosts"
1.1       deraadt   299: awk -F: '{ print $1 " " $6 }' /etc/passwd | \
                    300: while read uid homedir; do
                    301:        for f in $list ; do
                    302:                file=${homedir}/${f}
                    303:                if [ -f $file ] ; then
                    304:                        printf "$uid $f `ls -ldgT $file`\n"
                    305:                fi
                    306:        done
                    307: done |
                    308: awk '$1 != $5 && $5 != "root" \
                    309:        { print "user " $1 " " $2 " file is owned by " $5 }
                    310:      $3 ~ /^-......r/ \
                    311:        { print "user " $1 " " $2 " file is other readable" }
                    312:      $3 ~ /^-....w/ \
                    313:        { print "user " $1 " " $2 " file is group writeable" }
                    314:      $3 ~ /^-.......w/ \
                    315:        { print "user " $1 " " $2 " file is other writeable" }' > $OUTPUT
                    316:
                    317: # Files that should not be owned by someone else or writeable.
                    318: list=".bashrc .cshrc .emacs .exrc .forward .klogin .login .logout \
                    319:       .profile .tcshrc"
                    320: awk -F: '{ print $1 " " $6 }' /etc/passwd | \
                    321: while read uid homedir; do
                    322:        for f in $list ; do
                    323:                file=${homedir}/${f}
                    324:                if [ -f $file ] ; then
                    325:                        printf "$uid $f `ls -ldgT $file`\n"
                    326:                fi
                    327:        done
                    328: done |
                    329: awk '$1 != $5 && $5 != "root" \
                    330:        { print "user " $1 " " $2 " file is owned by " $5 }
                    331:      $3 ~ /^-....w/ \
                    332:        { print "user " $1 " " $2 " file is group writeable" }
                    333:      $3 ~ /^-.......w/ \
                    334:        { print "user " $1 " " $2 " file is other writeable" }' >> $OUTPUT
                    335: if [ -s $OUTPUT ] ; then
                    336:        printf "\nChecking dot files.\n"
                    337:        cat $OUTPUT
                    338: fi
                    339:
                    340: # Mailboxes should be owned by user and unreadable.
                    341: ls -l /var/mail | sed 1d | \
                    342: awk '$3 != $9 \
                    343:        { print "user " $9 " mailbox is owned by " $3 }
                    344:      $1 != "-rw-------" \
                    345:        { print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT
                    346: if [ -s $OUTPUT ] ; then
                    347:        printf "\nChecking mailbox ownership.\n"
                    348:        cat $OUTPUT
                    349: fi
                    350:
1.2     ! deraadt   351: if [ -f /etc/exports ]; then
        !           352:     # File systems should not be globally exported.
        !           353:     awk '{
1.1       deraadt   354:        readonly = 0;
                    355:        for (i = 2; i <= NF; ++i) {
                    356:                if ($i ~ /-ro/)
                    357:                        readonly = 1;
                    358:                else if ($i !~ /^-/)
                    359:                        next;
                    360:        }
                    361:        if (readonly)
                    362:                print "File system " $1 " globally exported, read-only."
                    363:        else
                    364:                print "File system " $1 " globally exported, read-write."
1.2     ! deraadt   365:     }' < /etc/exports > $OUTPUT
        !           366:     if [ -s $OUTPUT ] ; then
1.1       deraadt   367:        printf "\nChecking for globally exported file systems.\n"
                    368:        cat $OUTPUT
1.2     ! deraadt   369:     fi
1.1       deraadt   370: fi
                    371:
                    372: # Display any changes in setuid files and devices.
1.2     ! deraadt   373: pending="\nChecking setuid files and devices:\n"
1.1       deraadt   374: (find / \( ! -fstype local -o -fstype fdesc -o -fstype kernfs \
                    375:                -o -fstype procfs \) -a -prune -o \
1.2     ! deraadt   376:        -type f -a \( -perm -u+s -o -perm -g+s \) -print -o \
        !           377:        ! -type d -a ! -type f -a ! -type l -a ! -type s -print | \
1.1       deraadt   378: sort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT
                    379:
                    380: # Display any errors that occurred during system file walk.
                    381: if [ -s $OUTPUT ] ; then
1.2     ! deraadt   382:        printf "${pending}Setuid/device find errors:\n"
        !           383:        pending=
1.1       deraadt   384:        cat $OUTPUT
                    385:        printf "\n"
                    386: fi
                    387:
                    388: # Display any changes in the setuid file list.
                    389: egrep -v '^[bc]' $LIST > $TMP1
                    390: if [ -s $TMP1 ] ; then
                    391:        # Check to make sure uudecode isn't setuid.
                    392:        if grep -w uudecode $TMP1 > /dev/null ; then
1.2     ! deraadt   393:                printf "${pending}\nUudecode is setuid.\n"
        !           394:                pending=
1.1       deraadt   395:        fi
                    396:
                    397:        CUR=/var/backups/setuid.current
                    398:        BACK=/var/backups/setuid.backup
                    399:
                    400:        if [ -s $CUR ] ; then
                    401:                if cmp -s $CUR $TMP1 ; then
                    402:                        :
                    403:                else
                    404:                        > $TMP2
                    405:                        join -110 -210 -v2 $CUR $TMP1 > $OUTPUT
                    406:                        if [ -s $OUTPUT ] ; then
1.2     ! deraadt   407:                                printf "${pending}Setuid additions:\n"
        !           408:                                pending=
1.1       deraadt   409:                                tee -a $TMP2 < $OUTPUT
                    410:                                printf "\n"
                    411:                        fi
                    412:
                    413:                        join -110 -210 -v1 $CUR $TMP1 > $OUTPUT
                    414:                        if [ -s $OUTPUT ] ; then
1.2     ! deraadt   415:                                printf "${pending}Setuid deletions:\n"
        !           416:                                pending=
1.1       deraadt   417:                                tee -a $TMP2 < $OUTPUT
                    418:                                printf "\n"
                    419:                        fi
                    420:
                    421:                        sort +9 $TMP2 $CUR $TMP1 | \
                    422:                            sed -e 's/[  ][      ]*/ /g' | uniq -u > $OUTPUT
                    423:                        if [ -s $OUTPUT ] ; then
1.2     ! deraadt   424:                                printf "${pending}Setuid changes:\n"
        !           425:                                pending=
1.1       deraadt   426:                                column -t $OUTPUT
                    427:                                printf "\n"
                    428:                        fi
                    429:
                    430:                        cp $CUR $BACK
                    431:                        cp $TMP1 $CUR
                    432:                fi
                    433:        else
1.2     ! deraadt   434:                printf "${pending}Setuid additions:\n"
        !           435:                pending=
1.1       deraadt   436:                column -t $TMP1
                    437:                printf "\n"
                    438:                cp $TMP1 $CUR
                    439:        fi
                    440: fi
                    441:
                    442: # Check for block and character disk devices that are readable or writeable
                    443: # or not owned by root.operator.
                    444: >$TMP1
1.2     ! deraadt   445: DISKLIST="dk fd hd hk hp jb kra ra rb rd rl rx xd rz sd up wd vnd ccd"
1.1       deraadt   446: for i in $DISKLIST; do
                    447:        egrep "^b.*/${i}[0-9][0-9]*[a-h]$"  $LIST >> $TMP1
                    448:        egrep "^c.*/r${i}[0-9][0-9]*[a-h]$"  $LIST >> $TMP1
                    449: done
                    450:
                    451: awk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \
                    452:        { printf("Disk %s is user %s, group %s, permissions %s.\n", \
                    453:            $11, $3, $4, $1); }' < $TMP1 > $OUTPUT
                    454: if [ -s $OUTPUT ] ; then
                    455:        printf "\nChecking disk ownership and permissions.\n"
                    456:        cat $OUTPUT
                    457:        printf "\n"
                    458: fi
                    459:
                    460: # Display any changes in the device file list.
                    461: egrep '^[bc]' $LIST | sort +10 > $TMP1
                    462: if [ -s $TMP1 ] ; then
                    463:        CUR=/var/backups/device.current
                    464:        BACK=/var/backups/device.backup
                    465:
                    466:        if [ -s $CUR ] ; then
                    467:                if cmp -s $CUR $TMP1 ; then
                    468:                        :
                    469:                else
                    470:                        > $TMP2
                    471:                        join -111 -211 -v2 $CUR $TMP1 > $OUTPUT
                    472:                        if [ -s $OUTPUT ] ; then
                    473:                                printf "Device additions:\n"
                    474:                                tee -a $TMP2 < $OUTPUT
                    475:                                printf "\n"
                    476:                        fi
                    477:
                    478:                        join -111 -211 -v1 $CUR $TMP1 > $OUTPUT
                    479:                        if [ -s $OUTPUT ] ; then
                    480:                                printf "Device deletions:\n"
                    481:                                tee -a $TMP2 < $OUTPUT
                    482:                                printf "\n"
                    483:                        fi
                    484:
                    485:                        # Report any block device change.  Ignore character
                    486:                        # devices, only the name is significant.
                    487:                        cat $TMP2 $CUR $TMP1 | \
                    488:                        sed -e '/^c/d' | \
                    489:                        sort +10 | \
                    490:                        sed -e 's/[      ][      ]*/ /g' | \
                    491:                        uniq -u > $OUTPUT
                    492:                        if [ -s $OUTPUT ] ; then
                    493:                                printf "Block device changes:\n"
                    494:                                column -t $OUTPUT
                    495:                                printf "\n"
                    496:                        fi
                    497:
                    498:                        cp $CUR $BACK
                    499:                        cp $TMP1 $CUR
                    500:                fi
                    501:        else
                    502:                printf "Device additions:\n"
                    503:                column -t $TMP1
                    504:                printf "\n"
                    505:                cp $TMP1 $CUR
                    506:        fi
                    507: fi
                    508:
                    509: # Check special files.
                    510: # Check system binaries.
                    511: #
                    512: # Create the mtree tree specifications using:
                    513: #
                    514: #      mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure
1.2     ! deraadt   515: #      chown root.wheel DIR.secure
        !           516: #      chmod 600 DIR.secure
1.1       deraadt   517: #
                    518: # Note, this is not complete protection against Trojan horsed binaries, as
                    519: # the hacker can modify the tree specification to match the replaced binary.
                    520: # For details on really protecting yourself against modified binaries, see
                    521: # the mtree(8) manual page.
1.2     ! deraadt   522: if [ -d /etc/mtree ]; then
        !           523:        cd /etc/mtree
1.1       deraadt   524:        mtree -e -p / -f /etc/mtree/special > $OUTPUT
                    525:        if [ -s $OUTPUT ] ; then
                    526:                printf "\nChecking special files and directories.\n"
                    527:                cat $OUTPUT
                    528:        fi
                    529:
                    530:        > $OUTPUT
                    531:        for file in *.secure; do
1.2     ! deraadt   532:                [ $file = '*.secure' ] && continue
1.1       deraadt   533:                tree=`sed -n -e '3s/.* //p' -e 3q $file`
                    534:                mtree -f $file -p $tree > $TMP1
                    535:                if [ -s $TMP1 ]; then
                    536:                        printf "\nChecking $tree:\n" >> $OUTPUT
                    537:                        cat $TMP1 >> $OUTPUT
                    538:                fi
                    539:        done
                    540:        if [ -s $OUTPUT ] ; then
                    541:                printf "\nChecking system binaries:\n"
                    542:                cat $OUTPUT
                    543:        fi
1.2     ! deraadt   544: else
        !           545:        echo /etc/mtree is missing
1.1       deraadt   546: fi
                    547:
                    548: # List of files that get backed up and checked for any modifications.  Each
                    549: # file is expected to have two backups, /var/backups/file.{current,backup}.
                    550: # Any changes cause the files to rotate.
                    551: if [ -s /etc/changelist ] ; then
                    552:        for file in `cat /etc/changelist`; do
                    553:                CUR=/var/backups/`basename $file`.current
                    554:                BACK=/var/backups/`basename $file`.backup
                    555:                if [ -s $file ]; then
                    556:                        if [ -s $CUR ] ; then
                    557:                                diff $CUR $file > $OUTPUT
                    558:                                if [ -s $OUTPUT ] ; then
                    559:                printf "\n======\n%s diffs (OLD < > NEW)\n======\n" $file
                    560:                                        cat $OUTPUT
                    561:                                        cp -p $CUR $BACK
                    562:                                        cp -p $file $CUR
                    563:                                        chown root.wheel $CUR $BACK
                    564:                                fi
                    565:                        else
                    566:                                cp -p $file $CUR
                    567:                                chown root.wheel $CUR
                    568:                        fi
                    569:                fi
                    570:        done
                    571: fi