|
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 |