1 #!/bin/sh --
   2 #
   3 # CDDL HEADER START
   4 #
   5 # The contents of this file are subject to the terms of the
   6 # Common Development and Distribution License (the "License").
   7 # You may not use this file except in compliance with the License.
   8 #
   9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10 # or http://www.opensolaris.org/os/licensing.
  11 # See the License for the specific language governing permissions
  12 # and limitations under the License.
  13 #
  14 # When distributing Covered Code, include this CDDL HEADER in each
  15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16 # If applicable, add the following below this CDDL HEADER, with the
  17 # fields enclosed by brackets "[]" replaced with your own identifying
  18 # information: Portions Copyright [yyyy] [name of copyright owner]
  19 #
  20 # CDDL HEADER END
  21 #
  22 
  23 # Check :include: aliases (in files configured in sendmail.cf) and .forward
  24 # files to make sure the files and their parent directory paths all have
  25 # proper permissions.  And check the master alias file(s) too.
  26 #
  27 # See http://www.sendmail.org/vendor/sun/migration.html#Security for details.
  28 #
  29 # Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  30 # Use is subject to license terms.
  31 #
  32 # %W% (Sun) %G%
  33 
  34 PATH=/bin
  35 
  36 # Check the group- and world-writable bits on the given file.
  37 
  38 analyze() {
  39         case "`ls -Lldn $1`" in
  40                 ?????w??w?*) 
  41                         echo $2: $1 is group and world writable
  42                         bogus_dirs=true ;;
  43                 ????????w?*) 
  44                         echo $2: $1 is world writable
  45                         bogus_dirs=true ;;
  46                 ?????w????*) 
  47                         echo $2: $1 is group writable
  48                         bogus_dirs=true ;;
  49         esac
  50 }
  51 
  52 # Break down the given file name into its components, and call analyze with
  53 # each of them.  E.g., an argument of /usr/local/aliases/foo.list would call
  54 # analyze in turn with arguments:
  55 # * /usr/local/aliases/foo.list
  56 # * /usr/local/aliases
  57 # * /usr/local
  58 # * /usr
  59 
  60 break_down() {
  61         for j in `echo $1 | \
  62                 awk '{
  63                         n = split($0, parts, "/");
  64                         for (i = n; i >= 2; i--){
  65                                 string = "";
  66                                 for (j = 2; j <= i; j++){
  67                                         string = sprintf("%s/%s", string, parts[j]);
  68                                 }
  69                                 print string
  70                         }
  71                 }'` "/"
  72         do
  73                 analyze $j $1
  74         done
  75 }
  76 
  77 config=/etc/mail/sendmail.cf
  78 bogus_dirs=false
  79 
  80 afl1=`grep "^OA" $config | sed 's/^OA//' | sed 's/,/ /g' | sed 's/.*://'`
  81 afl2=`grep "^O AliasFile=" $config | sed 's/^O AliasFile=//' | \
  82     sed 's/,/ /g' | sed 's/.*://'`
  83 
  84 # These should be OK themselves, but other packages may have screwed up the
  85 # permissions on /etc or /etc/mail .  And best to check in case non-standard
  86 # alias paths are used.
  87 
  88 break_down $afl1 $afl2
  89 
  90 # Find all valid :include: files used in alias files configured in sendmail.cf
  91 
  92 for i in `sed 's/^[#].*$//' $afl1 $afl2 | \
  93         grep :include: | \
  94         sed 's/.*:include://' | \
  95         sed 's/,.*$//'`
  96 do
  97         break_down $i
  98 done
  99 
 100 # Check .forward files as well.  If the argument "ALL" is given, do it for
 101 # everyone.  If no argument to the script is given, just do it for the current
 102 # user.  O/w, do it for all arguments.
 103 
 104 if [ $# -eq 0 ] ; then
 105         arg=`id | /usr/xpg4/bin/awk -F'(' '{n = split($2,id,")"); print id[1]}'`
 106 elif [ $1 = "ALL" ] ; then
 107         arg=""
 108 else
 109         arg="$*"
 110 fi
 111 
 112 for i in `getent passwd $arg | /usr/xpg4/bin/awk -F: '{print $6}'`
 113 do
 114         if [ -f $i/.forward ] ; then
 115                 break_down $i/.forward
 116         fi
 117 done
 118 
 119 $bogus_dirs || echo "No unsafe directories found."