10Sstevel@tonic-gate#!/bin/sh -- 20Sstevel@tonic-gate# 30Sstevel@tonic-gate# CDDL HEADER START 40Sstevel@tonic-gate# 50Sstevel@tonic-gate# The contents of this file are subject to the terms of the 6*11262SRajagopal.Andra@Sun.COM# Common Development and Distribution License (the "License"). 7*11262SRajagopal.Andra@Sun.COM# You may not use this file except in compliance with the License. 80Sstevel@tonic-gate# 90Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate# See the License for the specific language governing permissions 120Sstevel@tonic-gate# and limitations under the License. 130Sstevel@tonic-gate# 140Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate# 200Sstevel@tonic-gate# CDDL HEADER END 210Sstevel@tonic-gate# 220Sstevel@tonic-gate 230Sstevel@tonic-gate# Check hostname configuration as per the sendmail code. 240Sstevel@tonic-gate# 250Sstevel@tonic-gate# See http://www.sendmail.org/sun-specific/migration.html#FQHN for details. 260Sstevel@tonic-gate# 27*11262SRajagopal.Andra@Sun.COM# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 28*11262SRajagopal.Andra@Sun.COM# Use is subject to license terms. 290Sstevel@tonic-gate# 300Sstevel@tonic-gate 310Sstevel@tonic-gatePATH=/bin:/usr/sbin 320Sstevel@tonic-gate 330Sstevel@tonic-gate# If $1 has a ".", accept it and exit. 340Sstevel@tonic-gate 350Sstevel@tonic-gateaccept_if_fully_qualified() { 360Sstevel@tonic-gate case $1 in 370Sstevel@tonic-gate *.*) 380Sstevel@tonic-gate echo "Hostname $myhostname OK: fully qualified as $1" 390Sstevel@tonic-gate exit 0 400Sstevel@tonic-gate ;; 410Sstevel@tonic-gate esac 420Sstevel@tonic-gate} 430Sstevel@tonic-gate 440Sstevel@tonic-gate# Check the `getent hosts $1` output, skipping the 1st entry (IP address). 450Sstevel@tonic-gate 460Sstevel@tonic-gatecheck_gethostbyname() { 470Sstevel@tonic-gate for host in `getent hosts $1 | awk '{for (f=2; f <= NF; f++) print $f}'` 480Sstevel@tonic-gate do 490Sstevel@tonic-gate accept_if_fully_qualified $host 500Sstevel@tonic-gate done 510Sstevel@tonic-gate} 520Sstevel@tonic-gate 530Sstevel@tonic-gate# Parse /etc/hosts, looking for $1 as an entry by itself, and try to find 540Sstevel@tonic-gate# a long name on the same line. First kill all comments, then check for 550Sstevel@tonic-gate# $1 as a word by itself, then take just the first such line, then skip 560Sstevel@tonic-gate# its first entry (IP address). 570Sstevel@tonic-gate 580Sstevel@tonic-gatecheck_hosts_file() { 590Sstevel@tonic-gate for entry in `sed -e 's/#.*$//' /etc/hosts | \ 600Sstevel@tonic-gate awk '/[ ]'$1'([ ]|$)/ \ 610Sstevel@tonic-gate {for (f=2; f <= NF; f++) print $f; exit}'` 620Sstevel@tonic-gate do 630Sstevel@tonic-gate accept_if_fully_qualified $entry 640Sstevel@tonic-gate done 650Sstevel@tonic-gate} 660Sstevel@tonic-gate 670Sstevel@tonic-gate# Parse the output of `nslookup $1`, checking the Name and Aliases. 680Sstevel@tonic-gate 690Sstevel@tonic-gatecheck_dns() { 700Sstevel@tonic-gate for host in `nslookup $1 2>/dev/null | \ 710Sstevel@tonic-gate awk '$1 == "Name:" || $1 == "Aliases:"{print $2}'` 720Sstevel@tonic-gate do 730Sstevel@tonic-gate accept_if_fully_qualified $host 740Sstevel@tonic-gate done 750Sstevel@tonic-gate} 760Sstevel@tonic-gate 770Sstevel@tonic-gate# Check the `ypmatch $1 hosts` output, skipping the 1st entry (IP address). 780Sstevel@tonic-gate 790Sstevel@tonic-gatecheck_nis() { 800Sstevel@tonic-gate for hst in `ypmatch $1 hosts | awk '{for (f=2; f <= NF; f++) print $f}'` 810Sstevel@tonic-gate do 820Sstevel@tonic-gate accept_if_fully_qualified $hst 830Sstevel@tonic-gate done 840Sstevel@tonic-gate} 850Sstevel@tonic-gate 860Sstevel@tonic-gate# Recommend how to reconfigure to get $1.$2 as the FQHN. 870Sstevel@tonic-gate# $3 is the first entry for hosts in /etc/nsswitch.conf . 880Sstevel@tonic-gate 890Sstevel@tonic-gatesuggest_fix_and_exit() { 900Sstevel@tonic-gate myhost=$1 910Sstevel@tonic-gate suggested_domain=$2 920Sstevel@tonic-gate fhe=$3 930Sstevel@tonic-gate myipaddr=`getent hosts $myhost | head -1 | awk '{print $1}'` 940Sstevel@tonic-gate 950Sstevel@tonic-gate # aliases: skip the 1st & 2nd entries: IP address & canonical name 960Sstevel@tonic-gate 970Sstevel@tonic-gate set -- '' '' '[ aliases ... ]' 980Sstevel@tonic-gate set -- `grep "^$myipaddr[ ]" /etc/hosts 2>/dev/null` 990Sstevel@tonic-gate result=$? 1000Sstevel@tonic-gate shift 2 1010Sstevel@tonic-gate echo "We recommend \c" 1020Sstevel@tonic-gate if [ "x$fhe" != "xfiles" ] ; then 1030Sstevel@tonic-gate echo "listing files first for hosts in /etc/nsswitch.conf" 1040Sstevel@tonic-gate echo "and then \c" 1050Sstevel@tonic-gate fi 1060Sstevel@tonic-gate if [ $result = 0 ] ; then 1070Sstevel@tonic-gate echo "changing the /etc/hosts entry:\n" 1080Sstevel@tonic-gate echo "$myipaddr $myhost $*\n" 1090Sstevel@tonic-gate echo "to:\n" 1100Sstevel@tonic-gate else 1110Sstevel@tonic-gate echo "adding the /etc/hosts entry:\n" 1120Sstevel@tonic-gate fi 1130Sstevel@tonic-gate echo "$myipaddr $myhost $myhost.$suggested_domain $*" 1140Sstevel@tonic-gate exit 0 1150Sstevel@tonic-gate} 1160Sstevel@tonic-gate 117*11262SRajagopal.Andra@Sun.COM# Fall back to the NIS domain, minus the first label. If it is non-null, 1180Sstevel@tonic-gate# use it but recommend against it. $2 is just informative, indicating whether 119*11262SRajagopal.Andra@Sun.COM# we're checking the NIS domain. $3 is to pass on. 1200Sstevel@tonic-gate 1210Sstevel@tonic-gatecheck_nis_domain() { 1220Sstevel@tonic-gate nisdomain=`domainname` 1230Sstevel@tonic-gate realdomain=`echo $nisdomain | sed 's/[^.]*\.//'` 1240Sstevel@tonic-gate if [ "x$realdomain" != "x" ] ; then 1250Sstevel@tonic-gate echo "Hostname $1 can be fully qualified using NIS$2 domain" 1260Sstevel@tonic-gate echo " $nisdomain" 1270Sstevel@tonic-gate echo "resulting in the name" 1280Sstevel@tonic-gate echo " $1.$realdomain" 1290Sstevel@tonic-gate echo "but this is bad practice.\n" 1300Sstevel@tonic-gate suggest_fix_and_exit $1 $realdomain $3 1310Sstevel@tonic-gate fi 1320Sstevel@tonic-gate} 1330Sstevel@tonic-gate 1340Sstevel@tonic-gate# Goal: try to fully qualify `hostname` as sendmail would. 1350Sstevel@tonic-gate# Algorithm (stop as soon as a name with a dot is found): 1360Sstevel@tonic-gate# 1. gethostbyname (simulate with getent hosts) 1370Sstevel@tonic-gate# 2. fall back to individual hosts: methods in nsswitch.conf, using 1380Sstevel@tonic-gate# only those that are configured, in their configured order 1390Sstevel@tonic-gate# * files (parse /etc/hosts directly) 1400Sstevel@tonic-gate# * dns (parse nslookup output) 1410Sstevel@tonic-gate# * nis (parse ypmatch output) 142*11262SRajagopal.Andra@Sun.COM# 3. fall back to the NIS domain name. 1430Sstevel@tonic-gate# If none of the above succeed, give up. Recommend: 1440Sstevel@tonic-gate# a. the domain entry in /etc/resolv.conf, if one exists 1450Sstevel@tonic-gate# b. "pick.some.domain" 1460Sstevel@tonic-gate 1470Sstevel@tonic-gatemyhostname=`hostname` 1480Sstevel@tonic-gate 1490Sstevel@tonic-gatecheck_gethostbyname $myhostname 1500Sstevel@tonic-gate 1510Sstevel@tonic-gatehosts_line=`sed -n -e 's/^hosts:\([^#]*\).*/\1/p' /etc/nsswitch.conf` 1520Sstevel@tonic-gatefirst_hosts_entry=`echo $hosts_line | awk '{print $1}'` 1530Sstevel@tonic-gatenis_domains="" 1540Sstevel@tonic-gate 1550Sstevel@tonic-gatefor entry in $hosts_line 1560Sstevel@tonic-gatedo 1570Sstevel@tonic-gate case $entry in 1580Sstevel@tonic-gate files) 1590Sstevel@tonic-gate check_hosts_file $myhostname 1600Sstevel@tonic-gate ;; 1610Sstevel@tonic-gate dns) 1620Sstevel@tonic-gate check_dns $myhostname 1630Sstevel@tonic-gate ;; 1640Sstevel@tonic-gate nis) 1650Sstevel@tonic-gate check_nis $myhostname 1660Sstevel@tonic-gate nis_domains="$nis_domains nis" 1670Sstevel@tonic-gate ;; 1680Sstevel@tonic-gate esac 1690Sstevel@tonic-gatedone 1700Sstevel@tonic-gate 1710Sstevel@tonic-gatefor entry in $nis_domains 1720Sstevel@tonic-gatedo 1730Sstevel@tonic-gate case $entry in 1740Sstevel@tonic-gate nis) 1750Sstevel@tonic-gate check_nis_domain $myhostname "" $first_hosts_entry 1760Sstevel@tonic-gate ;; 1770Sstevel@tonic-gate esac 1780Sstevel@tonic-gatedone 1790Sstevel@tonic-gate 1800Sstevel@tonic-gaterealdomain=`awk '$1 ~ /^domain/ {print $2}' 2>/dev/null < /etc/resolv.conf` 1810Sstevel@tonic-gatecase $realdomain in 1820Sstevel@tonic-gate*.*) 1830Sstevel@tonic-gate # OK 1840Sstevel@tonic-gate ;; 1850Sstevel@tonic-gate*) 1860Sstevel@tonic-gate realdomain="pick.some.domain" 1870Sstevel@tonic-gate ;; 1880Sstevel@tonic-gateesac 1890Sstevel@tonic-gate 1900Sstevel@tonic-gateecho "Hostname $myhostname could not be fully qualified." 1910Sstevel@tonic-gatesuggest_fix_and_exit $myhostname $realdomain $first_hosts_entry 192