This file documents MUDDLEFTPD, a file transfer protocol server.

Copyright (C) 1999 Jonas Öberg and Beau Kuiper

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

This file documents the MUDDLEFTPD program, a server for the Internet File Transfer Protocol. This is edition 1.1 for Muddleftpd version 1.1.

Introduction
************

MUDDLEFTPD is a server for the Internet File Transfer Protocol. Normal FTP servers tend to always want to run with root privileges on the server host. MUDDLEFTPD is designed to overcome this obstacle without limiting the available features when running without root privileges.

This manual describes version 1.1 of the program.

Invocation
**********

Neither the server program, MUDDLEFTPD, or the special information program, FTPWHO takes any special arguments except the name of the configuration file to use. If no configuration file is specified on the command line, both programs will try to open the default configuration file.

Site Configuration
******************

MUDDLEFTPD uses two different configuration files. The main configuration file and the user configuration files. They both use a simple format where lines consist of two items separated by space (key and value).  There can only be one pair of key and value on each line. Comments start with the # character and continue until the end of the line. Values can include spaces by escaping them with the \ character as is shown in the example below.

     	# The \ allows space to be recognized as part of the value
     	access  /etc/name\ spaced

Main config
***********

The main config file is read when muddleftpd is first started. It contains information that applies to the entire program. Some options can be declared several times in the configuration file to add more values.

ftpport
*******

  * Accepted value: (port)/(ip) | (port)

  * Default: none

ftpport tells the server that it should try to listen on port for connections. You may specify this directive more than once to listen on more than on port. For each ftpport directive, you may also specify the IP number of the interface on which MUDDLEFTPD should accept connections. MUDDLEFTPD will refuse to start if you don't specify atleast one ftpport directive.

Examples:

     ftpport	21	#listen to port 21 for connections
     ftpport 121/127.0.0.1	#listen to port 121 only on the loopback
     			#device
     ftpport 4990/10.1.1.1	#listen to port 4990 only on the ethernet
     			#device with IP 10.1.1.1

maxusers
********

  * Accepted value: (maximum user count)

  * Default: 30

maxusers tells the server the maximum number of users that MUDDLEFTPD will allow to connect at any one time. When the maximum number of users have been reached, all subsequent connections will be silently dropped to prevent resource wastage. If you are setting up an anonymous FTP server, you should have maxusers higher that anonymous's maxusers. This way, a full FTP server doesn't rudely drop connections.

logstrength
***********

  * Accepted value: (logvalue)

  * Default: 1

logstrength tells the server what information to log. The value for this option is the sum of any of the following types:

1   Clients that try to access the server from invalid	ip addresses
2   File transfers, uploads and downloads.
4   Commands the user sends to the server.
8   The replies the server sends to the user.
16   General Information logs (server starting and stopping)
32   Login information, including successful and denied logins.

Examples:

     logstrength 63		# log everything
     logstrength 0		# log nothing
     logstrength 51		# log everything except user commands
     			# and server replies

runasuid
********

  * Accepted value: (uid)

  * Default: (none)

When setting the directive, the server will attempt to change the user id to uid. This is usually used to bind to a privileged port number before switching to another user for user access. This may break some pedantic clients or firewalls, but these are few and far between. If you don't specify this directive, then the server will run with whatever permissions it has when it starts.

Examples:

     runasuid 65535		# run as nobody

runasgid
********

  * Accepted value: (gid)

  * Default: (none)

When setting the directive, the server will attempt to change the user group id to uid. This is usually used to bind to a privileged port number before switching to another user for user access. This may break some pedantic clients or firewalls, but these are few and far between. If you don't specify this directive, then the server will run with whatever permissions it has when it starts.

Examples:

     runasgid 65535          # run as the group nogroup

logfile
*******

  * Accepted value: (filename)

  * Default: /var/log/muddleftpd.log

This directive tells MUDDLEFTPD where to store its log file. The server will append to the specified file. This file must exist and be writable to the starting user, otherwise MUDDLEFTPD will refuse to start and exit.

Examples:

     logfile /home/rugger/ftpd/ftpd.log  # store logs in an alternative
     				    # place

accessdir
*********

  * Accepted value: (directory)

  * Default: /usr/local/etc

accessdir tells MUDDLEFTPD where to find the configuration files describing user access to the server. It must be readable to the running user or MUDDLEFTPD will be unable to autenticate any users.

Examples:

     accessdir /etc/muddleftpd	# files are stored in /etc/muddleftpd
     accessdir /home/rugger/ftpd	# files are stored in
     				# /home/rugger/ftpd

timeout
*******

  * Accepted value: (seconds)

  * Default: 300 seconds

