xref: /onnv-gate/usr/src/cmd/sendmail/cf/sh/check-hostname.sh (revision 0:68f95e015346)
1*0Sstevel@tonic-gate#!/bin/sh --
2*0Sstevel@tonic-gate#
3*0Sstevel@tonic-gate# CDDL HEADER START
4*0Sstevel@tonic-gate#
5*0Sstevel@tonic-gate# The contents of this file are subject to the terms of the
6*0Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only
7*0Sstevel@tonic-gate# (the "License").  You may not use this file except in compliance
8*0Sstevel@tonic-gate# with the License.
9*0Sstevel@tonic-gate#
10*0Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11*0Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
12*0Sstevel@tonic-gate# See the License for the specific language governing permissions
13*0Sstevel@tonic-gate# and limitations under the License.
14*0Sstevel@tonic-gate#
15*0Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
16*0Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17*0Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
18*0Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
19*0Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
20*0Sstevel@tonic-gate#
21*0Sstevel@tonic-gate# CDDL HEADER END
22*0Sstevel@tonic-gate#
23*0Sstevel@tonic-gate
24*0Sstevel@tonic-gate# Check hostname configuration as per the sendmail code.
25*0Sstevel@tonic-gate#
26*0Sstevel@tonic-gate# See http://www.sendmail.org/sun-specific/migration.html#FQHN for details.
27*0Sstevel@tonic-gate#
28*0Sstevel@tonic-gate# Copyright (c) 1997-2000 by Sun Microsystems, Inc.
29*0Sstevel@tonic-gate# All Rights Reserved.
30*0Sstevel@tonic-gate#
31*0Sstevel@tonic-gate# %W% (Sun) %G%
32*0Sstevel@tonic-gate# ident	"%Z%%M%	%I%	%E% SMI"
33*0Sstevel@tonic-gate
34*0Sstevel@tonic-gatePATH=/bin:/usr/sbin
35*0Sstevel@tonic-gate
36*0Sstevel@tonic-gate# If $1 has a ".", accept it and exit.
37*0Sstevel@tonic-gate
38*0Sstevel@tonic-gateaccept_if_fully_qualified() {
39*0Sstevel@tonic-gate	case $1 in
40*0Sstevel@tonic-gate	*.*)
41*0Sstevel@tonic-gate		echo "Hostname $myhostname OK: fully qualified as $1"
42*0Sstevel@tonic-gate		exit 0
43*0Sstevel@tonic-gate		;;
44*0Sstevel@tonic-gate	esac
45*0Sstevel@tonic-gate}
46*0Sstevel@tonic-gate
47*0Sstevel@tonic-gate# Check the `getent hosts $1` output, skipping the 1st entry (IP address).
48*0Sstevel@tonic-gate
49*0Sstevel@tonic-gatecheck_gethostbyname() {
50*0Sstevel@tonic-gate	for host in `getent hosts $1 | awk '{for (f=2; f <= NF; f++) print $f}'`
51*0Sstevel@tonic-gate	do
52*0Sstevel@tonic-gate		accept_if_fully_qualified $host
53*0Sstevel@tonic-gate	done
54*0Sstevel@tonic-gate}
55*0Sstevel@tonic-gate
56*0Sstevel@tonic-gate# Parse /etc/hosts, looking for $1 as an entry by itself, and try to find
57*0Sstevel@tonic-gate# a long name on the same line.  First kill all comments, then check for
58*0Sstevel@tonic-gate# $1 as a word by itself, then take just the first such line, then skip
59*0Sstevel@tonic-gate# its first entry (IP address).
60*0Sstevel@tonic-gate
61*0Sstevel@tonic-gatecheck_hosts_file() {
62*0Sstevel@tonic-gate	for entry in `sed -e 's/#.*$//' /etc/hosts | \
63*0Sstevel@tonic-gate		awk '/[ 	]'$1'([ 	]|$)/ \
64*0Sstevel@tonic-gate			{for (f=2; f <= NF; f++) print $f; exit}'`
65*0Sstevel@tonic-gate	do
66*0Sstevel@tonic-gate		accept_if_fully_qualified $entry
67*0Sstevel@tonic-gate	done
68*0Sstevel@tonic-gate}
69*0Sstevel@tonic-gate
70*0Sstevel@tonic-gate# Parse the output of `nslookup $1`, checking the Name and Aliases.
71*0Sstevel@tonic-gate
72*0Sstevel@tonic-gatecheck_dns() {
73*0Sstevel@tonic-gate	for host in `nslookup $1 2>/dev/null | \
74*0Sstevel@tonic-gate		awk '$1 == "Name:" || $1 == "Aliases:"{print $2}'`
75*0Sstevel@tonic-gate	do
76*0Sstevel@tonic-gate		accept_if_fully_qualified $host
77*0Sstevel@tonic-gate	done
78*0Sstevel@tonic-gate}
79*0Sstevel@tonic-gate
80*0Sstevel@tonic-gate# Check the `ypmatch $1 hosts` output, skipping the 1st entry (IP address).
81*0Sstevel@tonic-gate
82*0Sstevel@tonic-gatecheck_nis() {
83*0Sstevel@tonic-gate	for hst in `ypmatch $1 hosts | awk '{for (f=2; f <= NF; f++) print $f}'`
84*0Sstevel@tonic-gate	do
85*0Sstevel@tonic-gate		accept_if_fully_qualified $hst
86*0Sstevel@tonic-gate	done
87*0Sstevel@tonic-gate}
88*0Sstevel@tonic-gate
89*0Sstevel@tonic-gate# Check the `nismatch $1 hosts` output.  Its output is different from ypmatch
90*0Sstevel@tonic-gate# and the hosts file.  Field 1 is a cname (i.e., alias), field 2 is the
91*0Sstevel@tonic-gate# proper name, field 3 is the IP address and field 4 is comment.
92*0Sstevel@tonic-gate
93*0Sstevel@tonic-gatecheck_nisplus() {
94*0Sstevel@tonic-gate	for hst in `nismatch $1 hosts.org_dir | \
95*0Sstevel@tonic-gate		awk '{for (f=1; f <= 2; f++) print $f}'`
96*0Sstevel@tonic-gate	do
97*0Sstevel@tonic-gate		accept_if_fully_qualified $hst
98*0Sstevel@tonic-gate	done
99*0Sstevel@tonic-gate}
100*0Sstevel@tonic-gate
101*0Sstevel@tonic-gate# Recommend how to reconfigure to get $1.$2 as the FQHN.
102*0Sstevel@tonic-gate# $3 is the first entry for hosts in /etc/nsswitch.conf .
103*0Sstevel@tonic-gate
104*0Sstevel@tonic-gatesuggest_fix_and_exit() {
105*0Sstevel@tonic-gate	myhost=$1
106*0Sstevel@tonic-gate	suggested_domain=$2
107*0Sstevel@tonic-gate	fhe=$3
108*0Sstevel@tonic-gate	myipaddr=`getent hosts $myhost | head -1 | awk '{print $1}'`
109*0Sstevel@tonic-gate
110*0Sstevel@tonic-gate	# aliases: skip the 1st & 2nd entries: IP address & canonical name
111*0Sstevel@tonic-gate
112*0Sstevel@tonic-gate	set -- '' '' '[ aliases ... ]'
113*0Sstevel@tonic-gate	set -- `grep "^$myipaddr[	 ]" /etc/hosts 2>/dev/null`
114*0Sstevel@tonic-gate	result=$?
115*0Sstevel@tonic-gate	shift 2
116*0Sstevel@tonic-gate	echo "We recommend \c"
117*0Sstevel@tonic-gate	if [ "x$fhe" != "xfiles" ] ; then
118*0Sstevel@tonic-gate		echo "listing files first for hosts in /etc/nsswitch.conf"
119*0Sstevel@tonic-gate		echo "and then \c"
120*0Sstevel@tonic-gate	fi
121*0Sstevel@tonic-gate	if [ $result = 0 ] ; then
122*0Sstevel@tonic-gate		echo "changing the /etc/hosts entry:\n"
123*0Sstevel@tonic-gate		echo "$myipaddr $myhost $*\n"
124*0Sstevel@tonic-gate		echo "to:\n"
125*0Sstevel@tonic-gate	else
126*0Sstevel@tonic-gate		echo "adding the /etc/hosts entry:\n"
127*0Sstevel@tonic-gate	fi
128*0Sstevel@tonic-gate	echo "$myipaddr $myhost $myhost.$suggested_domain $*"
129*0Sstevel@tonic-gate	exit 0
130*0Sstevel@tonic-gate}
131*0Sstevel@tonic-gate
132*0Sstevel@tonic-gate# Fall back to the NIS[+] domain, minus the first label.  If it is non-null,
133*0Sstevel@tonic-gate# use it but recommend against it.  $2 is just informative, indicating whether
134*0Sstevel@tonic-gate# we're checking the NIS or NIS+ domain.  $3 is to pass on.
135*0Sstevel@tonic-gate
136*0Sstevel@tonic-gatecheck_nis_domain() {
137*0Sstevel@tonic-gate	nisdomain=`domainname`
138*0Sstevel@tonic-gate	realdomain=`echo $nisdomain | sed 's/[^.]*\.//'`
139*0Sstevel@tonic-gate	if [ "x$realdomain" != "x" ] ; then
140*0Sstevel@tonic-gate		echo "Hostname $1 can be fully qualified using NIS$2 domain"
141*0Sstevel@tonic-gate		echo "	$nisdomain"
142*0Sstevel@tonic-gate		echo "resulting in the name"
143*0Sstevel@tonic-gate		echo "	$1.$realdomain"
144*0Sstevel@tonic-gate		echo "but this is bad practice.\n"
145*0Sstevel@tonic-gate		suggest_fix_and_exit $1 $realdomain $3
146*0Sstevel@tonic-gate	fi
147*0Sstevel@tonic-gate}
148*0Sstevel@tonic-gate
149*0Sstevel@tonic-gate# Goal: try to fully qualify `hostname` as sendmail would.
150*0Sstevel@tonic-gate# Algorithm (stop as soon as a name with a dot is found):
151*0Sstevel@tonic-gate#    1. gethostbyname (simulate with getent hosts)
152*0Sstevel@tonic-gate#    2. fall back to individual hosts: methods in nsswitch.conf, using
153*0Sstevel@tonic-gate#       only those that are configured, in their configured order
154*0Sstevel@tonic-gate#       * files (parse /etc/hosts directly)
155*0Sstevel@tonic-gate#       * dns (parse nslookup output)
156*0Sstevel@tonic-gate#       * nis (parse ypmatch output)
157*0Sstevel@tonic-gate#       * nisplus (parse nismatch output)
158*0Sstevel@tonic-gate#    3. fall back to the NIS[+] domain name.
159*0Sstevel@tonic-gate# If none of the above succeed, give up.  Recommend:
160*0Sstevel@tonic-gate#    a. the domain entry in /etc/resolv.conf, if one exists
161*0Sstevel@tonic-gate#    b. "pick.some.domain"
162*0Sstevel@tonic-gate
163*0Sstevel@tonic-gatemyhostname=`hostname`
164*0Sstevel@tonic-gate
165*0Sstevel@tonic-gatecheck_gethostbyname $myhostname
166*0Sstevel@tonic-gate
167*0Sstevel@tonic-gatehosts_line=`sed -n -e 's/^hosts:\([^#]*\).*/\1/p' /etc/nsswitch.conf`
168*0Sstevel@tonic-gatefirst_hosts_entry=`echo $hosts_line | awk '{print $1}'`
169*0Sstevel@tonic-gatenis_domains=""
170*0Sstevel@tonic-gate
171*0Sstevel@tonic-gatefor entry in $hosts_line
172*0Sstevel@tonic-gatedo
173*0Sstevel@tonic-gate	case $entry in
174*0Sstevel@tonic-gate	files)
175*0Sstevel@tonic-gate		check_hosts_file $myhostname
176*0Sstevel@tonic-gate		;;
177*0Sstevel@tonic-gate	dns)
178*0Sstevel@tonic-gate		check_dns $myhostname
179*0Sstevel@tonic-gate		;;
180*0Sstevel@tonic-gate	nis)
181*0Sstevel@tonic-gate		check_nis $myhostname
182*0Sstevel@tonic-gate		nis_domains="$nis_domains nis"
183*0Sstevel@tonic-gate		;;
184*0Sstevel@tonic-gate	nisplus)
185*0Sstevel@tonic-gate		check_nisplus $myhostname
186*0Sstevel@tonic-gate		nis_domains="$nis_domains nisplus"
187*0Sstevel@tonic-gate		;;
188*0Sstevel@tonic-gate	esac
189*0Sstevel@tonic-gatedone
190*0Sstevel@tonic-gate
191*0Sstevel@tonic-gatefor entry in $nis_domains
192*0Sstevel@tonic-gatedo
193*0Sstevel@tonic-gate	case $entry in
194*0Sstevel@tonic-gate	nis)
195*0Sstevel@tonic-gate		check_nis_domain $myhostname "" $first_hosts_entry
196*0Sstevel@tonic-gate		;;
197*0Sstevel@tonic-gate	nisplus)
198*0Sstevel@tonic-gate		check_nis_domain $myhostname "+" $first_hosts_entry
199*0Sstevel@tonic-gate		;;
200*0Sstevel@tonic-gate	esac
201*0Sstevel@tonic-gatedone
202*0Sstevel@tonic-gate
203*0Sstevel@tonic-gaterealdomain=`awk '$1 ~ /^domain/ {print $2}' 2>/dev/null < /etc/resolv.conf`
204*0Sstevel@tonic-gatecase $realdomain in
205*0Sstevel@tonic-gate*.*)
206*0Sstevel@tonic-gate	# OK
207*0Sstevel@tonic-gate	;;
208*0Sstevel@tonic-gate*)
209*0Sstevel@tonic-gate	realdomain="pick.some.domain"
210*0Sstevel@tonic-gate	;;
211*0Sstevel@tonic-gateesac
212*0Sstevel@tonic-gate
213*0Sstevel@tonic-gateecho "Hostname $myhostname could not be fully qualified."
214*0Sstevel@tonic-gatesuggest_fix_and_exit $myhostname $realdomain $first_hosts_entry
215