mod_dbacl
The mod_dbacl module is used to map commands/requests to
ACLs, and then to look up the ACLs/permissions for the path/file in question,
on a per-command/request basis, from a SQL table. Thus the
mod_dbacl module allows the use of SQL tables for controlling
permissions of files, directories, etc on the server.
Installation instructions are discussed here.
The most current version of mod_dbacl 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.
2011-05-11: Thanks to Ben Timby <btimby at gmail.com> for providing the path splitting idea and suggested lookup query.
<VirtualHost>, <Global>
The DBACLEngine directive enables or disables the
mod_dbacl module.
<VirtualHost>, <Global>
The DBACLPolicy directive configures the default policy to use,
when mod_dbacl is unable to retrieve the ACL setting from the
SQL table, e.g. due to database misconfiguration or due to lack of
database entries for the paths/ACLs in question.
The default DBACLPolicy setting of "allow" is
highly recommended. You should only use "DBACLPolicy deny" if you need
to have a "fail-closed" system of permissions on your server.
<VirtualHost>, <Global>
The DBACLSchema directive can be used to override the
default SQL table and column names expected by the mod_dbacl
module. More details on the SQL schema used by this module can be found in
the usage section.
<VirtualHost>, <Global>
The DBACLWhereClause directive configures an additional clause
to add to the SQL WHERE clause constructed by
mod_dbacl. The configured WHERE clause can be
used to look up user/group-specific ACLs, for example.
Example WHERE clause of user-specific lookups:
DBACLWhereClause "user = '%u'"Note: If you use
DBACLWhereClause, make sure that
the columns named in the WHERE clause also have indexes on them,
so that the SQL query can be executed more quickly.
mod_dbacl, copy the mod_dbacl.c file into
the third-party module area in the proftpd source code:
cp mod_dbacl.c proftpd-dir/contrib/after unpacking the latest proftpd-1.3.x source code. For including
mod_dbacl as a staticly linked module:
./configure --with-modules=mod_dbacl:mod_sql ...Alternatively,
mod_dbacl can be built as a DSO module:
./configure --enable-dso --with-shared=mod_dbacl ...Then follow the usual steps:
make make install
Since the mod_dbacl module looks up ACLs/permissions from
SQL tables, it requires that the mod_sql module (and a
mod_sql module such as mod_sql_mysql,
mod_sql_postgres, mod_sql_sqlite, etc) be
used. For example, your configure command to build
proftpd might look like:
# ./configure --with-modules=mod_sql:mod_sql_sqlite:mod_dbacl ...
Mapping Commands/Requests to ACLs
The mod_dbacl works by first mapping each command/request to
a specific ACL (i.e. a "permission group"), and then looking for the
value for that ACL/path pair in the SQL table.
The ACLs currently supported by mod_dbacl, and the
commands/requests for those ACLs, are:
| ACL | Commands | |
READ |
RETR |
|
WRITE |
APPE, STOR, STOU |
|
DELETE |
DELE, RMD, XRMD |
|
CREATE |
MKD, XMKD, LINK, SYMLINK |
|
MODIFY |
MFF, MFMT, SITE CHGRP, SITE CHMOD, SETSTAT, FSETSTAT |
|
MOVE |
RNFR, RNTO, SITE CPTO, RENAME |
|
VIEW |
LIST, MDTM, MLSD, MLST, NLST, SIZE, STAT, LSTAT, OPENDIR, READLINK |
|
NAVIGATE |
CDUP, XCDUP, CWD, XCWD, PWD, XPWD, REALPATH |
Use the NAVIGATE ACL with caution. Many clients, both FTP
and SFTP, will not function properly if they are unable to execute commands
such as PWD or REALPATH. If you do use
the NAVIGATE ACL, make sure that it restricts only very specific
areas of your filesystem.
Splitting Paths into Component List
Once the command/request has been mapped to its ACL, the mod_dbacl
looks at the path to the file/directory being requested by the client.
Note that mod_dbacl always works on absolute paths;
it resolves the path as sent by the client into the absolute path, regardless
of any chroot(2) which may be in effect for the session.
The path-splitting algorithm takes a path like:
/home/user/dir/file.txtand breaks it down into a list of ever-more specific paths, like this:
/home /home/user /home/user/dir /home/user/dir/file.txtArmed with this list, the
mod_dbacl module can look for the
closest-matching path in the SQL table, if any, which covers the path
requested by the client.
This approach allows administrators to configure ACLs that cover broad ranges of filesystems (e.g. "/var") to very specific files, as they need.
Database Schema
So what does the database schema used by mod_dbacl look like?
Here's an example SQLite script, which creates the table used by
mod_dbacl, using the default table and column names:
CREATE TABLE ftpacl (
path TEXT NOT NULL,
read_acl TEXT,
write_acl TEXT,
delete_acl TEXT,
create_acl TEXT,
modify_acl TEXT,
move_acl TEXT,
view_acl TEXT,
navigate_acl TEXT
);
CREATE INDEX ftpacl_path_idx ON ftpacl (path);
Note that creating an index on the ftpacl.path column
is strongly recommended. Without an index on that column, your
mod_dbacl lookups will be quite slow.
The string values which can appear in the ACL columns can be any of the following:
mod_dbacl will deny that request.
Module Configuration
Configuring the mod_dbacl module is quite simple, as most of
the configuration lies in the SQL tables. To enable mod_dbacl
and use the default table/column names, simply use:
<IfModule mod_dbacl.c>
DBACLEngine on
</IfModule>
That's it!
Example Command
To illustrate all of this, let's take a common FTP command and walk through
how mod_dbacl would work. First, the FTP client (after
authenticating) sends a RETR command to download a file:
RETR dir/file.txt
The RETR command is mapped to its ACL, i.e. the "READ" ACL.
Then the path is resolved to the absolute path, then split into a list,
i.e.:
/home /home/user /home/user/dir /home/user/dir/file.txt
With the ACL and the path list, mod_dbacl builds up the SQL
query to use:
SELECT read_acl FROM ftpacl
WHERE path IN ('/home',
'/home/user',
'/home/user/dir',
'/home/user/dir/file.txt')
ORDER BY LENGTH(path) DESC LIMIT 1
In the ftpacl database table, assume the following rows are
present:
|--------------------------------------------------| | PATH | READ_ACL | |--------------------------------------------------| | /home | false | | /home/user/dir | false | | /home/user/dir/file.txt | true | |--------------------------------------------------|The longest matching path in the table is "/home/user/dir/file.txt", which matches the path being download by the FTP client. The value for the
ftpacl.read_acl column is "true", thus mod_dbacl
allows the command to proceed.
Note that mod_dbacl does not override any
<Directory>/<Limit> sections which may
also be configured, nor does it override the underlying filesystem permissions.
Logging/Debugging
Rather than having its own separate log file, the mod_dbacl
module uses the "dbacl" trace log channel in the TraceLog. Thus to enable logging
for mod_dbacl, in order to debug configuration issues, you would
use the following in your proftpd.conf:
TraceLog /path/to/ftpd/trace.log Trace dbacl:20 ...
SFTP/SCP Interoperability
The mod_dbacl does work with the mod_sftp module
such that SFTP requests are also handled/processed, just as FTP commands are
handled. Note that SCP transfers may not work as expected with
mod_dbacl yet (notably directory creation for recursive SCP
uploads).