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