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 # ident "%Z%%M% %I%     %E% SMI"
  34 
  35 PATH=/bin
  36 
  37 # Check the group- and world-writable bits on the given file.
  38 
  39 analyze() {
  40         case "`ls -Lldn $1`" in
  41                 ?????w??w?*) 
  42                         echo $2: $1 is group and world writable
  43                         bogus_dirs=true ;;
  44                 ????????w?*) 
  45                         echo $2: $1 is world writable
  46                         bogus_dirs=true ;;
  47                 ?????w????*) 
  48                         echo $2: $1 is group writable
  49                         bogus_dirs=true ;;
  50         esac
  51 }
  52 
  53 # Break down the given file name into its components, and call analyze with
  54 # each of them.  E.g., an argument of /usr/local/aliases/foo.list would call
  55 # analyze in turn with arguments:
  56 # * /usr/local/aliases/foo.list
  57 # * /usr/local/aliases
  58 # * /usr/local
  59 # * /usr
  60 
  61 break_down() {
  62         for j in `echo $1 | \
  63                 awk '{
  64                         n = split($0, parts, "/");
  65                         for (i = n; i >= 2; i--){
  66                                 string = "";
  67                                 for (j = 2; j <= i; j++){
  68                                         string = sprintf("%s/%s", string, parts[j]);
  69                                 }
  70                                 print string
  71                         }
  72                 }'` "/"
  73         do
  74                 analyze $j $1
  75         done
  76 }
  77 
  78 config=/etc/mail/sendmail.cf
  79 bogus_dirs=false
  80 
  81 afl1=`grep "^OA" $config | sed 's/^OA//' | sed 's/,/ /g' | sed 's/.*://'`
  82 afl2=`grep "^O AliasFile=" $config | sed 's/^O AliasFile=//' | \
  83     sed 's/,/ /g' | sed 's/.*://'`
  84 
  85 # These should be OK themselves, but other packages may have screwed up the
  86 # permissions on /etc or /etc/mail .  And best to check in case non-standard
  87 # alias paths are used.
  88 
  89 break_down $afl1 $afl2
  90 
  91 # Find all valid :include: files used in alias files configured in sendmail.cf
  92 
  93 for i in `sed 's/^[#].*$//' $afl1 $afl2 | \
  94         grep :include: | \
  95         sed 's/.*:include://' | \
  96         sed 's/,.*$//'`
  97 do
  98         break_down $i
  99 done
 100 
 101 # Check .forward files as well.  If the argument "ALL" is given, do it for
 102 # everyone.  If no argument to the script is given, just do it for the current
 103 # user.  O/w, do it for all arguments.
 104 
 105 if [ $# -eq 0 ] ; then
 106         arg=`id | nawk -F'(' '{n = split($2,id,")"); print id[1]}'`
 107 elif [ $1 = "ALL" ] ; then
 108         arg=""
 109 else
 110         arg="$*"
 111 fi
 112 
 113 for i in `getent passwd $arg | nawk -F: '{print $6}'`
 114 do
 115         if [ -f $i/.forward ] ; then
 116                 break_down $i/.forward
 117         fi
 118 done
 119 
 120 $bogus_dirs || echo "No unsafe directories found."