1*0Sstevel@tonic-gate#!/usr/bin/ksh
2*0Sstevel@tonic-gate#
3*0Sstevel@tonic-gate# ident	"%Z%%M%	%I%	%E% SMI"
4*0Sstevel@tonic-gate#
5*0Sstevel@tonic-gate# Copyright (c) 1997-2001 by Sun Microsystems, Inc.
6*0Sstevel@tonic-gate# All rights reserved.
7*0Sstevel@tonic-gate#
8*0Sstevel@tonic-gate#
9*0Sstevel@tonic-gate# This script sets up a virtual FTP host.
10*0Sstevel@tonic-gate#
11*0Sstevel@tonic-gate# Usage:
12*0Sstevel@tonic-gate#	ftpaddhost -c|-l [-b] [ -x xferlog ] hostname root_dir
13*0Sstevel@tonic-gate#
14*0Sstevel@tonic-gate# ftpaddhost configures virtual host hostname under directory root_dir.
15*0Sstevel@tonic-gate# An IP address can be used for hostname.
16*0Sstevel@tonic-gate#
17*0Sstevel@tonic-gate# The -c (complete) option configures complete virtual hosting, which allows
18*0Sstevel@tonic-gate# each virtual host to have its own version of the ftpaccess, ftpconversions,
19*0Sstevel@tonic-gate# ftpgroups, ftphosts and ftpusers files. The master version of each of these
20*0Sstevel@tonic-gate# configuration files is copied from the /etc/ftpd directory and placed in
21*0Sstevel@tonic-gate# the /etc/ftpd/virtual-ftpd/hostname directory. If the /etc/ftpusers file
22*0Sstevel@tonic-gate# exists it is appended to the virtual ftpusers file. If a virtual host lacks
23*0Sstevel@tonic-gate# its own version of a configuration file, the master version is used.
24*0Sstevel@tonic-gate#
25*0Sstevel@tonic-gate# The -l (limited) option configures limited virtual hosting, which only
26*0Sstevel@tonic-gate# allows a small number of parameters to be configured differently for a
27*0Sstevel@tonic-gate# virtual host (see the virtual keyword on the ftpaccess(4) manual page).
28*0Sstevel@tonic-gate#
29*0Sstevel@tonic-gate# When the -b (banner) option is supplied, ftpaddhost creates a banner for
30*0Sstevel@tonic-gate# the virtual host, useful to see that the virtual host is working.
31*0Sstevel@tonic-gate#
32*0Sstevel@tonic-gate# When the -x xferlog option is supplied, ftpaddhost creates a logfile entry
33*0Sstevel@tonic-gate# which causes the transfer logs for the virtual host to be written to the
34*0Sstevel@tonic-gate# specified file.
35*0Sstevel@tonic-gate#
36*0Sstevel@tonic-gate# Exit codes:	0 - success
37*0Sstevel@tonic-gate#		1 - usage
38*0Sstevel@tonic-gate#		2 - command failure
39*0Sstevel@tonic-gate#
40*0Sstevel@tonic-gate
41*0Sstevel@tonic-gateusage()
42*0Sstevel@tonic-gate{
43*0Sstevel@tonic-gate	fmt=`gettext "Usage: %s -c|-l [-b] [ -x xferlog ] hostname root_dir"`
44*0Sstevel@tonic-gate	printf "$fmt\n" "$cmd" >&2
45*0Sstevel@tonic-gate	exit 1
46*0Sstevel@tonic-gate}
47*0Sstevel@tonic-gate
48*0Sstevel@tonic-gateverify_root()
49*0Sstevel@tonic-gate{
50*0Sstevel@tonic-gate	# Verify caller has a real user ID of 0.
51*0Sstevel@tonic-gate	set `id`
52*0Sstevel@tonic-gate	if [ "$1" != "uid=0(root)" ]
53*0Sstevel@tonic-gate	then
54*0Sstevel@tonic-gate		fmt=`gettext "%s: Error: Only root can run %s"`
55*0Sstevel@tonic-gate		printf "$fmt\n" "$cmd" "$cmd" >&2
56*0Sstevel@tonic-gate		exit 1
57*0Sstevel@tonic-gate	fi
58*0Sstevel@tonic-gate}
59*0Sstevel@tonic-gate
60*0Sstevel@tonic-gate# Make directory $1 with mode $2 and ownership $3.
61*0Sstevel@tonic-gatemake_dir()
62*0Sstevel@tonic-gate{
63*0Sstevel@tonic-gate	if [ ! -d "$1" ]
64*0Sstevel@tonic-gate	then
65*0Sstevel@tonic-gate		mkdir "$1" || exit 2
66*0Sstevel@tonic-gate	fi
67*0Sstevel@tonic-gate	chmod "$2" "$1"
68*0Sstevel@tonic-gate	chown "$3" "$1"
69*0Sstevel@tonic-gate}
70*0Sstevel@tonic-gate
71*0Sstevel@tonic-gatesetup_complete_vhost()
72*0Sstevel@tonic-gate{
73*0Sstevel@tonic-gate	fmt=`gettext "Setting up complete virtual host %s"`
74*0Sstevel@tonic-gate	printf "$fmt\n" "$hostname"
75*0Sstevel@tonic-gate	make_dir /etc/ftpd/virtual-ftpd 755 root:sys
76*0Sstevel@tonic-gate	make_dir "/etc/ftpd/virtual-ftpd/$hostname" 755 root:sys
77*0Sstevel@tonic-gate
78*0Sstevel@tonic-gate	fmt=`gettext "Configuration directory is %s"`
79*0Sstevel@tonic-gate	printf "$fmt\n" "/etc/ftpd/virtual-ftpd/$hostname"
80*0Sstevel@tonic-gate
81*0Sstevel@tonic-gate	# Update the virtual host configuration file.
82*0Sstevel@tonic-gate	vhconfig=/etc/ftpd/ftpservers
83*0Sstevel@tonic-gate
84*0Sstevel@tonic-gate	fmt=`gettext "Updating virtual hosting configuration file %s"`
85*0Sstevel@tonic-gate	printf "$fmt\n" $vhconfig
86*0Sstevel@tonic-gate	if [ -f $vhconfig ]
87*0Sstevel@tonic-gate	then
88*0Sstevel@tonic-gate		# Remove any existing entries for the virtual host.
89*0Sstevel@tonic-gate		sed "/^[ 	]*$hostname[ 	]/d" $vhconfig >$vhconfig.tmp.$$
90*0Sstevel@tonic-gate		mv -f $vhconfig.tmp.$$ $vhconfig || exit 2
91*0Sstevel@tonic-gate	fi
92*0Sstevel@tonic-gate
93*0Sstevel@tonic-gate	echo "$hostname /etc/ftpd/virtual-ftpd/$hostname" >>$vhconfig
94*0Sstevel@tonic-gate	chmod 644 $vhconfig
95*0Sstevel@tonic-gate	chown root:sys $vhconfig
96*0Sstevel@tonic-gate
97*0Sstevel@tonic-gate	# Make copies of the master configuration files.
98*0Sstevel@tonic-gate	for file in ftpconversions ftpgroups ftphosts ftpusers
99*0Sstevel@tonic-gate	do
100*0Sstevel@tonic-gate		target="/etc/ftpd/virtual-ftpd/$hostname/$file"
101*0Sstevel@tonic-gate		rm -f "$target"
102*0Sstevel@tonic-gate		if [ -f /etc/ftpd/$file ]
103*0Sstevel@tonic-gate		then
104*0Sstevel@tonic-gate			cp /etc/ftpd/$file "$target" || exit 2
105*0Sstevel@tonic-gate			chmod 644 "$target"
106*0Sstevel@tonic-gate			chown root:sys "$target"
107*0Sstevel@tonic-gate		fi
108*0Sstevel@tonic-gate	done
109*0Sstevel@tonic-gate
110*0Sstevel@tonic-gate	# Append /etc/ftpusers to the virtual hosts ftpusers.
111*0Sstevel@tonic-gate	if [ -f /etc/ftpusers ]
112*0Sstevel@tonic-gate	then
113*0Sstevel@tonic-gate		target="/etc/ftpd/virtual-ftpd/$hostname/ftpusers"
114*0Sstevel@tonic-gate		cat /etc/ftpusers >>"$target"
115*0Sstevel@tonic-gate		chmod 644 "$target"
116*0Sstevel@tonic-gate		chown root:sys "$target"
117*0Sstevel@tonic-gate	fi
118*0Sstevel@tonic-gate
119*0Sstevel@tonic-gate	vhftpaccess="/etc/ftpd/virtual-ftpd/$hostname/ftpaccess"
120*0Sstevel@tonic-gate	rm -f "$vhftpaccess"
121*0Sstevel@tonic-gate
122*0Sstevel@tonic-gate	# Remove any existing root or logfile entries.
123*0Sstevel@tonic-gate	sed "/^[ 	]*root[ 	]/d
124*0Sstevel@tonic-gate	     /^[ 	]*logfile[ 	]/d" $ftpaccess >"$vhftpaccess"
125*0Sstevel@tonic-gate
126*0Sstevel@tonic-gate	# Add the virtual host root.
127*0Sstevel@tonic-gate	echo "root $vhroot" >>"$vhftpaccess"
128*0Sstevel@tonic-gate
129*0Sstevel@tonic-gate	# Add a banner to show the virtual host configuration worked.
130*0Sstevel@tonic-gate	if [ -n "$banner" ]
131*0Sstevel@tonic-gate	then
132*0Sstevel@tonic-gate		# Add a banner entry if there isn't already one.
133*0Sstevel@tonic-gate		grep "^[ 	]*banner[ 	]" "$vhftpaccess" >/dev/null 2>&1
134*0Sstevel@tonic-gate		if [ $? -eq 0 ]
135*0Sstevel@tonic-gate		then
136*0Sstevel@tonic-gate			fmt=`gettext "Existing banner entry not changed in %s"`
137*0Sstevel@tonic-gate			printf "$fmt\n" "$vhftpaccess"
138*0Sstevel@tonic-gate		else
139*0Sstevel@tonic-gate			bannerf="/etc/ftpd/virtual-ftpd/$hostname/cbanner.msg"
140*0Sstevel@tonic-gate			if [ -f "$bannerf" ]
141*0Sstevel@tonic-gate			then
142*0Sstevel@tonic-gate				fmt=`gettext "Using existing banner file %s"`
143*0Sstevel@tonic-gate				printf "$fmt\n" "$bannerf"
144*0Sstevel@tonic-gate			else
145*0Sstevel@tonic-gate				fmt=`gettext "Creating banner file %s"`
146*0Sstevel@tonic-gate				printf "$fmt\n" "$bannerf"
147*0Sstevel@tonic-gate				fmt=`gettext "Complete virtual host %%L test banner"`
148*0Sstevel@tonic-gate				printf "$fmt\n" >"$bannerf"
149*0Sstevel@tonic-gate				chmod 644 "$bannerf"
150*0Sstevel@tonic-gate				chown root:sys "$bannerf"
151*0Sstevel@tonic-gate			fi
152*0Sstevel@tonic-gate			echo "banner $bannerf" >>"$vhftpaccess"
153*0Sstevel@tonic-gate		fi
154*0Sstevel@tonic-gate	fi
155*0Sstevel@tonic-gate
156*0Sstevel@tonic-gate	# Add the transfer logfile.
157*0Sstevel@tonic-gate	if [ -n "$logfile" ]
158*0Sstevel@tonic-gate	then
159*0Sstevel@tonic-gate		echo "logfile $logfile" >>"$vhftpaccess"
160*0Sstevel@tonic-gate	fi
161*0Sstevel@tonic-gate
162*0Sstevel@tonic-gate	chmod 644 "$vhftpaccess"
163*0Sstevel@tonic-gate	chown root:sys "$vhftpaccess"
164*0Sstevel@tonic-gate}
165*0Sstevel@tonic-gate
166*0Sstevel@tonic-gatesetup_limited_vhost()
167*0Sstevel@tonic-gate{
168*0Sstevel@tonic-gate	# Check complete virtual hosting is not configured for the host.
169*0Sstevel@tonic-gate	grep "^[ 	]*$hostname[ 	]" /etc/ftpd/ftpservers >/dev/null 2>&1
170*0Sstevel@tonic-gate	if [ $? -eq 0 ]
171*0Sstevel@tonic-gate	then
172*0Sstevel@tonic-gate		fmt=`gettext "%s: Error: Complete virtual hosting already configured for %s"`
173*0Sstevel@tonic-gate		printf "$fmt\n" "$cmd" "$hostname" >&2
174*0Sstevel@tonic-gate		exit 1
175*0Sstevel@tonic-gate	fi
176*0Sstevel@tonic-gate
177*0Sstevel@tonic-gate	fmt=`gettext "Setting up limited virtual host %s"`
178*0Sstevel@tonic-gate	printf "$fmt\n" "$hostname"
179*0Sstevel@tonic-gate
180*0Sstevel@tonic-gate	# Update the ftpaccess file.
181*0Sstevel@tonic-gate	fmt=`gettext "Updating FTP server configuration file %s"`
182*0Sstevel@tonic-gate	printf "$fmt\n" $ftpaccess
183*0Sstevel@tonic-gate
184*0Sstevel@tonic-gate	# Remove any existing entries for the virtual host.
185*0Sstevel@tonic-gate	sed "/^[ 	]*virtual[ 	][ 	]*$hostname[ 	]/d" $ftpaccess >$ftpaccess.tmp.$$
186*0Sstevel@tonic-gate	mv -f $ftpaccess.tmp.$$ $ftpaccess || exit 2
187*0Sstevel@tonic-gate
188*0Sstevel@tonic-gate	# Add a limited virtual hosting entry for the virtual host.
189*0Sstevel@tonic-gate	echo "virtual $hostname root $vhroot" >>$ftpaccess
190*0Sstevel@tonic-gate
191*0Sstevel@tonic-gate	# Add a banner to show the virtual host configuration worked.
192*0Sstevel@tonic-gate	if [ -n "$banner" ]
193*0Sstevel@tonic-gate	then
194*0Sstevel@tonic-gate		bannerf="/etc/ftpd/virtual-ftpd/$hostname/lbanner.msg"
195*0Sstevel@tonic-gate		if [ -f "$bannerf" ]
196*0Sstevel@tonic-gate		then
197*0Sstevel@tonic-gate			fmt=`gettext "Using existing banner file %s"`
198*0Sstevel@tonic-gate			printf "$fmt\n" "$bannerf"
199*0Sstevel@tonic-gate		else
200*0Sstevel@tonic-gate			fmt=`gettext "Creating banner file %s"`
201*0Sstevel@tonic-gate			printf "$fmt\n" "$bannerf"
202*0Sstevel@tonic-gate			make_dir /etc/ftpd/virtual-ftpd 755 root:sys
203*0Sstevel@tonic-gate			make_dir "/etc/ftpd/virtual-ftpd/$hostname" 755 root:sys
204*0Sstevel@tonic-gate			fmt=`gettext "Limited virtual host %%L test banner"`
205*0Sstevel@tonic-gate			printf "$fmt\n" >"$bannerf"
206*0Sstevel@tonic-gate			chmod 644 "$bannerf"
207*0Sstevel@tonic-gate			chown root:sys "$bannerf"
208*0Sstevel@tonic-gate		fi
209*0Sstevel@tonic-gate		echo "virtual $hostname banner $bannerf" >>$ftpaccess
210*0Sstevel@tonic-gate	fi
211*0Sstevel@tonic-gate
212*0Sstevel@tonic-gate	# Add the transfer logfile.
213*0Sstevel@tonic-gate	if [ -n "$logfile" ]
214*0Sstevel@tonic-gate	then
215*0Sstevel@tonic-gate		echo "virtual $hostname logfile $logfile" >>$ftpaccess
216*0Sstevel@tonic-gate	fi
217*0Sstevel@tonic-gate
218*0Sstevel@tonic-gate	chmod 644 $ftpaccess
219*0Sstevel@tonic-gate	chown root:sys $ftpaccess
220*0Sstevel@tonic-gate}
221*0Sstevel@tonic-gate
222*0Sstevel@tonic-gate# Execution starts here.
223*0Sstevel@tonic-gate
224*0Sstevel@tonic-gateIFS="
225*0Sstevel@tonic-gate"
226*0Sstevel@tonic-gateSHELL=/usr/bin/ksh
227*0Sstevel@tonic-gatePATH=/usr/bin
228*0Sstevel@tonic-gateTEXTDOMAIN=SUNW_OST_OSCMD
229*0Sstevel@tonic-gateexport SHELL PATH IFS TEXTDOMAIN
230*0Sstevel@tonic-gate
231*0Sstevel@tonic-gatecmd=`basename "$0"`
232*0Sstevel@tonic-gate
233*0Sstevel@tonic-gateverify_root
234*0Sstevel@tonic-gate
235*0Sstevel@tonic-gatewhile getopts bclx: arg
236*0Sstevel@tonic-gatedo
237*0Sstevel@tonic-gate	case $arg in
238*0Sstevel@tonic-gate	b)	banner=1;;
239*0Sstevel@tonic-gate	c)	complete=1;;
240*0Sstevel@tonic-gate	l)	limited=1;;
241*0Sstevel@tonic-gate	x)	logfile="$OPTARG";;
242*0Sstevel@tonic-gate	\?)	usage;;
243*0Sstevel@tonic-gate	esac
244*0Sstevel@tonic-gatedone
245*0Sstevel@tonic-gateshift `expr $OPTIND - 1`
246*0Sstevel@tonic-gate
247*0Sstevel@tonic-gate# Check arguments.
248*0Sstevel@tonic-gate[ -z "$complete" -a -z "$limited" ] && usage
249*0Sstevel@tonic-gate[ -n "$complete" -a -n "$limited" ] && usage
250*0Sstevel@tonic-gate
251*0Sstevel@tonic-gate[ $# -ne 2 ] && usage
252*0Sstevel@tonic-gatehostname="$1"
253*0Sstevel@tonic-gatevhroot="$2"
254*0Sstevel@tonic-gate
255*0Sstevel@tonic-gate[ -z "$hostname" -o -z "$vhroot" ] && usage
256*0Sstevel@tonic-gate
257*0Sstevel@tonic-gateecho "$hostname" | grep / >/dev/null 2>&1
258*0Sstevel@tonic-gateif [ $? -eq 0 ]
259*0Sstevel@tonic-gatethen
260*0Sstevel@tonic-gate	fmt=`gettext "%s: Error: hostname must not contain a /"`
261*0Sstevel@tonic-gate	printf "$fmt\n" "$cmd" >&2
262*0Sstevel@tonic-gate	usage
263*0Sstevel@tonic-gatefi
264*0Sstevel@tonic-gate
265*0Sstevel@tonic-gateecho "$vhroot" | grep "^/" >/dev/null 2>&1
266*0Sstevel@tonic-gateif [ $? -ne 0 ]
267*0Sstevel@tonic-gatethen
268*0Sstevel@tonic-gate	fmt=`gettext "%s: Error: root_dir must be an absolute pathname"`
269*0Sstevel@tonic-gate	printf "$fmt\n" "$cmd" >&2
270*0Sstevel@tonic-gate	usage
271*0Sstevel@tonic-gatefi
272*0Sstevel@tonic-gate
273*0Sstevel@tonic-gateif [ -n "$logfile" ]
274*0Sstevel@tonic-gatethen
275*0Sstevel@tonic-gate	echo "$logfile" | grep "^/" >/dev/null 2>&1
276*0Sstevel@tonic-gate	if [ $? -ne 0 ]
277*0Sstevel@tonic-gate	then
278*0Sstevel@tonic-gate		fmt=`gettext "%s: Error: xferlog must be an absolute pathname"`
279*0Sstevel@tonic-gate		printf "$fmt\n" "$cmd" >&2
280*0Sstevel@tonic-gate		usage
281*0Sstevel@tonic-gate	fi
282*0Sstevel@tonic-gatefi
283*0Sstevel@tonic-gate
284*0Sstevel@tonic-gateftpaccess=/etc/ftpd/ftpaccess
285*0Sstevel@tonic-gateif [ ! -f $ftpaccess ]
286*0Sstevel@tonic-gatethen
287*0Sstevel@tonic-gate	fmt=`gettext "%s: Error: FTP server configuration file %s missing"`
288*0Sstevel@tonic-gate	printf "$fmt\n" "$cmd" $ftpaccess >&2
289*0Sstevel@tonic-gate	exit 2
290*0Sstevel@tonic-gatefi
291*0Sstevel@tonic-gate
292*0Sstevel@tonic-gategrep "^ftp:" /etc/passwd >/dev/null 2>&1
293*0Sstevel@tonic-gateif [ $? -ne 0 ]
294*0Sstevel@tonic-gatethen
295*0Sstevel@tonic-gate	fmt=`gettext "Warning: Must create ftp user account before virtual hosts will work"`
296*0Sstevel@tonic-gate	printf "$fmt\n"
297*0Sstevel@tonic-gatefi
298*0Sstevel@tonic-gate
299*0Sstevel@tonic-gate# Ignore certain signals.
300*0Sstevel@tonic-gatetrap '' 1 2 3 15
301*0Sstevel@tonic-gate
302*0Sstevel@tonic-gateumask 022
303*0Sstevel@tonic-gate
304*0Sstevel@tonic-gateif [ -n "$complete" ]
305*0Sstevel@tonic-gatethen
306*0Sstevel@tonic-gate	setup_complete_vhost
307*0Sstevel@tonic-gateelse
308*0Sstevel@tonic-gate	setup_limited_vhost
309*0Sstevel@tonic-gatefi
310*0Sstevel@tonic-gate
311*0Sstevel@tonic-gate/usr/sbin/ftpconfig -d "$vhroot" >/dev/null
312*0Sstevel@tonic-gateif [ $? -ne 0 ]
313*0Sstevel@tonic-gatethen
314*0Sstevel@tonic-gate	fmt=`gettext "%s: Error: ftpconfig -d %s failed"`
315*0Sstevel@tonic-gate	printf "$fmt\n" "$cmd" "$vhroot" >&2
316*0Sstevel@tonic-gate	exit 2
317*0Sstevel@tonic-gatefi
318*0Sstevel@tonic-gate
319*0Sstevel@tonic-gateexit 0
320