timeout gives the default timeout for a user connection. This timeout will apply before the user logs in, and will persist if timeout isn't configured in the user configuration files.

Examples:

     timeout 20		# users must log in within 20 seconds
     timeout 3600		# 1 hour timeout

addhost
*******

  * Accepted value: (ip address)/(netmask)

  * Default: (none)

addhost tells the server to allow access to a given subnet. By default, MUDDLEFTPD denies access to all hosts.

Examples:

     addhost 192.203.224.0/255.255.255.0
     	# allow access to all hosts from 192.203.224.X
     addhost 76.2.0.0/255.255.0.0
     	# allow access to all hosts from 76.2.X.X
     addhost 10.2.9.34/255.255.255.255
     	# allow access to host 10.2.9.34
     addhost 0.0.0.0/0.0.0.0
             # allow access to everyone

logindump
*********

  * Accepted value: (filename)

  * Default: (none)

logindump specifies what file will be displayed to the user before the user logs in. All normal magic cookies are available (except %C) for use, although the information in many of them is useless until the user logs in. See Magic Cookies. This can be used to display welcome messages and information to the user before he or she logs in.

Examples:

     logindump /etc/issue	 # display the issue file
     logindump /etc/issue.ftp # display this file

pidfile
*******

  * Accepted value: (filename)

  * Default: /var/run/muddleftpd.pid

pidfile defines the file that you wish to store the pid of the main MUDDLEFTPD process in. It is required to determine if MUDDLEFTPD is already running with a particular config file. If one can not be created, the server will abort and refuse to run. pidfile MUST not be in a directory where other users can create links.

Examples:

     pidfile /home/rugger/pids/muddleftpd.pid
     		# store the pid file here

email
*****

  * Accepted value: (email address)

  * Default: <unknown>

email is where you provide an email address that is stored in the magic cookie %E. See Magic Cookies. You can specify anything you want.

Examples:

     email ekuiperba@cc.curtin.edu.au
     email I\ don't\ want\ to\ tell\ you!	# just a string

User config
***********

The user configuration files define almost everything about a user connection to the ftp server. This includes home directory, root directory, password and file access rights. MUDDLEFTPD will have at least one ofthese files, and will load them in the following order:

 1. user.<username>

 2. user.default

user.default will be loaded if MUDDLEFTPD can not find the first configuration file. Note that if user.default doesn't exist, then an error message will be written to the log.

You can also create group.<groupname> files that can be used as templates for user.<username> files. If you specify a group template file in the user.<username> file, then the group.<groupname> file will be loaded AFTER the user.<username> file has been parsed.

If you specify a directive more than once in a user config file, then the first one will be the one that the server recognizes.

User files also use magic cookies to improve configurablity. See Magic Cookies.

group
*****

  * Accepted value: (group name)

  * Default: (none)

group tells the server to load the file group.(groupname) after processing all the directives in the user configuration file. This lets you use templates that multiple user configuration files can use. If this group file doesn't exist, a log entry will be generated. These group files are kept in the same directory as the user config files.

Examples:

     group users	# read the file group.users
     group <none>	# use no group file

password
********

  * Accpted value: (encrypted password)

  * Default: %p

password specifies the password (in encrypted form) that the user must enter to successfully log on. If you specify *, the username is disabled. if you specify <none>, then any password is accepted.

Examples:

     password %p	# use the normal password from /etc/passwd
     password %s	# use a shadow password.
     password <none>	# accept any password.

rootdir
*******

  * Accepted value: (directory)

  * Default: /

rootdir specifies the root directory for this user. The user will not be able to access directories above this directory (unless a symbolic link exists to an outside directory, where that directory and its children will be visible).

Examples:

     rootdir %h 	# use the home directory as the root directory.
     rootdir /home/ftp # use /home/ftp as the root directory.
     rootdir /	# use / as the root directory.

homedir
*******

  * Accepted value: (directory)

  * Default: %h

homedir is the directory the server will place a user in after they have been successfully authenticated. It is relative to rootdir (eg if homedir is /cow and rootdir is /mad, then the login directory will be /mad/cow). The user can also use ~ to access their home directory.

Examples:

     homedir %h 	# set home directory to the passwd home directory
     homedir /	# use / as the home directory.

welcome
*******

  * Accepted value: (filename)

  * Default: (none)

welcome specifies the file that the user will see when he or she logs in. It is an absolute filename (no relation to rootdir). File magic cookies apply to this file. See Magic Cookies.

Examples:

     welcome /etc/ftpwelcome
     welcome /home/ftp/welcome.txt

access
******

  * Accepted value: (filename or directory):(keys)

  * Default: no access.

access controls the ACL access layer that MUDDLEFTPD places above unix file system permissions. (filename or directory) specify the filename or directory to which these restrictions apply. (keys) specify which access rights to grant to the user in this directory or file. (filename or directory) is relative to rootdir.

