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