ftpd

DARPA internet file transfer protocol daemon (UNIX)

Syntax:

ftpd [-AdHklru] [-a anondir] [-c confdir] 
     [-h hostname] [-V version]

Runs on:

Neutrino

Options:

-A
Allow clients to access non-regular files such as named special files under /dev/shmem. Use this option only when access to such files are necessary -- this may allow mallicious users to open any path on the system (for which they have appropriate file permissions) with undesired results.
-a anondir
Use this as the root directory ( chroot()) for anonymous logins. By default, the home directory of the ftp user is used.
-c confdir
Change the root directory of the configuration files from /etc to confdir.
-d
Write debugging info to the system log using LOG_FTP. In order to capture the log messages, you need to have syslogd running.
-H
Set the system's hostname (see gethostname()) as the hostname to advertise.
-h hostname
Set this hostname to advertise as the hostname. By default, the hostname associated with the IP address that ftpd listens on is used. The ability to advertise a hostname (either explicitly with -h, or implicitly by default), and change the root directory of a configuration file (see -c confdir) allows you to configure "virtual" FTP servers that can listen in on separate addresses as separate names. For more information about starting services to listen in on specific IP interfaces, see /etc/inetd.conf.
-k
Disable the keepalive (SO_KEEPALIVE) option on the ftpd sockets. By default, keepalive is on and messages are sent out on the data connection at least every two hours. If the client fails to respond, the connection is considered broken and is closed. The -k option disables this.

Note: The current npm-ttcpip.so doesn't support keepalive.

-l
Log each ftp session in the system log using LOG_FTP. If this option is specified twice, then include the retrieve (get), store (put), append, delete, make directory, remove directory and rename operations and their filename arguments in the log.
-r
Permanently drop root privileges when the user logs in. This may result in the server using a port other than the (listening-port - 1) for PORT style commands, which is contrary to the RFC 959 specification (in practice, few clients rely upon this behaviour). See Security considerations below for more details.
-u
Log concurrent FTP sessions to /var/run/utmp, to make them visible for other commands.
-V version
Advertise this version in the login banner and in the output of STAT and SYST instead of the default version information. Don't display any version information if the value of version is empty or "-".

Description:

The ftpd daemon is a DARPA Internet File Transfer Protocol server. It uses the TCP protocol.

The ftpd daemon is started when inetd receives a service request at the port specified by the FTP entry in the /etc/services file (inetd listens for service requests specified in the /etc/inetd.conf file at a port defined in the services file).


Note: Since stdin and stdout must be TCP sockets, you should launch the ftpd daemon from the inetd daemon or from a similar application. It can't be started on the command line.

Displaying welcome messages

The ftpd daemon checks for the existence of the following files. If a file exists, the appropriate action is performed.

If this file exists: Then ftpd:
/etc/ftpwelcome Prints the contents of this file before the "FTP Ready" message is issued.
/etc/motd Prints the contents of this file after a successful login. (This may be changed with the /etc/ftpd.conf directive upload.)
/etc/nologin Disables FTP access and displays the contents of this file before exiting.

Supported ftp requests

The ftpd daemon currently supports the following ftp requests; case isn't distinguished.

Request: Description:
ABOR Abort previous command
ACCT Specify account (ignored)
ALLO Allocate storage
APPE Append to a file
CDUP Change to parent of current working directory
CWD Change working directory
DELE Delete a file
EPSV Prepare for server-to-server transfer
EPRT Specify data connection port
FEAT List extra features that aren't defined in RFC 959
HELP Give help information
LIST List files in a directory (ls -l)
LPSV Prepare for server-to-server transfer
LPRT Specify data connection port
MLSD List contents of directory in a machine-processable form
MLST Show a pathname in a machine-processable form
MKD Make a directory
MDTM Show last modification time of file
MODE Specify data transfer mode
NLST Give name list of files in directory
NOOP Do nothing
OPTS Define persistent options for a given command
PASS Specify password
PASV Prepare for server-to-server transfer
PORT Specify data connection port
PWD Print the current working directory
QUIT Terminate a session
REIN Terminate a user (ignored)
REST Restart incomplete transfer
RETR Retrieve a file
RMD Remove a directory
RNFR Specify rename-from filename
RNTO Specify rename-to filename
SITE Nonstandard commands (see the next section)
SIZE Return size of file
SMNT Mount a different filesystem data structure (ignored)
STAT Return status of server
STOR Store a file
STOU Store a file with a unique name
STRU Specify data transfer structure
SYST Show operating system type of server system
TYPE Specify data transfer type
USER Specify username
XCUP Change to parent of current working directory (deprecated)
XCWD Change working directory (deprecated)
XMKD Make a directory (deprecated)
XPWD Print the current working directory (deprecated)
XRMD Remove a directory (deprecated)

Note: The following FTP requests (as specified in RFC 959) are recognized, but aren't implemented: ACCT, REIN, and SMNT.

The MDTM and SIZE requests aren't specified in RFC 959, but will appear in the next RFC update.


ABOR command

The ftp daemon aborts an active file transfer only when the ABOR command is preceded by a Telnet "Interrupt Process" (IP) signal and by a Telnet "Synch" signal in the command Telnet stream, as described in Internet RFC 959. If a STAT command is received during a data transfer and is preceded by a Telnet IP and Synch, transfer status is returned.

SITE nonstandard commands

The following nonstandard or UNIX-specific commands are supported by the SITE request:

Request: Description:
CHMOD Change the mode of a file (e.g. SITE CHMOD 755 filename)
HELP Give help information (e.g. SITE HELP)
IDLE Set the idle-timer (e.g. SITE IDLE 60)
RATEGET Set the maximum get rate throttle in bytes/second, e.g. SITE RATEGET 5k
RATEPUT Set the maximum put rate throttle in bytes/second, e.g. SITE RATEPUT 5k
UMASK Change the umask (e.g. SITE UMASK 002)

Metacharacters

Because the ftpd daemon interprets filenames according to the globbing conventions used by sh, users can employ these metacharacters:

*  ?  [  ]  ~

User authorization

The ftpd daemon authenticates users according to these rules:

  1. The username must be in the password database /etc/passwd and must not have a null password. The client must provide a password before any file operations may be performed.
  2. The username must not appear in the /etc/ftpusers file, which contains a list of users who aren't allowed to use ftp. One username is listed per line. If this file is missing, no user on the local system may access ftp.
  3. The user must have a standard shell (i.e. one listed in /etc/shells).
  4. If directed by the /etc/ftpchroot file, the session's root directory is changed by chroot() to the directory specified in the /etc/ftpd.conf chroot directive (if set), or to the home directory of the user. However, the user must still supply a password. This feature is intended as a compromise between a fully anonymous account and a fully privileged account. The account should also be set up as for an anonymous account.
  5. If the username is anonymous or ftp, an anonymous ftp account must be present in the password file (user ftp). In this case, the user can log in by giving any password (by convention, users give the name of the client host).

    The server performs a chroot() to the directory specified in the /etc/ftpd.conf chroot directive (if set), the -a anondir directory (if set), or to the home directory of the ftp user.

    The server then performs a chdir() to the directory specified in the /etc/ftpd.conf homedir directive (if set), otherwise to /.

    If other restrictions are required (such as disabling of certain commands and the setting of a specific umask), then appropriate entries in /etc/ftpd.conf are required.

    If the first character of the password supplied by an anonymous user is -, then the verbose messages displayed at login and upon a CWD command are suppressed.

Display file escape sequences

When ftpd displays various files back to the client (such as /etc/ftpwelcome and /etc/motd), various escape strings are replaced with information pertinent to the current connection.

The supported escape strings are:

Escape: Description:
%c Class name
%C Current working directory
%L Local hostname
%M Maximum number of users for this class. Displays "unlimited" if there's no limit.
%N Current number of users for this class
%R Remote hostname
%T Current time
%U User name
%% A "%" character

Setting up a restricted ftp subtree

So that system security isn't breached, it's recommended that the ftp subtree be constructed with care; the following rules are recommended:

