Home | History | Annotate | Download | only in in.ftpd
      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 
     41 usage()
     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 
     48 verify_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.
     61 make_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 
     71 setup_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 
    166 setup_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 
    224 IFS=" 	
    225 "
    226 SHELL=/usr/bin/ksh
    227 PATH=/usr/bin
    228 TEXTDOMAIN=SUNW_OST_OSCMD
    229 export SHELL PATH IFS TEXTDOMAIN
    230 
    231 cmd=`basename "$0"`
    232 
    233 verify_root
    234 
    235 while getopts bclx: arg
    236 do
    237 	case $arg in
    238 	b)	banner=1;;
    239 	c)	complete=1;;
    240 	l)	limited=1;;
    241 	x)	logfile="$OPTARG";;
    242 	\?)	usage;;
    243 	esac
    244 done
    245 shift `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
    252 hostname="$1"
    253 vhroot="$2"
    254 
    255 [ -z "$hostname" -o -z "$vhroot" ] && usage
    256 
    257 echo "$hostname" | grep / >/dev/null 2>&1
    258 if [ $? -eq 0 ]
    259 then
    260 	fmt=`gettext "%s: Error: hostname must not contain a /"`
    261 	printf "$fmt\n" "$cmd" >&2
    262 	usage
    263 fi
    264 
    265 echo "$vhroot" | grep "^/" >/dev/null 2>&1
    266 if [ $? -ne 0 ]
    267 then
    268 	fmt=`gettext "%s: Error: root_dir must be an absolute pathname"`
    269 	printf "$fmt\n" "$cmd" >&2
    270 	usage
    271 fi
    272 
    273 if [ -n "$logfile" ]
    274 then
    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
    282 fi
    283 
    284 ftpaccess=/etc/ftpd/ftpaccess
    285 if [ ! -f $ftpaccess ]
    286 then
    287 	fmt=`gettext "%s: Error: FTP server configuration file %s missing"`
    288 	printf "$fmt\n" "$cmd" $ftpaccess >&2
    289 	exit 2
    290 fi
    291 
    292 grep "^ftp:" /etc/passwd >/dev/null 2>&1
    293 if [ $? -ne 0 ]
    294 then
    295 	fmt=`gettext "Warning: Must create ftp user account before virtual hosts will work"`
    296 	printf "$fmt\n"
    297 fi
    298 
    299 # Ignore certain signals.
    300 trap '' 1 2 3 15
    301 
    302 umask 022
    303 
    304 if [ -n "$complete" ]
    305 then
    306 	setup_complete_vhost
    307 else
    308 	setup_limited_vhost
    309 fi
    310 
    311 /usr/sbin/ftpconfig -d "$vhroot" >/dev/null
    312 if [ $? -ne 0 ]
    313 then
    314 	fmt=`gettext "%s: Error: ftpconfig -d %s failed"`
    315 	printf "$fmt\n" "$cmd" "$vhroot" >&2
    316 	exit 2
    317 fi
    318 
    319 exit 0
    320