Net::FTPServer::PWP::Server - The FTP server for PWP (personal web pages) service.


  ftpd [-d] [-v] [-p port] [-s] [-S] [-V] [-C conf_file]


Net::FTPServer::PWP::Server is a FTP server personality. This personality implements a complete FTP server with special functionalities in order to provide a PWP service implementation.

The features provided include:

  • Directory quotas

  • Authentication using the RADIUS protocol

  • Configurable root directory


A few config file entries have been added, as described below:

pwp root subdir

If specified, tacks its contents to the root directory obtained through RADIUS. This allows the contraining of the user to a part of her home directory.

default pwp quota

Defaults to -1 or unlimited. Is the number of octets allocated by default to users.

pwp quota cache secs

Controls how often the FTP server will invalidate its notion of the current space consumption. This allows performance tuning. Use a larger value where a small number of concurrent (same user) sessions are expected. Use a smaller value in the oposite case. Finding out what 'larger' and 'smaller' means is left as an excercise for the reader.

A smaller value causes each FTP server to scan the whole user directory more often (actually, every time the number of seconds specified passes).

pwp quota exceeded message

The message to return to the user when her quota is exceeded. Defaults to This operation would exceed your quota.

pwp quota file

The name of the quota file to use. Defaults to ../$user-pwpquota, which places the quota file just above the PWP directory at the home dir of each user using a name composed of the user name plus '-pwpquota'.

You can use variables such as $hostname, $username, etc. within its specification. Note that the quota file is specified relative to the PWP directory of the user, but is not subjected to the jail limitations. This allows the quota file to be placed outside the PWP directories.

pwp max quota file age

Maximum age in seconds that the quota file can have, before requiring it to be rebuilt.

pwp max quota file lines

Maximum amount of entries in the quota file before forcing it to be rebuilt.

radius realm

The realm used for authenticating users. Defaults to 'pwp'.

radius server

RADIUS server (or comma separated list of servers) to send requests to. It is an error to not specify at least, a RADIUS server.

radius port

The port to direct the RADIUS request. Defaults to 1645.

radius secret

The secret used to authenticate against the RADIUS server. Not specifying it is an error.

radius dictionary

The RADIUS dictionary file used to encode and decode the RADIUS request. It defaults to /usr/local/lib/pwp-dictionary.

radius timeout

The amount of time we will wait for an answer from a RADIUS server. After this many seconds, the server is skipped and the next one is tried.

pwp radius vendor id

The vendor-id used in the Vendor-Specific Attributes sent and received from the RADIUS server. The dafault is 582. The value specified here must match the one used in your dictionary files.

hide mount point

When true, instructs the FTP server to attempt to hide the actual mount point from the client. This forms a sort of jail similar to what chroot() imposes, but without the need to replicate system files to the chroot()-ed environment.


    $rv = $self->authentication_hook ($user, $pass, $user_is_anon)

    Perform login authentication against a RADIUS server. We also take this opportunity to insert our very own handler for the DELE command. This is required to properly keep track of the disk usage of the user. Our handler is called _DELE_command and is documented below.

    We also hardcode the SITE QUOTA command to allow the user to check her quota. This is done with _SITE_QUOTA_command, documented below. Note that this will conflict with locally defined handlers for the SITE QUOTA command.

    $self->user_login_hook ($user, $anon)

    Hook: Called just after user $user has successfully logged in.

    $dirh = $self->root_directory_hook;

    Hook: Return an instance of Net::FTPServer::PWPDirHandle corresponding to the root directory.

    $dirh = $self->pre_command_hook;

    Hook: Insures that our quotas look sane enough. Otherwise, have them recalculated.

    $dirh = $self->transfer_hook;

    Hook: Enforce the quota mechanism by seeing that no transfer exceed the allocated quota.


    This method handles the SITE QUOTA command, that allows the user to check at a glance, what the server thinks of its space usage.


    This is supposed to intercept Net::FTPServer::_DELE_command before it is called. What we do here, is to note the size of the soon-to-be-deleted file and apply the change in the quota file if the operation was succesful.

    Note that this might be somewhat dangerous or un-portable as traditionally, method names starting with _ mean internal things that should not be messed from the outside. Yet it seems we do not have a better solution to this issue.

    The code contains a race condition: If two different sessions try to delete the same file at the same time, probably both will think they did and will attempt to reflect this in the quota file. There's a chance for both of the updates to make it to the quota file, thus over-reducing the user's space allocation. This will correct automatically after either a few more operations or some time.




$Id:,v 1.30 2003/04/01 15:50:42 lem Exp $


Original version; created by h2xs 1.21 with options


PWD will return the path minus the current root. This allows for the hidding of the home directory.


As per Rob Brown suggestion, the quota file will no longer be within the home directory. Any arbitrary pathname can be specified in the config file. Include the directory size in the quota calculation to avoid abuses.

The quota file specification has variable interpolation performed.

SITE QUOTA was broken in 1.10. Fixed.


Added code to avoid this error

    Argument "" isn't numeric in addition (+) at
    / line 636, <GEN28979> line 2.


Luis Munoz <>, Manuel Picone <>


Copyright (c) 2002, Luis Munoz and Manuel Picone


Net::FTPServer(3), Net::FTPServer::PWP(3), perl(1)

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 145:

You can't have =items (as at line 176) unless the first thing after the =over is an =item

Around line 815:

=back doesn't take any parameters, but you said =back 4