svrs:ftp configuration 

invocation 

If the -l option is specified, each ftp session is logged in the syslog.

If the -a option is specified, the use of the ftpaccess(5) configuration file is enabled.

If the -i option is specified, files received by the ftpd(8) server will be logged to the xferlog(5). The -i option is overridden by the use of the ftpaccess(5) file.

Port 

Taken from:

Testing on a different port number than ftp:21
http://www.wu-ftpd.org/wu-ftpd-faq.html#IDX38

This can be done from the command line or with a special definition in /etc/services / /etc/inetd.conf. For command-line, look up -P and -p in the ftpaccess(5) manpage.

To set up with special definitions, add 2 ports with consecutive numbers in /etc/services, and then start WU-FTPD on these ports. Add to /etc/services something like :

ftptest         4021/tcp        #command port
ftptest-data    4020/tcp        #data port

Then start WU-FTPD from /etc/inetd.conf like :

ftptest stream tcp nowait root /usr/etc/in.ftpd in.ftpd

The key is the name 'ftptest' which associates the port assignment in the /etc/services file to that in the inetd.conf file.

Make certain the choice of ports in /etc/services (4021 and 4020 above) are from the local use list and don't conflict with other port assignments (see RFC1700, ASSIGNED NUMBERS). One important subtlety. The data port is not really derived from the data port declaration in the /etc/services file. The FTP specification (RFC765) states the data port is defined as one less than the command port. However, including the data port declaration in the /etc/services file prevents it from being accidentally assigned to something else.

anonymous ftp 

http://www.wu-ftpd.org/HOWTO/upload.configuration.HOWTO

If your /etc/passwd file does not contain an entry for the user 'ftp' your site will not allow anonymous FTP. In addition, if the usernames 'ftp' or 'anonymous' appear in the /etc/ftpusers file, anonymous FTP will not be allowed.

Messages 

Messages like

message                /etc/welcome.msg        login

are from root of ftp directory, not from root of file system!

cd /etc
lns /home/ftp/etc ftp

But banner is from root of file system, not from root of ftp directory!

banner         /home/ftp/msg/banner.msg

login greeting 

Symptom 

The greeting message no longer shows.

Conclusion 

Anonymous users have diferent banners, etc.
http://www.wu-ftpd.org/wu-ftpd-faq.html#IDX45

When the anonymous user is logged in, bannerfiles are opened relative to the root of the anonymous user. Keep this in mind. It can be usefull to have 2 sets of banners or use links.

% dir /etc/ftpaccess
lrwxrwxrwx    1 root     root           23 Aug 10 03:01 /etc/ftpaccess -> /home/ftp/msg/ftpaccess
% cd /home/ftp/msg
% dir
-rw-------    1 ftp      ftp            72 Aug 10 01:31 banner.msg
-rw-------    1 ftp      ftp          1787 Aug 10 03:06 ftpaccess
-rw-------    1 ftp      ftp            23 Aug  9 23:44 path.msg
-rw-------    1 ftp      ftp            47 Mar 14 14:50 shutdown.msg
-rw-------    1 ftp      ftp            44 Oct 31  2000 toomany.msg
-rw-------    1 ftp      ftp           203 Aug 10 02:28 welcome.msg

— have to be owned by ftp. chown to bin:bin won't work any more.

Analysis / Reason 

( echo user anonymous y@e.ca; echo cd win; echo cd inc:; echo cd tong; echo put file.sample.bin; echo bye; ) | ftp -vin localhost
message                /etc/ftp/welcome.msg    login
$ fpv /etc/ftp/welcome.msg
-rw-r--r--    1 ftp      ftp           202 Mar 14 17:57 /etc/ftp/welcome.msg
lrwxrwxrwx    1 root     root           15 Aug 10 00:07 /etc/ftp -> ../home/ftp/etc/
drwxr-xr-x   36 root     root         4096 Aug 10 01:41 /etc/
% dirdir /home/ftp/etc/
d--x--x--x    2 ftp      ftp          4096 Aug 10 01:31 ../home/ftp/etc//
% chmod 755 /home/ftp/etc/
% dirdir /home/ftp/etc/
drwxr-xr-x    2 ftp      ftp          4096 Aug 10 01:31 ../home/ftp/etc//
lns /home/ftp/etc ftp
lns /export/home/ftp/etc ftp

— the same

Move all messages back to /etc/ftp.

cp /etc/ftp/welcome.msg /etc

and then

message                /etc/welcome.msg        login
#message               /etc/ftp/welcome.msg    login
message                /etc/welcome.msg        login
message                .message                cwd=*
message                /etc/ftp/welcome.msg    cwd=*

Nothing above can make it shown.

Reason: msg should be in the root of ftp directory.
[Tip]

!!

$ ftp -vin
ftp> open localhost
Connected to localhost.
220-    *******************
220-    * Tong's FTP site *
220-    *******************
220-
220 sunny FTP server (Version wu-2.6.0(1) Fri Jun 23 09:17:44 EDT 2000) ready.
ftp> user anonymous a@b.ca
331 Guest login ok, send your complete e-mail address as password.
230-
230-Hi, anonymous from localhost, Welcome to Tong's FTP site.
230-You are now in sunny/ at local time Fri Aug 10 03:18:50 2001
230-There are currently 1 of maximum 4 user logged on to this site.
230-Enjoy yourself here and feel free to contact me at root@sunny.
230-
230 Guest login ok, access restrictions apply.
ftp> cd inc:
250-                         *** GO AWAY ***
250- ...
250 CWD command successful.
ftp> bye
221-You have transferred 0 bytes in 0 files.
221-Total traffic for this session was 894 bytes in 0 transfers.
221-Thank you for using the FTP service on sunny.
221 Goodbye.