If a filename is specified, then the access will apply only to that file. If a directory is specified by ending (filename or directory) with a /, then the access directive will apply to all files and subdirectories of that directory.

The default is to give no access. To allow unix permission define access, use

     access /:ALL

in the user configuration file. The following keys are available:

R   Read file or directory
L   List files (only meaningful for directories)
A   Add new files (only meaningful for directories)
W   Write access.
D   Delete file access (only meaningful for directories)
X   Do not override this ACL (if one exists in the group file)

ALL   All attributes except X
NONE   No attributes (no access)

Examples:

     access /etc/ftpwelcome:R # give read access to /etc/ftpwelcome
     access /etc/:R           # give read access to all files in /etc/
     access /incoming/:A      # give add file access to /incoming
     access /:ALL             # give full access to all files, dirs.
     access /secret/:NONE     # don't give access to any files in /secret.

umask
*****

  * Accepted value: (octal integer)

  * Default: umask when MUDDLEFTPD was started

umask specifies what attributes files and directories will be given when they are created. umask specifies what bits are not set.

Examples:

     umask 077	# only user bits are set on new file creation
     umask 666	# all new files are set non-accessible.

unixuser
********

  * Accepted value: (username)

  * Default: (none)

unixuser specifies what username to load the magic cookies from. It loads these cookies from the password file (/etc/passwd) with (username). The only magic cookie available to this directive %U. See Magic Cookies.

Examples:

     unixuser %U	# use the entered username as the unix username
     unixuser ftp	# use the user ftp for all the cookies

maxconnect
**********

  * Accepted value: (count)

  * Default: (no limit)

maxconnect controls how many people with the same username can log in at the same time (NOTE: This restribution is per username and not per configuration file). If this value is reached, user trying to connect will be denied access and busydump will be returned to the user.

Examples:

     maxconnect 10
     maxconnect 150

utimeout
********

  * Accepted value: (seconds)

  * Default: the main configuration timeout value

This sets the utimeout for this specific user. Any sessions will automaticly be disconnected after this period of inactivity.

Examples:

     utimeout 600	# set user timeout to 10 minutes
     utimeout 7200	# set user timeout to 2 hours.

permissions
***********

  * Accepted value: (integer)

  * Default: %u | %g

The uid and gid directives sets the user and group id that all user requests file accesses will be performed as. Note: The server will not accept uid 0 (root) and will automatically change it to -1 (nobody). gid 0 (root or wheel) will be changed to -1 (nogroup).

Examples:

     uid 20		# use user id 20 for all file access.
     uid %u		# use the user id from the password file.
     gid 20		# use group id 20 for all file access.
     gid %g		# use the group id from the password file.

dumpfiles
*********

  * Accepted value: (filename)

  * Default: (none)

The cddump, busydump and quitdump directives specify what files to send to the user when they perform a number of actions or when a certain event occurs. cddump specifies the file to send when a change directory action is performed. busydump specifies the file to send when maxconnect number of users are already connected. quitdump specifies the file to send when the user disconnects from the ftp service.

File magic cookies apply to these files. See Magic Cookies.

Examples:

     cddump .message		# show .message in the directory the user
     			# changes to.
     busydump /etc/ftpbusy
     quitdump /etc/ftpbye

chmoding
********

  * Accepted value: 0 | 1

  * Default: 0

If chmoding is set to 1, the user is allowed to change the umask and change permissions on files.

Examples:

     chmoding 0	# disable chmod and umask changing
     chmoding 1	# enable chmod and umask changing

Troubleshooting
***************

If problems occur while compiling, check the following:

  * If you are running OpenLinux 2.2, make sure that you have downloaded and installed the crypt package. Get it from: ftp://ftp.linuxland.de/pub/OpenLinux/crypto/2.2/glibc-crypt-2.1-3i.i386.rpm

If you get either of these messages when running the sever:

muddleftpd error in file init.c line 51: muddleftpd already running!

     This means that you are already running a copy of muddleftpd using the configuration file muddleftpd tried to open. (That is, the default compiled in config file, or what you specified on the command line). Simply close down the old version (with a SIGTERM) and start it again.

muddleftpd error in file shmem.c line 91: Permission denied

     This means that muddleftpd could not get write permission on the main configuration file (It is used for locking the shared memory). You must give the user running muddleftpd write permission to the main config file muddleftpd will be running as.

FTP Commands
************

The following commands are understood and used by muddleftpd:

