ProFTPD module mod_facts

File "Facts" Support

The mod_facts module is ProFTPD's module for handling the MLSD and MLST commands, in support of RFC 3659. In addition, the mod_facts module implements the MFF and MFMT commands defined in:

This module is contained in the mod_facts.c file for ProFTPD 1.3.x, and is compiled by default. Other installation instructions are discussed here.

The most current version of mod_facts can be found in the ProFTPD source distribution:



Syntax: FactsAdvertise on|off
Default: FactsAdvertise on
Context: server config, <VirtualHost>, <Global>
Module: mod_facts
Compatibility: 1.3.2rc2 and later

The FactsAdvertise directive is used to control whether the mod_facts module advertises its MLST support via the FEAT command.

By default, the mod_facts module will list MLST in the FEAT response. FTP clients use this to determine whether to use the newer MLSD/MLST commands, or the older LIST/NLST commands. Some FTP clients, though, will attempt to use the newer commands just as if they were equivalent to the older commands, including supporting glob/wildcard characters. Section 2.2.2 of RFC3659, which explicitly states that wildcard characters are not supported in the MLSD and MLST commands. Thus, to prevent problems when using such FTP clients with proftpd, you can disable the advertising of support for those commands using e.g. the following in your proftpd.conf:

  <IfModule mod_facts.c>
    FactsAdvertise off


Syntax: FactsOptions opt1 ...
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_facts
Compatibility: 1.3.4b and later

The FactsOptions directive is used to configure various optional behavior of mod_facts. Note: all of the configured FactsOptions parameters must appear on the same line in the configuration; only the first FactsOptions directive that appears in the configuration is used.

The currently implemented options are:

Frequently Asked Questions

Question: Why does MLSD list all of the files in a directory, including the "hidden" files, where the LIST command does not?
Answer: The MLSD and MLST commands do not have any notions of "options" like the LIST and NLST commands do; there is no way for a client, in the request to list the files in a directory, to ask the server to filter the list of files somehow. Instead, MLSD contains a list of "facts" for each file in its list; the client then has to to decide how to filter the list of files based on those facts. This is why the ListOptions directive has no influence over the MLSD and MLST commands.

Question: Why does MLST show the UIDs/GIDs for listed files, where LIST/NLST show the user/group names?
Answer: The list of "facts" defined by RFC 3659 does not include a fact for the stringified version of user/group owner names, unfortunately. This means that the MLSD/MLST commands do not have a good way of obtaining the user/group names.

To work around this issue, you can add the following to your proftpd.conf:

  <IfModule mod_facts.c>
    FactsAdvertise off
This tells proftpd to not advertise to the client that it can support the MLSD/MLST commands. The client will then usually fall back to using the older LIST command, which does include the file owner user/group names.

Question: Why does FileZilla not display symlinks properly, even though I have "ShowSymlinks on" in my proftpd.conf?
Answer: Newer versions of FileZilla (and other FTP clients) use the MLSD command for listing files, rather than the older LIST command. And FileZilla and the mod_facts module disagree on the proper syntax for indicating when a file is a symlink.

To work around this issue, you can add the following to your proftpd.conf:

  <IfModule mod_facts.c>
    FactsOptions UseSlink
This tells the mod_facts module to use the improper "OS.unix=slink:path" syntax for symlinks; this is the syntax preferred by FileZilla (and perhaps other FTP clients). By default, the mod_facts module uses the better "OS.unix=symlink" syntax.

Note that if you are running proftpd-1.3.3, however, the FactsOptions directive is not supported. To get FileZilla to display symlinks properly for older proftpd versions, then, you would use:

  <IfModule mod_facts.c>
    FactsAdvertise off
This tells the mod_facts module to not advertise that it supports the newer MLST/MLSD commands. FileZilla will then fall back to using the older directory list commands (i.e. LIST, NLST), which should show symlinks properly.

Question: How can I hide dotfiles (e.g. ".msg") from the MLSD command?
Answer: There are two possible ways of dealing with FTP clients which use the MLSD command for listing directories, as opposed to the LIST/NLST commands.

Since the MLSD command does not have the concept of "options", unlike LIST/NLST, the ListOptions directive does not apply to MLSD as some would expect. Thus using a configuration like so:

  ListOptions +a
to hide dotfiles from LIST commands does not work for MLSD. How, then, to hide dotfiles from MLSD commands? You can configure proftpd so that it does not advertise the fact that it can support the MLSD command, via:
  <IfModule mod_facts.c>
    FactsAdvertise off
Alternatively, you can use the HideFiles and IgnoreHidden directives:
  <Directory />
    # Hide files whose names start with "."
    HideFiles ^\.

    <Limit LIST MLSD NLST>
      # Do not include hidden files for LIST, MLSD, and NLST
      IgnoreHidden on
This latter configuration will apply to LIST, NLST, and MLSD equally.

Question: How can I disable the mod_facts module entirely? Some clients (e.g. ncftp) do not appear to implement MLSD properly, and do not honor the FEAT response from proftpd when FactsAdvertise is configured off.
Answer: There is no easy way of disabling the mod_facts module at present; the
FactsAdvertise directive is intended to do this in a way compliant with the RFCs.

That said, you can compile proftpd such that mod_facts is built as a DSO/shared module:

  $ ./configure --enable-dso --with-shared=mod_facts ...
and then, in your proftpd.conf, you simply omit any "LoadModule mod_facts.c" directive, so that that module is never dynamically loaded.


The mod_facts module is distributed with ProFTPD, and is normally compiled as a static module by default. However, if you wish to have mod_facts be built as a shared module, you would use:
  $ ./configure --enable-dso --with-shared=mod_facts ...
Then follow the usual steps:
  $ make
  $ make install

© Copyright 2007-2020 The ProFTPD Project
All Rights Reserved