shutdown can be at both places 

shutdown /msg/shutdown.msg 
% grep '/msg/' /tmp/strace.out
8278  stat("/msg/shutdown.msg", 0xbfffd8c8) = -1 ENOENT (No such file or directory)
8278  open("/home/ftp/msg/banner.msg", O_RDONLY) = 5
8278  stat("/msg/shutdown.msg", 0xbfffc398) = -1 ENOENT (No such file or directory)
8278  stat("/msg/shutdown.msg", 0xbfffc398) = -1 ENOENT (No such file or directory)
8278  stat("/msg/shutdown.msg", 0xbfffc398) = -1 ENOENT (No such file or directory)
8278  open("/msg/welcome.msg", O_RDONLY) = 9
8278  stat("/msg/shutdown.msg", {st_mode=S_IFREG|0644, st_size=47, ...}) = 0
8278  open("/msg/shutdown.msg", O_RDONLY) = 9
8278  stat("/msg/shutdown.msg", {st_mode=S_IFREG|0644, st_size=47, ...}) = 0
8278  stat("/msg/shutdown.msg", {st_mode=S_IFREG|0644, st_size=47, ...}) = 0
shutdown /home/ftp/msg/shutdown.msg 
% grep '/msg/' /tmp/strace.out
8284  stat("/home/ftp/msg/shutdown.msg", {st_mode=S_IFREG|0644, st_size=47, ...}) = 0
8284  open("/home/ftp/msg/shutdown.msg", O_RDONLY) = 5
8284  open("/home/ftp/msg/banner.msg", O_RDONLY) = 5
8284  stat("/home/ftp/msg/shutdown.msg", {st_mode=S_IFREG|0644, st_size=47, ...}) = 0
8284  stat("/home/ftp/msg/shutdown.msg", {st_mode=S_IFREG|0644, st_size=47, ...}) = 0
8284  stat("/home/ftp/msg/shutdown.msg", {st_mode=S_IFREG|0644, st_size=47, ...}) = 0
8284  open("/msg/welcome.msg", O_RDONLY) = 9
8284  stat("/home/ftp/msg/shutdown.msg", 0xbfffbf74) = -1 ENOENT (No such file or directory)
8284  stat("/home/ftp/msg/shutdown.msg", 0xbfffc398) = -1 ENOENT (No such file or directory)
8284  stat("/home/ftp/msg/shutdown.msg", 0xbfffc398) = -1 ENOENT (No such file or directory)

So, within ftp is opened later, thus better

upload control 

Actions 

Settings 

upload    /home/ftp    /incoming       yes ftp crew 0660
upload    /home/ftp    /incoming/*     yes ftp crew 0660 nodirs
noretrieve /home/ftp/incoming

or

upload    relative /incoming *         yes ftp
noretrieve     relative        /incoming

Help sources 

man ftpaccess /usr/doc/wu-ftpd-2.6.0/HOWTO/upload.configuration.HOWTO ftp://ftp.wu-ftpd.org/pub/wu-ftpd/upload.configuration.HOWTO

Help Info 

Finally, before we get into allowing uploads, one last thing. Whether you allow on-the-fly tar'ing of directories or not, you should make sure an end-run cannot be made and the incoming area downloaded using tar. To do so, create the special file '.notar' in both the FTP directory and the incoming area:

touch /home/ftp/.notar
chmod 0 /home/ftp/.notar
touch /home/ftp/incoming/.notar
chmod 0 /home/ftp/incoming/.notar

The zero-length .notar file can confuse some web clients and FTP proxies, so let's mark it unretrievable.

noretrieve .notar

upload  [absolute|relative]  [class=<classname>]... [-] <root-dir>
<dirglob>           <yes|no> <owner> <group> <mode> ["dirs"|"nodirs"]
[<d_mode>]

Some FTP sites like to live dangerously and allow anonymous users to create directories. I don't recommend this; it cannot be done with absolute safety. If you insist, however, you can at least limit it to a single directory level. For example, replace the upload clause just added with the following:

upload /home/ftp /incoming   yes ftpadmin ftpadmin 0440 dirs 3773
upload /home/ftp /incoming/* yes ftpadmin ftpadmin 0440 nodirs

Directory creation is allowed by default for upload command. To turn it off by default, you must specify a user, group and mode followed by the "nodirs" keyword as the first line where the upload command is used in this file.

Notice one of the problems with allowing directory creation is there is no way to automatically create a '.notar' in the new directory, so a crafty user may be able to make an end-run and download it anyway using on-the-fly tar'ing.

For example, we can deny all uploads the remote guests except to their personal tmp directories:

upload class=remote /home/users/* *      no
upload class=remote /home/users/* /*/tmp yes nodirs
umask 
umask no  anonymous
umask yes real,guest

If, for example, you wanted to disable these commands for guests accessing the server from outside the local network, you could add the following:

chmod no  class=remote
umask no  class=remote

Private dirs 

we'll allow anonymous uploads into all private incoming areas:

upload /home/ftp            /private/*/incoming          yes * * 0640 dirs

The assumption here is Unix shell users have private areas in the anonymous site. Those areas are owned by the appropriate user, and incoming files are to be owned by that user. The wildcard match on directory allows anonymous uploading to any private incoming directory. The wildcard for owning user and group instructs the daemon to set the file's ownership to that of the directory receiving it.