PORT   Define the data port the server will connect to
PASV   Tell the server that the next data connection will
use passive mode
RETR   Retreive a file from the server
STOR   Store a file on the server
STOU   Store a file on the server using an unique filename
APPE   Append to a file on the server
TYPE   Specify what type to transfer data (A = Ascii, B = binary)
QUIT   Quit the ftp server
PASS   Password to log on using
USER   Username to log on using
SYST   Returns the system type muddleftpd is running on (UNIX)
LIST   Do a long list over a data connection
NLST   Do a short list over a data connection
PWD    see XPWD
XPWD   Return the current directory
CWD    see XCWD
XCWD   Change the working directory
ABOR   Abort a data connection in progress
CDUP   Change to the parent directory.
XCUP   see CDUP
STAT   return server status or a listing over the control connection.
NOOP   Do nothing
REIN   Reinitalize the server for a new user
REST   Resume a data transfer at a particular position
DELE   Delete a file
MKD    see XMKD
XMKD   make a new directory
RMD    see XRMD
XRMD   remove a directory
RNFR   set the file to rename
RNTO   set the name to rename to
SIZE   get the size of a file using the current TYPE setting
MDTM   get the modification time of a file
HELP   show list of recognized commands
SITE DUMP	  display a file over the control connection
SITE ACCESS   show ACLs of the current user
SITE HELP	  show recognised site commands
SITE UMASK   set the umask
SITE CHMOD   change the permissions of a file

Commands recognised but ignored in muddleftpd

ALLO   Allocate space (not needed)
ACCT   Account	name (not needed)

Magic Cookies
*************

Magic cookies are used in MUDDLEFTPD user config files and in files displayed to the user. Magic cookies recognized in files are replaced with the values they represent as MUDDLEFTPD parses them. eg:

     my email is %E

has the magic cookie %E. Since %E represents the FTP server maintainer's email address, MUDDLEFTPD would create the following:

     my email is ekuiperba@cc.curtin.edu.au

All magic cookies in MUDDLEFTPD start with a % char. There are 2 formats available:

The %x Format:

This format is simplest syntax and simply replaces the cookie (%x) with the entire string that represents the character x.

The %(m,n)x Format:

This format selects a range of characters from the string cookie (%x) represents. m is the first character to insert and n is the last character to insert from cookie x. The first character in a magic cookie is numbered is 0. m and n are both adjusted so m >= 0 and n <= length of the Magic cookie. See Magic Cookies. if n > m, then the cookie is considered invalid, see below.

eg.

%(0,5)u   will give the first six characters of what magic cookie
u represents.
%(10,10)E   returns the 11th character of what cookie E represents.
%(6,8)M   returns the 7th to 9th characters from what cookie M represents.
%(10,8)F   This is invalid because n > m.

Invalid Syntax:

If MUDDLEFTPD determines that a magic cookie is invalid (ie, it doesn't exist or is the format is bad), then the line where the magic cookie was found will not be parsed and an entry (informational) will be added to the log.

The following magic cookies are recognized in dumped files:

%T   The current time in the format: Wed Jan 30 21:49:08 1993
%U   The username the user used to login
%C   The current directory of the user
%E   The administrators email, set in the main config file
%M   The maximum number of users muddleftpd will log on at a time
%N   The current number of users logged into this muddleftpd server.
%R   The string representation of the remote user's IP
(muddleftpd doesn't do reverse name lookup on users)
%L   The full hostname of the host muddleftpd is running on
%f   The number of files the user has downloaded
%F   The number of files the user has uploaded
%b   The number of bytes the user has downloaded, downloading files.
%B   The number of bytes the user has uploaded, uploading files
%I   The number of bytes the user has downloaded, from listings
%i   The number of listings the user has downloaded
%D   The total number of bytes downloaded (listing and file downloads) over data connections.
%d   The total number of connections opened for downloading (listing and file downloads)
%t   The total number of bytes transfered (listing, uploading and downloading) over data connections
%c   The total number of data connections made (for listing, uploading and downloading)

You can also use the %(m,n)x format on any of the above cookies. (although doing so may not be useful for many of the cookies) The %C magic cookie is invalid during the logindump file, because the user has no current directory before startup.

To make user configuration files flexable, a set of magic cookies are accepted in these files. Most of these magic cookies get read from the password file.

The following magic cookies are recognized in config files:

%U   The username of the connecting party
%p   The encrypted password from the normal password file
%s   The encrypted password from the shadow password file
(if your system uses shadow passwords)
%u   The uid from the password file
%g   The gid from the password file
%h   The home directory from the password file.

You can also use the %(m,n)x format on any of the above cookies. (although doing so may not be useful for many of the cookies) For the unixuser directive, only %U will be avaliable. unixuser will load the other cookies thought.

Reporting Bugs
**************

Report bugs to Beau Kuiper <ekuiperba@cc.curtin.edu.au>.