xref: /freebsd/usr.sbin/bsdconfig/networking/share/hostname.subr (revision 25408c853d9ecb2e76b9e38407338f86ecb8a55c)
1if [ ! "$_NETWORKING_HOSTNAME_SUBR" ]; then _NETWORKING_HOSTNAME_SUBR=1
2#
3# Copyright (c) 2006-2012 Devin Teske
4# All Rights Reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD$
28#
29############################################################ INCLUDES
30
31BSDCFG_SHARE="/usr/share/bsdconfig"
32. $BSDCFG_SHARE/common.subr || exit 1
33f_include $BSDCFG_SHARE/sysrc.subr
34f_include $BSDCFG_SHARE/dialog.subr
35f_include $BSDCFG_SHARE/networking/common.subr
36f_include $BSDCFG_SHARE/networking/resolv.subr
37
38BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="120.networking"
39f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
40
41############################################################ FUNCTIONS
42
43# f_dialog_validate_hostname $hostname
44#
45# Returns zero if the given argument (a fully-qualified hostname) is compliant
46# with standards set-forth in RFC's 952 and 1123 of the Network Working Group:
47#
48# RFC 952 - DoD Internet host table specification
49# http://tools.ietf.org/html/rfc952
50#
51# RFC 1123 - Requirements for Internet Hosts - Application and Support
52# http://tools.ietf.org/html/rfc1123
53#
54# See http://en.wikipedia.org/wiki/Hostname for a brief overview.
55#
56# The return status for invalid hostnames is one of:
57# 	255	Entire hostname exceeds the maximum length of 255 characters.
58# 	 63	One or more individual labels within the hostname (separated by
59# 	   	dots) exceeds the maximum of 63 characters.
60# 	  1	One or more individual labels within the hostname contains one
61# 	   	or more invalid characters.
62# 	  2	One or more individual labels within the hostname starts or
63# 	   	ends with a hyphen (hyphens are allowed, but a label cannot
64# 	   	begin or end with a hyphen).
65# 	  3	One or more individual labels within the hostname are null.
66#
67# If the hostname is determined to be invalid, the appropriate error will be
68# displayed using the f_dialog_msgbox function.
69#
70f_dialog_validate_hostname()
71{
72	local fqhn="$1"
73
74	( # Operate within a sub-shell to protect the parent environment
75
76		# Return error if the hostname exceeds 255 characters
77		[ ${#fqhn} -gt 255 ] && exit 255
78
79		IFS="." # Split on `dot'
80		for label in $fqhn; do
81
82			# Return error if the label exceeds 63 characters
83			[ ${#label} -gt 63 ] && exit 63
84
85			# Return error if the label is null
86			[ "$label" ] || exit 3
87
88			# Return error if label begins/ends with dash
89			case "$label" in
90			-*|*-) exit 2
91			esac
92
93			# Return error if the label contains any invalid chars
94			echo "$label" | grep -q '^[[:alnum:]-]*$' || exit 1
95
96		done
97	)
98
99	#
100	# Produce an appropriate error message if necessary.
101	#
102	local retval=$?
103	case $retval in
104	1) f_dialog_msgbox "$( printf \
105		"$msg_hostname_label_contains_invalid_chars" "$fqhn" )";;
106	2) f_dialog_msgbox "$( printf \
107		"$msg_hostname_label_starts_or_ends_with_hyphen" "$fqhn" )";;
108	3) f_dialog_msgbox "$( printf \
109		"$msg_hostname_label_is_null" "$fqhn" )";;
110	63) f_dialog_msgbox "$( printf \
111		"$msg_hostname_label_exceeds_max_length" "$fqhn" )";;
112	255) f_dialog_msgbox "$( printf \
113		"$msg_hostname_exceeds_max_length" "$fqhn" )";;
114	esac
115
116	return $retval
117}
118
119# f_dialog_input_hostname
120#
121# Edits the current hostname.
122#
123f_dialog_input_hostname()
124{
125	local hostname="$( f_sysrc_get 'hostname:-$(hostname)' )"
126	local hostname_orig="$hostname" # for change-tracking
127
128	local msg
129	if [ "$USE_XDIALOG" ]; then
130		msg="$xmsg_please_enter_fqhn"
131	else
132		msg="$msg_please_enter_fqhn"
133	fi
134
135	local hline="$hline_alnum_punc_tab_enter"
136
137	#
138	# Loop until the user provides taint-free input.
139	#
140	local size height width
141	while :; do
142
143		size=$( f_dialog_inputbox_size \
144		         	"$DIALOG_TITLE"     \
145		         	"$DIALOG_BACKTITLE" \
146		         	"$msg"              \
147		         	"$hostname"         \
148		         	"$hline"            )
149		local dialog_inputbox
150		dialog_inputbox=$( eval $DIALOG \
151			--title \"\$DIALOG_TITLE\"         \
152			--backtitle \"\$DIALOG_BACKTITLE\" \
153			--hline \"\$hline\"                \
154			--ok-label \"\$msg_ok\"            \
155			--cancel-label \"\$msg_cancel\"    \
156			--inputbox \"\$msg\" $size         \
157			\"\$hostname\"                     \
158			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
159		)
160
161		local retval=$?
162		setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox"
163		hostname=$( f_dialog_inputstr )
164
165		[ $retval -eq $SUCCESS ] || return $retval
166
167		# Taint-check the user's input
168		f_dialog_validate_hostname "$hostname" && break
169
170	done
171
172	#
173	# Save hostname only if the user changed the hostname.
174	#
175	if [ "$hostname" != "$hostname_orig" ]; then
176		f_dialog_info "$msg_saving_hostname"
177		f_sysrc_set hostname "$hostname"
178	fi
179
180	#
181	# Update resolv.conf(5) search/domain directives
182	#
183	f_dialog_resolv_conf_update "$hostname"
184
185	#
186	# Only ask to apply setting if the current hostname is different than
187	# the stored configuration (in rc.conf(5)).
188	#
189	if [ "$( hostname )" != "$( f_sysrc_get hostname )" ]; then
190		[ ! "$USE_XDIALOG" ] && dialog_clear
191
192		#
193		# If connected via ssh(1) and performing X11-Forwarding, don't
194		# allow the hostname to be changed to prevent the fatal error
195		# "X11 connection rejected because of wrong authentication."
196		#
197		if [ "$USE_XDIALOG" -a "$SSH_CONNECTION" ]; then
198			f_dialog_msgbox "$(
199				printf "$msg_activate_hostname_x11warning" \
200				       "$( hostname )" "$hostname"
201			)"
202		else
203			f_dialog_yesno "$(
204				printf "$msg_activate_hostname" \
205				       "$( hostname )" "$hostname" \
206			)" \
207			&& hostname "$hostname"
208		fi
209	fi
210
211	return $SUCCESS
212}
213
214fi # ! $_NETWORKING_HOSTNAME_SUBR
215