~ftp
Make the home directory owned by the superuser and unwritable by anyone.
~ftp/bin
Make this directory owned by the superuser and unwritable by anyone. Generally, conversion commands are installed here. The ls utility, which must be present to support the LIST command, should have mode 111.
~ftp/usr/lib
A directory to contain shared libraries. This example uses /usr/lib -- as it is usually part of _CS_LIBPATH (see getconf _CS_LIBPATH); however, this may vary on custom installations. If no binaries in ~ftp/bin use shared libraries (all statically linked), this directory is not needed; however, the ls utility is usually linked against the shared libc. In such a situation:
# cd ~ftp
# mkdir -m0555 usr
# chown root:root usr
# mkdir -m0555 usr/lib
# chown root:root usr/lib
# cd usr/lib
# cp /lib/libc.so.2 .
# chmod 0555 libc.so.2
# chown root:root libc.so.2
# ln -s libc.so.2 ldqnx.so.2
~ftp/etc
Make this directory owned by the superuser and unwritable by anyone. The /etc/passwd and /etc/group files must be present for the LIST command to be able to produce owner names rather than numbers. The password field in /etc/passwd isn't used and shouldn't contain real encrypted passwords. If present, the contents of the /etc/motd file is printed after a successful login. The /etc/passwd and /etc/group files should be mode 444.
~ftp/pub
Make this directory mode 777 and owned by ftp. If any files are to be accessed via the anonymous account, the user should place them in this directory.
~ftp/incoming
Make this directory where the anonymous users place files they upload. The owners should be user ftp with an appropriate group. Members of this group are the only users with access to these files after they've been uploaded, so these people should know how to deal with them appropriately. To allow anonymous FTP users the ability to see filenames in this directory, set the permissions to 770; otherwise, set to 370.

Anonymous users are able to upload files to this directory, but they're unable to download them, delete them, or overwrite them due to the umask and disabling of the commands mentioned above.

~ftp/tmp
This directory is used to create temporary files which contain the error messages generated by a conversion or LIST command. The owner should be the user ftp. The permissions should be 300.

Don't create this directory if you don't want to enable conversion commands or don't want to allow anonymous users uploading files here (see ~ftp/incoming above). Error messages from conversion or LIST commands won't be returned to the user. (This is the traditional behaviour.) The /etc/ftpd.conf upload directive can be used to prevent users uploading here.

To set up "ftp-only" accounts to provide FTP only with no valid shell login, you can:

This allows you to log in via FTP into accounts that have /sbin/ftplogin as the login shell.

Security considerations

RFC 959 provides no restrictions on the PORT command, and this can lead to security problems since ftpd can be fooled into connecting to any service on any host. If the checkportcmd directive of /etc/ftpd.conf is specified, PORT commands with different host addresses, or TCP ports lower than IPPORT_RESERVED, are rejected. This option prevents "third-party proxy ftp" from working. Use of this option is strongly recommended, and is enabled by default.

By default ftpd uses a port that is one less than the port it is listening on to communicate back to the client for the EPRT, LPTR, and PORT commands. As the default port for ftpd is a privileged port below IPPORT_RESERVED, ftpd retains the ability to switch back to root privileges to bind these ports. In order to increase security by reducing the potential for a bug in ftpd providing a remote root compromise, ftpd permanently drops root privileges if one of the following is true:

  1. ftpd runs on a port greater than IPPORT_RESERVED and the user logged in as a "guest" or "chroot" user.
  2. ftpd is invoked using -r.

Don't create ~ftp/tmp if you don't want anonymous users to upload files there. The directory is necessary only if you want to display the error messages of conversion commands to the user. If uploads are disabled with the /etc/ftpd.conf directive upload, then this directory cannot be abused by the user in this way, so it should be safe to create.

Files:

/etc/ftpchroot
List of normal users to change root directory for.
/etc/ftpd.conf
Configure file conversions and other settings.
/etc/ftpusers
List of unwelcome and restricted users.
/etc/ftpwelcome
Welcome notice before login.
/etc/motd
Welcome notice after login.
/etc/nologin
If this file exists, display the contents of the file and refuse FTP access.

The ftpd daemon requires the libsocket.so shared library.

Caveats:

The server must run as the superuser to create sockets with privileged port numbers. It maintains an effective user ID of the logged-in user, reverting to the superuser only when binding addresses to sockets. The possible security holes have been extensively scrutinized, but are possibly incomplete.

If the pipe manager isn't running, LIST and other commands may not be available.

See also:

ftp, /etc/ftpchroot, /etc/ftpd.conf, ftpusers, inetd, tftpd, pipe, syslogd

TCP/IP Networking in the Neutrino User's Guide

RFC 959, RFC 1123, RFC 2389, RFC 2428