components/sendmail/files/check-hostname.sh
changeset 3649 4006eaaa7d29
child 7951 3b581304cb26
equal deleted inserted replaced
3648:29c40c98aad3 3649:4006eaaa7d29
       
     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 hostname configuration as per the sendmail code.
       
    24 #
       
    25 # See http://www.sendmail.org/sun-specific/migration.html#FQHN for details.
       
    26 #
       
    27 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
       
    28 # Use is subject to license terms.
       
    29 #
       
    30 
       
    31 PATH=/bin:/usr/sbin
       
    32 
       
    33 # If $1 has a ".", accept it and exit.
       
    34 
       
    35 accept_if_fully_qualified() {
       
    36 	case $1 in
       
    37 	*.*)
       
    38 		echo "Hostname $myhostname OK: fully qualified as $1"
       
    39 		exit 0
       
    40 		;;
       
    41 	esac
       
    42 }
       
    43 
       
    44 # Check the `getent hosts $1` output, skipping the 1st entry (IP address).
       
    45 
       
    46 check_gethostbyname() {
       
    47 	for host in `getent hosts $1 | awk '{for (f=2; f <= NF; f++) print $f}'`
       
    48 	do
       
    49 		accept_if_fully_qualified $host
       
    50 	done
       
    51 }
       
    52 
       
    53 # Parse /etc/hosts, looking for $1 as an entry by itself, and try to find
       
    54 # a long name on the same line.  First kill all comments, then check for
       
    55 # $1 as a word by itself, then take just the first such line, then skip
       
    56 # its first entry (IP address).
       
    57 
       
    58 check_hosts_file() {
       
    59 	for entry in `sed -e 's/#.*$//' /etc/hosts | \
       
    60 		awk '/[ 	]'$1'([ 	]|$)/ \
       
    61 			{for (f=2; f <= NF; f++) print $f; exit}'`
       
    62 	do
       
    63 		accept_if_fully_qualified $entry
       
    64 	done
       
    65 }
       
    66 
       
    67 # Parse the output of `nslookup $1`, checking the Name and Aliases.
       
    68 
       
    69 check_dns() {
       
    70 	for host in `nslookup $1 2>/dev/null | \
       
    71 		awk '$1 == "Name:" || $1 == "Aliases:"{print $2}'`
       
    72 	do
       
    73 		accept_if_fully_qualified $host
       
    74 	done
       
    75 }
       
    76 
       
    77 # Check the `ypmatch $1 hosts` output, skipping the 1st entry (IP address).
       
    78 
       
    79 check_nis() {
       
    80 	for hst in `ypmatch $1 hosts | awk '{for (f=2; f <= NF; f++) print $f}'`
       
    81 	do
       
    82 		accept_if_fully_qualified $hst
       
    83 	done
       
    84 }
       
    85 
       
    86 # Recommend how to reconfigure to get $1.$2 as the FQHN.
       
    87 # $3 is the first entry for hosts in /etc/nsswitch.conf . 
       
    88 
       
    89 suggest_fix_and_exit() {
       
    90 	myhost=$1
       
    91 	suggested_domain=$2
       
    92 	fhe=$3
       
    93 	myipaddr=`getent hosts $myhost | head -1 | awk '{print $1}'`
       
    94 
       
    95 	# aliases: skip the 1st & 2nd entries: IP address & canonical name
       
    96 
       
    97 	set -- '' '' '[ aliases ... ]'
       
    98 	set -- `grep "^$myipaddr[	 ]" /etc/hosts 2>/dev/null`
       
    99 	result=$?
       
   100 	shift 2
       
   101 	echo "We recommend \c"
       
   102 	if [ "x$fhe" != "xfiles" ] ; then
       
   103 		echo "listing files first for hosts in /etc/nsswitch.conf"
       
   104 		echo "and then \c"
       
   105 	fi
       
   106 	if [ $result = 0 ] ; then
       
   107 		echo "changing the /etc/hosts entry:\n"
       
   108 		echo "$myipaddr $myhost $*\n"
       
   109 		echo "to:\n"
       
   110 	else
       
   111 		echo "adding the /etc/hosts entry:\n"
       
   112 	fi
       
   113 	echo "$myipaddr $myhost $myhost.$suggested_domain $*"
       
   114 	exit 0
       
   115 }
       
   116 
       
   117 # Fall back to the NIS domain, minus the first label.  If it is non-null,
       
   118 # use it but recommend against it.  $2 is just informative, indicating whether
       
   119 # we're checking the NIS domain.  $3 is to pass on.
       
   120 
       
   121 check_nis_domain() {
       
   122 	nisdomain=`domainname`
       
   123 	realdomain=`echo $nisdomain | sed 's/[^.]*\.//'`
       
   124 	if [ "x$realdomain" != "x" ] ; then
       
   125 		echo "Hostname $1 can be fully qualified using NIS$2 domain"
       
   126 		echo "	$nisdomain"
       
   127 		echo "resulting in the name"
       
   128 		echo "	$1.$realdomain"
       
   129 		echo "but this is bad practice.\n"
       
   130 		suggest_fix_and_exit $1 $realdomain $3
       
   131 	fi
       
   132 }
       
   133 
       
   134 # Goal: try to fully qualify `hostname` as sendmail would.
       
   135 # Algorithm (stop as soon as a name with a dot is found):
       
   136 #    1. gethostbyname (simulate with getent hosts)
       
   137 #    2. fall back to individual hosts: methods in nsswitch.conf, using
       
   138 #       only those that are configured, in their configured order
       
   139 #       * files (parse /etc/hosts directly)
       
   140 #       * dns (parse nslookup output)
       
   141 #       * nis (parse ypmatch output)
       
   142 #    3. fall back to the NIS domain name.
       
   143 # If none of the above succeed, give up.  Recommend:
       
   144 #    a. the domain entry in /etc/resolv.conf, if one exists
       
   145 #    b. "pick.some.domain"
       
   146 
       
   147 myhostname=`hostname`
       
   148 
       
   149 check_gethostbyname $myhostname
       
   150 
       
   151 hosts_line=`sed -n -e 's/^hosts:\([^#]*\).*/\1/p' /etc/nsswitch.conf`
       
   152 first_hosts_entry=`echo $hosts_line | awk '{print $1}'`
       
   153 nis_domains=""
       
   154 
       
   155 for entry in $hosts_line
       
   156 do
       
   157 	case $entry in
       
   158 	files)
       
   159 		check_hosts_file $myhostname
       
   160 		;;
       
   161 	dns)
       
   162 		check_dns $myhostname
       
   163 		;;
       
   164 	nis)
       
   165 		check_nis $myhostname
       
   166 		nis_domains="$nis_domains nis"
       
   167 		;;
       
   168 	esac
       
   169 done
       
   170 
       
   171 for entry in $nis_domains
       
   172 do
       
   173 	case $entry in
       
   174 	nis)
       
   175 		check_nis_domain $myhostname "" $first_hosts_entry
       
   176 		;;
       
   177 	esac
       
   178 done
       
   179 
       
   180 realdomain=`awk '$1 ~ /^domain/ {print $2}' 2>/dev/null < /etc/resolv.conf`
       
   181 case $realdomain in
       
   182 *.*)
       
   183 	# OK
       
   184 	;;
       
   185 *)
       
   186 	realdomain="pick.some.domain"
       
   187 	;;
       
   188 esac
       
   189 
       
   190 echo "Hostname $myhostname could not be fully qualified."
       
   191 suggest_fix_and_exit $myhostname $realdomain $first_hosts_entry