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