## 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:

      http://tools.ietf.org/html/draft-somers-ftp-mfxx-04

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:

      http://www.proftpd.org/

## Directives

- FactsAdvertise
- FactsDefault
- FactsOptions

### FactsAdvertise

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
      </IfModule>

### FactsDefault

Syntax: FactsDefault fact1 ...
Default: None Context: server config, `<VirtualHost>`, `<Global>`
Module: mod_facts
Compatibility: 1.3.8rc3 and later

The `FactsDefault` directive configures the default list of facts to include in responses to `MLSD`/`MLST` FTP commands. The supported fact names are:

- `media-type` (file media type, where known)
- `modify` (file modification timestamp)
- `perm` (file permissions)
- `size` (file size in bytes)
- `type` (file type, per RFC 3659, Section 7.5.1)
- `unique` (unique file identifier)
- `UNIX.group` (file numeric UNIX group ID)
- `UNIX.groupname` (file textual UNIX group name)
- `UNIX.mode` (file numeric UNIX permissions/mode)
- `UNIX.owner` (file numeric UNIX user ID)
- `UNIX.ownername` (file textual UNIX user name)

By default, the `mod_facts` module will provide the following facts:

- `modify`
- `perm`
- `size`
- `type`
- `unique`
- `UNIX.group`
- `UNIX.groupname`
- `UNIX.mode`
- `UNIX.owner`
- `UNIX.ownername`

### FactsOptions

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:

- `UseSlink`

  Use this option to have `mod_facts` use the broken "OS.unix=slink" syntax, preferred by FTP clients such as FileZilla, for indicating symlinks, rather than the more correct "OS.unix=symlink" syntax. See Bug#3318 for a more detailed discussion.

  Note that this option first appeared in `proftpd-1.3.4b`.

- `AdjustedSymlinks`

  Using this option will cause `mod_facts` to try to automatically adjust any symlink destination paths when the FTP session is chrooted, so that the adjusted symlinks work properly e.g. for FTP clients.

  Note that this option first appeared in `proftpd-1.3.7rc1`.

- `NoNames`

  By default, `mod_facts` will automatically use the newer `UNIX.ownername` and `UNIX.groupname` facts in its `MLSD`/`MLST` responses. But some FTP clients may not react well to the presence of these facts. Use this option to disable to use of these facts.

  Note that this option first appeared in `proftpd-1.3.6rc3`.

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
      </IfModule>

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
      </IfModule>

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
      </IfModule>

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
      </IfModule>

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
        </Limit>
      </Directory>

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.

## Installation

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