xref: /illumos-gate/usr/src/cmd/sendmail/cf/sh/check-hostname.sh (revision 36e852a172cba914383d7341c988128b2c667fbd)
17c478bd9Sstevel@tonic-gate#!/bin/sh --
27c478bd9Sstevel@tonic-gate#
37c478bd9Sstevel@tonic-gate# CDDL HEADER START
47c478bd9Sstevel@tonic-gate#
57c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the
6*36e852a1SRaja Andra# Common Development and Distribution License (the "License").
7*36e852a1SRaja Andra# You may not use this file except in compliance with the License.
87c478bd9Sstevel@tonic-gate#
97c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate# and limitations under the License.
137c478bd9Sstevel@tonic-gate#
147c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate#
207c478bd9Sstevel@tonic-gate# CDDL HEADER END
217c478bd9Sstevel@tonic-gate#
227c478bd9Sstevel@tonic-gate
237c478bd9Sstevel@tonic-gate# Check hostname configuration as per the sendmail code.
247c478bd9Sstevel@tonic-gate#
257c478bd9Sstevel@tonic-gate# See http://www.sendmail.org/sun-specific/migration.html#FQHN for details.
267c478bd9Sstevel@tonic-gate#
27*36e852a1SRaja Andra# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
28*36e852a1SRaja Andra# Use is subject to license terms.
297c478bd9Sstevel@tonic-gate#
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gatePATH=/bin:/usr/sbin
327c478bd9Sstevel@tonic-gate
337c478bd9Sstevel@tonic-gate# If $1 has a ".", accept it and exit.
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gateaccept_if_fully_qualified() {
367c478bd9Sstevel@tonic-gate	case $1 in
377c478bd9Sstevel@tonic-gate	*.*)
387c478bd9Sstevel@tonic-gate		echo "Hostname $myhostname OK: fully qualified as $1"
397c478bd9Sstevel@tonic-gate		exit 0
407c478bd9Sstevel@tonic-gate		;;
417c478bd9Sstevel@tonic-gate	esac
427c478bd9Sstevel@tonic-gate}
437c478bd9Sstevel@tonic-gate
447c478bd9Sstevel@tonic-gate# Check the `getent hosts $1` output, skipping the 1st entry (IP address).
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gatecheck_gethostbyname() {
477c478bd9Sstevel@tonic-gate	for host in `getent hosts $1 | awk '{for (f=2; f <= NF; f++) print $f}'`
487c478bd9Sstevel@tonic-gate	do
497c478bd9Sstevel@tonic-gate		accept_if_fully_qualified $host
507c478bd9Sstevel@tonic-gate	done
517c478bd9Sstevel@tonic-gate}
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate# Parse /etc/hosts, looking for $1 as an entry by itself, and try to find
547c478bd9Sstevel@tonic-gate# a long name on the same line.  First kill all comments, then check for
557c478bd9Sstevel@tonic-gate# $1 as a word by itself, then take just the first such line, then skip
567c478bd9Sstevel@tonic-gate# its first entry (IP address).
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gatecheck_hosts_file() {
597c478bd9Sstevel@tonic-gate	for entry in `sed -e 's/#.*$//' /etc/hosts | \
607c478bd9Sstevel@tonic-gate		awk '/[ 	]'$1'([ 	]|$)/ \
617c478bd9Sstevel@tonic-gate			{for (f=2; f <= NF; f++) print $f; exit}'`
627c478bd9Sstevel@tonic-gate	do
637c478bd9Sstevel@tonic-gate		accept_if_fully_qualified $entry
647c478bd9Sstevel@tonic-gate	done
657c478bd9Sstevel@tonic-gate}
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate# Parse the output of `nslookup $1`, checking the Name and Aliases.
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gatecheck_dns() {
707c478bd9Sstevel@tonic-gate	for host in `nslookup $1 2>/dev/null | \
717c478bd9Sstevel@tonic-gate		awk '$1 == "Name:" || $1 == "Aliases:"{print $2}'`
727c478bd9Sstevel@tonic-gate	do
737c478bd9Sstevel@tonic-gate		accept_if_fully_qualified $host
747c478bd9Sstevel@tonic-gate	done
757c478bd9Sstevel@tonic-gate}
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gate# Check the `ypmatch $1 hosts` output, skipping the 1st entry (IP address).
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gatecheck_nis() {
807c478bd9Sstevel@tonic-gate	for hst in `ypmatch $1 hosts | awk '{for (f=2; f <= NF; f++) print $f}'`
817c478bd9Sstevel@tonic-gate	do
827c478bd9Sstevel@tonic-gate		accept_if_fully_qualified $hst
837c478bd9Sstevel@tonic-gate	done
847c478bd9Sstevel@tonic-gate}
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate# Recommend how to reconfigure to get $1.$2 as the FQHN.
877c478bd9Sstevel@tonic-gate# $3 is the first entry for hosts in /etc/nsswitch.conf .
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gatesuggest_fix_and_exit() {
907c478bd9Sstevel@tonic-gate	myhost=$1
917c478bd9Sstevel@tonic-gate	suggested_domain=$2
927c478bd9Sstevel@tonic-gate	fhe=$3
937c478bd9Sstevel@tonic-gate	myipaddr=`getent hosts $myhost | head -1 | awk '{print $1}'`
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate	# aliases: skip the 1st & 2nd entries: IP address & canonical name
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate	set -- '' '' '[ aliases ... ]'
987c478bd9Sstevel@tonic-gate	set -- `grep "^$myipaddr[	 ]" /etc/hosts 2>/dev/null`
997c478bd9Sstevel@tonic-gate	result=$?
1007c478bd9Sstevel@tonic-gate	shift 2
1017c478bd9Sstevel@tonic-gate	echo "We recommend \c"
1027c478bd9Sstevel@tonic-gate	if [ "x$fhe" != "xfiles" ] ; then
1037c478bd9Sstevel@tonic-gate		echo "listing files first for hosts in /etc/nsswitch.conf"
1047c478bd9Sstevel@tonic-gate		echo "and then \c"
1057c478bd9Sstevel@tonic-gate	fi
1067c478bd9Sstevel@tonic-gate	if [ $result = 0 ] ; then
1077c478bd9Sstevel@tonic-gate		echo "changing the /etc/hosts entry:\n"
1087c478bd9Sstevel@tonic-gate		echo "$myipaddr $myhost $*\n"
1097c478bd9Sstevel@tonic-gate		echo "to:\n"
1107c478bd9Sstevel@tonic-gate	else
1117c478bd9Sstevel@tonic-gate		echo "adding the /etc/hosts entry:\n"
1127c478bd9Sstevel@tonic-gate	fi
1137c478bd9Sstevel@tonic-gate	echo "$myipaddr $myhost $myhost.$suggested_domain $*"
1147c478bd9Sstevel@tonic-gate	exit 0
1157c478bd9Sstevel@tonic-gate}
1167c478bd9Sstevel@tonic-gate
117*36e852a1SRaja Andra# Fall back to the NIS domain, minus the first label.  If it is non-null,
1187c478bd9Sstevel@tonic-gate# use it but recommend against it.  $2 is just informative, indicating whether
119*36e852a1SRaja Andra# we're checking the NIS domain.  $3 is to pass on.
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gatecheck_nis_domain() {
1227c478bd9Sstevel@tonic-gate	nisdomain=`domainname`
1237c478bd9Sstevel@tonic-gate	realdomain=`echo $nisdomain | sed 's/[^.]*\.//'`
1247c478bd9Sstevel@tonic-gate	if [ "x$realdomain" != "x" ] ; then
1257c478bd9Sstevel@tonic-gate		echo "Hostname $1 can be fully qualified using NIS$2 domain"
1267c478bd9Sstevel@tonic-gate		echo "	$nisdomain"
1277c478bd9Sstevel@tonic-gate		echo "resulting in the name"
1287c478bd9Sstevel@tonic-gate		echo "	$1.$realdomain"
1297c478bd9Sstevel@tonic-gate		echo "but this is bad practice.\n"
1307c478bd9Sstevel@tonic-gate		suggest_fix_and_exit $1 $realdomain $3
1317c478bd9Sstevel@tonic-gate	fi
1327c478bd9Sstevel@tonic-gate}
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate# Goal: try to fully qualify `hostname` as sendmail would.
1357c478bd9Sstevel@tonic-gate# Algorithm (stop as soon as a name with a dot is found):
1367c478bd9Sstevel@tonic-gate#    1. gethostbyname (simulate with getent hosts)
1377c478bd9Sstevel@tonic-gate#    2. fall back to individual hosts: methods in nsswitch.conf, using
1387c478bd9Sstevel@tonic-gate#       only those that are configured, in their configured order
1397c478bd9Sstevel@tonic-gate#       * files (parse /etc/hosts directly)
1407c478bd9Sstevel@tonic-gate#       * dns (parse nslookup output)
1417c478bd9Sstevel@tonic-gate#       * nis (parse ypmatch output)
142*36e852a1SRaja Andra#    3. fall back to the NIS domain name.
1437c478bd9Sstevel@tonic-gate# If none of the above succeed, give up.  Recommend:
1447c478bd9Sstevel@tonic-gate#    a. the domain entry in /etc/resolv.conf, if one exists
1457c478bd9Sstevel@tonic-gate#    b. "pick.some.domain"
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gatemyhostname=`hostname`
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gatecheck_gethostbyname $myhostname
1507c478bd9Sstevel@tonic-gate
1517c478bd9Sstevel@tonic-gatehosts_line=`sed -n -e 's/^hosts:\([^#]*\).*/\1/p' /etc/nsswitch.conf`
1527c478bd9Sstevel@tonic-gatefirst_hosts_entry=`echo $hosts_line | awk '{print $1}'`
1537c478bd9Sstevel@tonic-gatenis_domains=""
1547c478bd9Sstevel@tonic-gate
1557c478bd9Sstevel@tonic-gatefor entry in $hosts_line
1567c478bd9Sstevel@tonic-gatedo
1577c478bd9Sstevel@tonic-gate	case $entry in
1587c478bd9Sstevel@tonic-gate	files)
1597c478bd9Sstevel@tonic-gate		check_hosts_file $myhostname
1607c478bd9Sstevel@tonic-gate		;;
1617c478bd9Sstevel@tonic-gate	dns)
1627c478bd9Sstevel@tonic-gate		check_dns $myhostname
1637c478bd9Sstevel@tonic-gate		;;
1647c478bd9Sstevel@tonic-gate	nis)
1657c478bd9Sstevel@tonic-gate		check_nis $myhostname
1667c478bd9Sstevel@tonic-gate		nis_domains="$nis_domains nis"
1677c478bd9Sstevel@tonic-gate		;;
1687c478bd9Sstevel@tonic-gate	esac
1697c478bd9Sstevel@tonic-gatedone
1707c478bd9Sstevel@tonic-gate
1717c478bd9Sstevel@tonic-gatefor entry in $nis_domains
1727c478bd9Sstevel@tonic-gatedo
1737c478bd9Sstevel@tonic-gate	case $entry in
1747c478bd9Sstevel@tonic-gate	nis)
1757c478bd9Sstevel@tonic-gate		check_nis_domain $myhostname "" $first_hosts_entry
1767c478bd9Sstevel@tonic-gate		;;
1777c478bd9Sstevel@tonic-gate	esac
1787c478bd9Sstevel@tonic-gatedone
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gaterealdomain=`awk '$1 ~ /^domain/ {print $2}' 2>/dev/null < /etc/resolv.conf`
1817c478bd9Sstevel@tonic-gatecase $realdomain in
1827c478bd9Sstevel@tonic-gate*.*)
1837c478bd9Sstevel@tonic-gate	# OK
1847c478bd9Sstevel@tonic-gate	;;
1857c478bd9Sstevel@tonic-gate*)
1867c478bd9Sstevel@tonic-gate	realdomain="pick.some.domain"
1877c478bd9Sstevel@tonic-gate	;;
1887c478bd9Sstevel@tonic-gateesac
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gateecho "Hostname $myhostname could not be fully qualified."
1917c478bd9Sstevel@tonic-gatesuggest_fix_and_exit $myhostname $realdomain $first_hosts_entry
192