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