mod_conf_ldapmod_conf_ldap module can be used to store configuration
information, as would normally be found in the proftpd.conf
file, in LDAP directories, and to have proftpd consequently
retrieve that configuration information. Detailed usage instructions can be
found here.
This module is contained in the mod_conf_ldap.c file for
ProFTPD 1.2.x, and is not compiled by default. Installation instructions
are discussed here.
The most current version of mod_conf_ldap can be found at:
http://www.castaglia.org/proftpd/
Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.
mod_conf_ldap.c file into:
proftpd-dir/contrib/Then follow the normal steps for using third-party modules in proftpd:
./configure --with-modules=mod_conf_ldap make make install
proftpd.conf:
contexts and directives. Contexts include <Anonymous>,
<VirtualHost>, the "server config" default
context, and conditional contexts such as <IfDefine> and
<IfModule>. Configuration directives are contained
within a context.
To represent the configuration file contents within LDAP directories, a schema was designed that contains the necessary attrributes that represent these configuration contexts and directives.
LDAP Schema
The following LDAP schema (contained in the mod_conf_ldap.schema
file bundled with mod_conf_ldap) defines the attributes and class
needed to represent a proftpd.conf file in an LDAP directory:
attributetype ( 1.3.6.1.4.1.17852.2.1.3.1.1
NAME 'ProFTPDConfContains'
DESC 'Ids for ProFTPDConfContexts contained within this context'
EQUALITY caseExactMatch
SUBSTR caseExactSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
)
attributetype ( 1.3.6.1.4.1.17852.2.1.3.1.2
NAME 'ProFTPDConfContext'
DESC 'proftpd.conf start context string'
EQUALITY caseExactMatch
SUBSTR caseExactSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE
)
attributetype ( 1.3.6.1.4.1.17852.2.1.3.1.3
NAME 'ProFTPDConfDirective'
DESC 'proftpd.conf configuration directive'
EQUALITY caseExactMatch
SUBSTR caseExactSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
)
attributetype ( 1.3.6.1.4.1.17852.2.1.3.1.4
NAME 'ProFTPDConfId'
DESC 'Descriptor for this proftpd.conf context'
EQUALITY caseExactMatch
SUBSTR caseExactSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE
)
objectclass ( 1.3.6.1.4.1.17852.2.1.3.2.1
NAME 'ProFTPDConf'
DESC 'proftpd.conf configuration context'
MUST ( ProFTPDConfId $ ProFTPDConfContext )
MAY ( ProFTPDConfContains $ ProFTPDConfDirective $ cn $ dc )
)
Each context is assigned a unique ID (ProFTPDConfId). Each
ProFTPDConf class contains its unique ID and a context
identifier (ProFTPDConfContext), and may contain multiple
configuration directives (ProFTPDConfDirective) and multiple
sub-contexts (ProFTPDConfContains). Contexts must be able to
contain other contexts, which allows for nested contexts, such as:
<Directory incoming>
<Limit DELE MKD RMD STOR XMKD XRMD>
DenyAll
</Limit>
</Directory>
Configuration URI
How does mod_conf_ldap do its magic? This module uses ProFTPD's
FSIO API to temporarily redefine what it means to open and read a file; it
presents a file-like interface to an LDAP directory such that ProFTPD's
configuration parser does not know that the configuration is coming from a
LDAP server rather than a flat file.
In order to accomplish this magic, mod_conf_ldap needs to know
some things about the server, so that it can connect and retrieve the
configuration data. This information is provided in the "path"
to the configuration file, using proftpd's
-c/--config command-line option. The specific
"path" to use for mod_conf_ldap uses an URI-like
syntax:
ldap://hostport/dn[?attrs[?scope[?filter[?exts]]]]The syntax is long, but it has to be so in order to provide all of the information
mod_conf_ldap needs. (This information cannot be
stored in the configuration file because mod_conf_ldap will
be constructing that configuration file.)
The "ldap://" (or "ldaps://") prefix informs the FSIO API
that this "path" should be handled differently from a normal Unix
filesystem path. The hostport is a host name, with an optional
":port", defines the LDAP server to contact. The dn
is the base DN to use for search for configuration data. attrs is
a comma-separated list of attributes to request; using "*" suffices.
The scope should be "sub", to allow subtree searches.
The filter is important: it is used to define a filter for searching
for the root "server config" configuration context. Currently,
mod_conf_ldap does not support any extensions.
Here is an example of using the above syntax:
proftpd -c 'ldap:///dc=castaglia,dc=org?*?sub?(ProFTPDConfId=proftpdContext#0)'Note that the LDAP URL is explicitly enclosed in single quotes, to present it from being handled by the shell. In this URL, the hostport is empty, which thus defaults to "localhost", port 389. Using "ldaps" as the scheme would connect to port 636 by default. The
* wildcard is used to search for all attributes, and the
sub parameter allows for subtree searching. The filter used
identifies a ProFTPDConf object whose ProFTPDConfId
is "proftpdContext#0". The filter must identify one and only
one matching ProFTPDConf.
This URL path syntax can also be used as the parameter to the
Include configuration directive:
<VirtualHost 1.2.3.4>
Include ldap:///dc=castaglia,dc=org?*?sub?(ProFTPDConfId=vhostContext#1)
</VirtualHost>
This tells mod_conf_ldap to look for a ProFTPDConf
object whose id is "vhostContext#1", and then to recurse through the
contents of this "vhost" context.
The mod_conf_ldap module does not require the
mod_ldap module to be compiled or configured.
Importing Existing Configurations
While storing configuration information in LDAP directories may make some tasks
easier, it will making editing of configurations more complex. To help
with this, mod_conf_ldap is accompanied by a Perl script that
can be used to import existing proftpd.conf files into a
directory.
The conf2ldif.pl script reads a given proftpd.conf
configuration file and generates an LDIF with the information from that file.
One specifies the full path to the proftpd.conf to be imported.
Use conf2ldif.pl --help to see usage information.
Example:
conf2ldif.pl --dn=dc=castaglia,dc=org /etc/proftpd.conf > proftpd.ldif
Future Work
Future improvements to the mod_conf_ldap module wil include: