Merge branch 'master' into master

This commit is contained in:
Antoine Nguyen
2018-06-09 09:44:26 +02:00
committed by GitHub
45 changed files with 1961 additions and 187 deletions

View File

@@ -0,0 +1,213 @@
-- Amavis 2.11.0 MySQL schema
-- Provided by Modoboa
-- Warning: foreign key creations are enabled
-- local users
CREATE TABLE users (
id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, -- unique id
priority integer NOT NULL DEFAULT '7', -- sort field, 0 is low prior.
policy_id integer unsigned NOT NULL DEFAULT '1', -- JOINs with policy.id
email varbinary(255) NOT NULL UNIQUE,
fullname varchar(255) DEFAULT NULL -- not used by amavisd-new
-- local char(1) -- Y/N (optional field, see note further down)
);
-- any e-mail address (non- rfc2822-quoted), external or local,
-- used as senders in wblist
CREATE TABLE mailaddr (
id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
priority integer NOT NULL DEFAULT '7', -- 0 is low priority
email varbinary(255) NOT NULL UNIQUE
);
-- per-recipient whitelist and/or blacklist,
-- puts sender and recipient in relation wb (white or blacklisted sender)
CREATE TABLE wblist (
rid integer unsigned NOT NULL, -- recipient: users.id
sid integer unsigned NOT NULL, -- sender: mailaddr.id
wb varchar(10) NOT NULL, -- W or Y / B or N / space=neutral / score
PRIMARY KEY (rid,sid)
);
CREATE TABLE policy (
id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
-- 'id' this is the _only_ required field
policy_name varchar(32), -- not used by amavisd-new, a comment
virus_lover char(1) default NULL, -- Y/N
spam_lover char(1) default NULL, -- Y/N
unchecked_lover char(1) default NULL, -- Y/N
banned_files_lover char(1) default NULL, -- Y/N
bad_header_lover char(1) default NULL, -- Y/N
bypass_virus_checks char(1) default NULL, -- Y/N
bypass_spam_checks char(1) default NULL, -- Y/N
bypass_banned_checks char(1) default NULL, -- Y/N
bypass_header_checks char(1) default NULL, -- Y/N
virus_quarantine_to varchar(64) default NULL,
spam_quarantine_to varchar(64) default NULL,
banned_quarantine_to varchar(64) default NULL,
unchecked_quarantine_to varchar(64) default NULL,
bad_header_quarantine_to varchar(64) default NULL,
clean_quarantine_to varchar(64) default NULL,
archive_quarantine_to varchar(64) default NULL,
spam_tag_level float default NULL, -- higher score inserts spam info headers
spam_tag2_level float default NULL, -- inserts 'declared spam' header fields
spam_tag3_level float default NULL, -- inserts 'blatant spam' header fields
spam_kill_level float default NULL, -- higher score triggers evasive actions
-- e.g. reject/drop, quarantine, ...
-- (subject to final_spam_destiny setting)
spam_dsn_cutoff_level float default NULL,
spam_quarantine_cutoff_level float default NULL,
addr_extension_virus varchar(64) default NULL,
addr_extension_spam varchar(64) default NULL,
addr_extension_banned varchar(64) default NULL,
addr_extension_bad_header varchar(64) default NULL,
warnvirusrecip char(1) default NULL, -- Y/N
warnbannedrecip char(1) default NULL, -- Y/N
warnbadhrecip char(1) default NULL, -- Y/N
newvirus_admin varchar(64) default NULL,
virus_admin varchar(64) default NULL,
banned_admin varchar(64) default NULL,
bad_header_admin varchar(64) default NULL,
spam_admin varchar(64) default NULL,
spam_subject_tag varchar(64) default NULL,
spam_subject_tag2 varchar(64) default NULL,
spam_subject_tag3 varchar(64) default NULL,
message_size_limit integer default NULL, -- max size in bytes, 0 disable
banned_rulenames varchar(64) default NULL, -- comma-separated list of ...
-- names mapped through %banned_rules to actual banned_filename tables
disclaimer_options varchar(64) default NULL,
forward_method varchar(64) default NULL,
sa_userconf varchar(64) default NULL,
sa_username varchar(64) default NULL
);
-- R/W part of the dataset (optional)
-- May reside in the same or in a separate database as lookups database;
-- REQUIRES SUPPORT FOR TRANSACTIONS; specified in @storage_sql_dsn
--
-- MySQL note ( http://dev.mysql.com/doc/mysql/en/storage-engines.html ):
-- ENGINE is the preferred term, but cannot be used before MySQL 4.0.18.
-- TYPE is available beginning with MySQL 3.23.0, the first version of
-- MySQL for which multiple storage engines were available. If you omit
-- the ENGINE or TYPE option, the default storage engine is used.
-- By default this is MyISAM.
--
-- Please create additional indexes on keys when needed, or drop suggested
-- ones as appropriate to optimize queries needed by a management application.
-- See your database documentation for further optimization hints. With MySQL
-- see Chapter 15 of the reference manual. For example the chapter 15.17 says:
-- InnoDB does not keep an internal count of rows in a table. To process a
-- SELECT COUNT(*) FROM T statement, InnoDB must scan an index of the table,
-- which takes some time if the index is not entirely in the buffer pool.
--
-- Wayne Smith adds: When using MySQL with InnoDB one might want to
-- increase buffer size for both pool and log, and might also want
-- to change flush settings for a little better performance. Example:
-- innodb_buffer_pool_size = 384M
-- innodb_log_buffer_size = 8M
-- innodb_flush_log_at_trx_commit = 0
-- The big performance increase is the first two, the third just helps with
-- lowering disk activity. Consider also adjusting the key_buffer_size.
-- provide unique id for each e-mail address, avoids storing copies
CREATE TABLE maddr (
partition_tag integer DEFAULT 0, -- see $partition_tag
id bigint unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
email varbinary(255) NOT NULL, -- full mail address
domain varchar(255) NOT NULL, -- only domain part of the email address
-- with subdomain fields in reverse
CONSTRAINT part_email UNIQUE (partition_tag,email)
) ENGINE=InnoDB;
-- information pertaining to each processed message as a whole;
-- NOTE: records with NULL msgs.content should be ignored by utilities,
-- as such records correspond to messages just being processes, or were lost
-- NOTE: instead of a character field time_iso, one might prefer:
-- time_iso TIMESTAMP NOT NULL DEFAULT 0,
-- but the following MUST then be set in amavisd.conf: $timestamp_fmt_mysql=1
CREATE TABLE msgs (
partition_tag integer DEFAULT 0, -- see $partition_tag
mail_id varbinary(16) NOT NULL, -- long-term unique mail id, dflt 12 ch
secret_id varbinary(16) DEFAULT '', -- authorizes release of mail_id, 12 ch
am_id varchar(20) NOT NULL, -- id used in the log
time_num integer unsigned NOT NULL, -- rx_time: seconds since Unix epoch
time_iso char(16) NOT NULL, -- rx_time: ISO8601 UTC ascii time
sid bigint unsigned NOT NULL, -- sender: maddr.id
policy varchar(255) DEFAULT '', -- policy bank path (like macro %p)
client_addr varchar(255) DEFAULT '', -- SMTP client IP address (IPv4 or v6)
size integer unsigned NOT NULL, -- message size in bytes
originating char(1) DEFAULT ' ' NOT NULL, -- sender from inside or auth'd
content char(1), -- content type: V/B/U/S/Y/M/H/O/T/C
-- virus/banned/unchecked/spam(kill)/spammy(tag2)/
-- /bad-mime/bad-header/oversized/mta-err/clean
-- is NULL on partially processed mail
-- (prior to 2.7.0 the CC_SPAMMY was logged as 's', now 'Y' is used;
-- to avoid a need for case-insenstivity in queries)
quar_type char(1), -- quarantined as: ' '/F/Z/B/Q/M/L
-- none/file/zipfile/bsmtp/sql/
-- /mailbox(smtp)/mailbox(lmtp)
quar_loc varbinary(255) DEFAULT '', -- quarantine location (e.g. file)
dsn_sent char(1), -- was DSN sent? Y/N/q (q=quenched)
spam_level float, -- SA spam level (no boosts)
message_id varchar(255) DEFAULT '', -- mail Message-ID header field
from_addr varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '',
-- mail From header field, UTF8
subject varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '',
-- mail Subject header field, UTF8
host varchar(255) NOT NULL, -- hostname where amavisd is running
PRIMARY KEY (partition_tag,mail_id),
FOREIGN KEY (sid) REFERENCES maddr(id) ON DELETE RESTRICT
) ENGINE=InnoDB;
CREATE INDEX msgs_idx_sid ON msgs (sid);
CREATE INDEX msgs_idx_mess_id ON msgs (message_id); -- useful with pen pals
CREATE INDEX msgs_idx_time_num ON msgs (time_num);
-- alternatively when purging based on time_iso (instead of msgs_idx_time_num):
CREATE INDEX msgs_idx_time_iso ON msgs (time_iso);
-- When using FOREIGN KEY contraints, InnoDB requires index on a field
-- (an the field must be the first field in the index). Hence create it:
CREATE INDEX msgs_idx_mail_id ON msgs (mail_id);
-- per-recipient information related to each processed message;
-- NOTE: records in msgrcpt without corresponding msgs.mail_id record are
-- orphaned and should be ignored and eventually deleted by external utilities
CREATE TABLE msgrcpt (
partition_tag integer DEFAULT 0, -- see $partition_tag
mail_id varbinary(16) NOT NULL, -- (must allow duplicates)
rseqnum integer DEFAULT 0 NOT NULL, -- recip's enumeration within msg
rid bigint unsigned NOT NULL, -- recipient: maddr.id (dupl. allowed)
is_local char(1) DEFAULT ' ' NOT NULL, -- recip is: Y=local, N=foreign
content char(1) DEFAULT ' ' NOT NULL, -- content type V/B/U/S/Y/M/H/O/T/C
ds char(1) NOT NULL, -- delivery status: P/R/B/D/T
-- pass/reject/bounce/discard/tempfail
rs char(1) NOT NULL, -- release status: initialized to ' '
bl char(1) DEFAULT ' ', -- sender blacklisted by this recip
wl char(1) DEFAULT ' ', -- sender whitelisted by this recip
bspam_level float, -- per-recipient (total) spam level
smtp_resp varchar(255) DEFAULT '', -- SMTP response given to MTA
PRIMARY KEY (partition_tag,mail_id,rseqnum),
FOREIGN KEY (rid) REFERENCES maddr(id) ON DELETE RESTRICT,
FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE
) ENGINE=InnoDB;
CREATE INDEX msgrcpt_idx_mail_id ON msgrcpt (mail_id);
CREATE INDEX msgrcpt_idx_rid ON msgrcpt (rid);
-- Additional index on rs since Modoboa uses it to filter its quarantine
CREATE INDEX msgrcpt_idx_rs ON msgrcpt (rs);
-- mail quarantine in SQL, enabled by $*_quarantine_method='sql:'
-- NOTE: records in quarantine without corresponding msgs.mail_id record are
-- orphaned and should be ignored and eventually deleted by external utilities
CREATE TABLE quarantine (
partition_tag integer DEFAULT 0, -- see $partition_tag
mail_id varbinary(16) NOT NULL, -- long-term unique mail id
chunk_ind integer unsigned NOT NULL, -- chunk number, starting with 1
mail_text blob NOT NULL, -- store mail as chunks of octets
PRIMARY KEY (partition_tag,mail_id,chunk_ind),
FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE
) ENGINE=InnoDB;

View File

@@ -173,6 +173,8 @@ CREATE TABLE msgrcpt (
);
CREATE INDEX msgrcpt_idx_mail_id ON msgrcpt (mail_id);
CREATE INDEX msgrcpt_idx_rid ON msgrcpt (rid);
-- Additional index on rs since Modoboa uses it to filter its quarantine
CREATE INDEX msgrcpt_idx_rs ON msgrcpt (rs);
-- mail quarantine in SQL, enabled by $*_quarantine_method='sql:'
-- NOTE: records in quarantine without corresponding msgs.mail_id record are

View File

@@ -0,0 +1,189 @@
CREATE TABLE policy (
id serial PRIMARY KEY, -- 'id' is the _only_ required field
policy_name varchar(32), -- not used by amavisd-new, a comment
virus_lover char(1) default NULL, -- Y/N
spam_lover char(1) default NULL, -- Y/N
unchecked_lover char(1) default NULL, -- Y/N
banned_files_lover char(1) default NULL, -- Y/N
bad_header_lover char(1) default NULL, -- Y/N
bypass_virus_checks char(1) default NULL, -- Y/N
bypass_spam_checks char(1) default NULL, -- Y/N
bypass_banned_checks char(1) default NULL, -- Y/N
bypass_header_checks char(1) default NULL, -- Y/N
virus_quarantine_to varchar(64) default NULL,
spam_quarantine_to varchar(64) default NULL,
banned_quarantine_to varchar(64) default NULL,
unchecked_quarantine_to varchar(64) default NULL,
bad_header_quarantine_to varchar(64) default NULL,
clean_quarantine_to varchar(64) default NULL,
archive_quarantine_to varchar(64) default NULL,
spam_tag_level real default NULL, -- higher score inserts spam info headers
spam_tag2_level real default NULL, -- inserts 'declared spam' header fields
spam_tag3_level real default NULL, -- inserts 'blatant spam' header fields
spam_kill_level real default NULL, -- higher score triggers evasive actions
-- e.g. reject/drop, quarantine, ...
-- (subject to final_spam_destiny setting)
spam_dsn_cutoff_level real default NULL,
spam_quarantine_cutoff_level real default NULL,
addr_extension_virus varchar(64) default NULL,
addr_extension_spam varchar(64) default NULL,
addr_extension_banned varchar(64) default NULL,
addr_extension_bad_header varchar(64) default NULL,
warnvirusrecip char(1) default NULL, -- Y/N
warnbannedrecip char(1) default NULL, -- Y/N
warnbadhrecip char(1) default NULL, -- Y/N
newvirus_admin varchar(64) default NULL,
virus_admin varchar(64) default NULL,
banned_admin varchar(64) default NULL,
bad_header_admin varchar(64) default NULL,
spam_admin varchar(64) default NULL,
spam_subject_tag varchar(64) default NULL,
spam_subject_tag2 varchar(64) default NULL,
spam_subject_tag3 varchar(64) default NULL,
message_size_limit integer default NULL, -- max size in bytes, 0 disable
banned_rulenames varchar(64) default NULL, -- comma-separated list of ...
-- names mapped through %banned_rules to actual banned_filename tables
disclaimer_options varchar(64) default NULL,
forward_method varchar(64) default NULL,
sa_userconf varchar(64) default NULL,
sa_username varchar(64) default NULL
);
-- local users
CREATE TABLE users (
id serial PRIMARY KEY, -- unique id
priority integer NOT NULL DEFAULT 7, -- sort field, 0 is low prior.
policy_id integer NOT NULL DEFAULT 1 CHECK (policy_id >= 0) REFERENCES policy(id),
email bytea NOT NULL UNIQUE, -- email address, non-rfc2822-quoted
fullname varchar(255) DEFAULT NULL -- not used by amavisd-new
-- local char(1) -- Y/N (optional, see SQL section in README.lookups)
);
-- any e-mail address (non- rfc2822-quoted), external or local,
-- used as senders in wblist
CREATE TABLE mailaddr (
id serial PRIMARY KEY,
priority integer NOT NULL DEFAULT 9, -- 0 is low priority
email bytea NOT NULL UNIQUE
);
-- per-recipient whitelist and/or blacklist,
-- puts sender and recipient in relation wb (white or blacklisted sender)
CREATE TABLE wblist (
rid integer NOT NULL CHECK (rid >= 0) REFERENCES users(id),
sid integer NOT NULL CHECK (sid >= 0) REFERENCES mailaddr(id),
wb varchar(10) NOT NULL, -- W or Y / B or N / space=neutral / score
PRIMARY KEY (rid,sid)
);
-- grant usage rights:
GRANT select ON policy TO amavis;
GRANT select ON users TO amavis;
GRANT select ON mailaddr TO amavis;
GRANT select ON wblist TO amavis;
-- R/W part of the dataset (optional)
-- May reside in the same or in a separate database as lookups database;
-- REQUIRES SUPPORT FOR TRANSACTIONS; specified in @storage_sql_dsn
--
-- Please create additional indexes on keys when needed, or drop suggested
-- ones as appropriate to optimize queries needed by a management application.
-- See your database documentation for further optimization hints.
-- provide unique id for each e-mail address, avoids storing copies
CREATE TABLE maddr (
id serial PRIMARY KEY,
partition_tag integer DEFAULT 0, -- see $partition_tag
email bytea NOT NULL, -- full e-mail address
domain varchar(255) NOT NULL, -- only domain part of the email address
-- with subdomain fields in reverse
CONSTRAINT part_email UNIQUE (partition_tag,email)
);
-- information pertaining to each processed message as a whole;
-- NOTE: records with a NULL msgs.content should be ignored by utilities,
-- as such records correspond to messages just being processed, or were lost
CREATE TABLE msgs (
partition_tag integer DEFAULT 0, -- see $partition_tag
mail_id bytea NOT NULL, -- long-term unique mail id, dflt 12 ch
secret_id bytea DEFAULT '', -- authorizes release of mail_id, 12 ch
am_id varchar(20) NOT NULL, -- id used in the log
time_num integer NOT NULL CHECK (time_num >= 0),
-- rx_time: seconds since Unix epoch
time_iso timestamp WITH TIME ZONE NOT NULL,-- rx_time: ISO8601 UTC ascii time
sid integer NOT NULL CHECK (sid >= 0), -- sender: maddr.id
policy varchar(255) DEFAULT '', -- policy bank path (like macro %p)
client_addr varchar(255) DEFAULT '', -- SMTP client IP address (IPv4 or v6)
size integer NOT NULL CHECK (size >= 0), -- message size in bytes
originating char(1) DEFAULT ' ' NOT NULL, -- sender from inside or auth'd
content char(1), -- content type: V/B/U/S/Y/M/H/O/T/C
-- virus/banned/unchecked/spam(kill)/spammy(tag2)/
-- /bad-mime/bad-header/oversized/mta-err/clean
-- is NULL on partially processed mail
-- (prior to 2.7.0 the CC_SPAMMY was logged as 's', now 'Y' is used;
--- to avoid a need for case-insenstivity in queries)
quar_type char(1), -- quarantined as: ' '/F/Z/B/Q/M/L
-- none/file/zipfile/bsmtp/sql/
-- /mailbox(smtp)/mailbox(lmtp)
quar_loc varchar(255) DEFAULT '', -- quarantine location (e.g. file)
dsn_sent char(1), -- was DSN sent? Y/N/q (q=quenched)
spam_level real, -- SA spam level (no boosts)
message_id varchar(255) DEFAULT '', -- mail Message-ID header field
from_addr varchar(255) DEFAULT '', -- mail From header field, UTF8
subject varchar(255) DEFAULT '', -- mail Subject header field, UTF8
host varchar(255) NOT NULL, -- hostname where amavisd is running
CONSTRAINT msgs_partition_mail UNIQUE (partition_tag,mail_id),
PRIMARY KEY (partition_tag,mail_id)
--FOREIGN KEY (sid) REFERENCES maddr(id) ON DELETE RESTRICT
);
CREATE INDEX msgs_idx_sid ON msgs (sid);
CREATE INDEX msgs_idx_mess_id ON msgs (message_id); -- useful with pen pals
CREATE INDEX msgs_idx_time_iso ON msgs (time_iso);
CREATE INDEX msgs_idx_time_num ON msgs (time_num); -- optional
-- per-recipient information related to each processed message;
-- NOTE: records in msgrcpt without corresponding msgs.mail_id record are
-- orphaned and should be ignored and eventually deleted by external utilities
CREATE TABLE msgrcpt (
partition_tag integer DEFAULT 0, -- see $partition_tag
mail_id bytea NOT NULL, -- (must allow duplicates)
rseqnum integer DEFAULT 0 NOT NULL, -- recip's enumeration within msg
rid integer NOT NULL, -- recipient: maddr.id (duplicates allowed)
is_local char(1) DEFAULT ' ' NOT NULL, -- recip is: Y=local, N=foreign
content char(1) DEFAULT ' ' NOT NULL, -- content type V/B/U/S/Y/M/H/O/T/C
ds char(1) NOT NULL, -- delivery status: P/R/B/D/T
-- pass/reject/bounce/discard/tempfail
rs char(1) NOT NULL, -- release status: initialized to ' '
bl char(1) DEFAULT ' ', -- sender blacklisted by this recip
wl char(1) DEFAULT ' ', -- sender whitelisted by this recip
bspam_level real, -- per-recipient (total) spam level
smtp_resp varchar(255) DEFAULT '', -- SMTP response given to MTA
CONSTRAINT msgrcpt_partition_mail_rseq UNIQUE (partition_tag,mail_id,rseqnum),
PRIMARY KEY (partition_tag,mail_id,rseqnum)
--FOREIGN KEY (rid) REFERENCES maddr(id) ON DELETE RESTRICT,
--FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE
);
CREATE INDEX msgrcpt_idx_mail_id ON msgrcpt (mail_id);
CREATE INDEX msgrcpt_idx_rid ON msgrcpt (rid);
-- Additional index on rs since Modoboa uses it to filter its quarantine
CREATE INDEX msgrcpt_idx_rs ON msgrcpt (rs);
-- mail quarantine in SQL, enabled by $*_quarantine_method='sql:'
-- NOTE: records in quarantine without corresponding msgs.mail_id record are
-- orphaned and should be ignored and eventually deleted by external utilities
CREATE TABLE quarantine (
partition_tag integer DEFAULT 0, -- see $partition_tag
mail_id bytea NOT NULL, -- long-term unique mail id
chunk_ind integer NOT NULL CHECK (chunk_ind >= 0), -- chunk number, 1..
mail_text bytea NOT NULL, -- store mail as chunks of octects
PRIMARY KEY (partition_tag,mail_id,chunk_ind)
--FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE
);

View File

@@ -10,7 +10,7 @@ rate_limit_exception_networks = 127.0.0.0/8, ::1/128
[global]
backend = sql
actions = settings
action = settings
account_type = email
host = %sql_dsn
query = %sql_query

View File

@@ -96,7 +96,7 @@ auth_master_user_separator = *
# plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp skey
# gss-spnego
# NOTE: See also disable_plaintext_auth setting.
auth_mechanisms = plain
auth_mechanisms = plain login
##
## Password and user databases

View File

@@ -71,11 +71,22 @@ service imap {
# Max. number of IMAP processes (connections)
#process_limit = 1024
executable = imap postlogin
}
service pop3 {
# Max. number of POP3 processes (connections)
#process_limit = 1024
executable = pop3 postlogin
}
service postlogin {
executable = script-login /usr/local/bin/postlogin.sh
user = %modoboa_user
unix_listener postlogin {
}
}
service auth {
@@ -105,6 +116,13 @@ service auth {
group = postfix
}
# Radicale auth
%{radicale_enabled}unix_listener %{radicale_auth_socket_path} {
%{radicale_enabled} mode = 0666
%{radicale_enabled} user = %{radicale_user}
%{radicale_enabled} group = %{radicale_user}
%{radicale_enabled}}
# Auth process is run as this user.
#user = $default_internal_user
}

View File

@@ -123,7 +123,7 @@ connect = host=%dbhost dbname=%modoboa_dbname user=%modoboa_dbuser password=%mod
#user_query = \
# SELECT home, uid, gid \
# FROM users WHERE username = '%%n' AND domain = '%%d'
user_query = SELECT '%{home_dir}/%%d/%%n' AS home, %mailboxes_owner_uid as uid, %mailboxes_owner_gid as gid, CONCAT('*:bytes=', mb.quota, 'M') AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user u ON u.id=mb.user_id WHERE mb.address='%%n' AND dom.name='%%d' AND u.is_active=1 AND dom.enabled=1
user_query = SELECT '%{home_dir}/%%d/%%n' AS home, %mailboxes_owner_uid as uid, %mailboxes_owner_gid as gid, CONCAT('*:bytes=', mb.quota, 'M') AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user u ON u.id=mb.user_id WHERE mb.address='%%n' AND dom.name='%%d'
# If you wish to avoid two SQL lookups (passdb + userdb), you can use
# userdb prefetch instead of userdb sql in dovecot.conf. In that case you'll

View File

@@ -123,7 +123,7 @@ connect = host=%dbhost dbname=%modoboa_dbname user=%modoboa_dbuser password=%mod
#user_query = \
# SELECT home, uid, gid \
# FROM users WHERE username = '%%n' AND domain = '%%d'
user_query = SELECT '%{home_dir}/%%d/%%n' AS home, %mailboxes_owner_uid as uid, %mailboxes_owner_gid as gid, '*:bytes=' || mb.quota || 'M' AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user u ON u.id=mb.user_id WHERE mb.address='%%n' AND dom.name='%%d' AND u.is_active AND dom.enabled
user_query = SELECT '%{home_dir}/%%d/%%n' AS home, %mailboxes_owner_uid as uid, %mailboxes_owner_gid as gid, '*:bytes=' || mb.quota || 'M' AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user u ON u.id=mb.user_id WHERE mb.address='%%n' AND dom.name='%%d'
# If you wish to avoid two SQL lookups (passdb + userdb), you can use
# userdb prefetch instead of userdb sql in dovecot.conf. In that case you'll

View File

@@ -0,0 +1,7 @@
#!/bin/sh
DBNAME=%modoboa_dbname DBUSER=%modoboa_dbuser DBPASSWORD=%modoboa_dbpassword
echo "UPDATE core_user SET last_login=now() WHERE username='$USER'" | mysql -u $DBUSER -p$DBPASSWORD $DBNAME
exec "$@"

View File

@@ -0,0 +1,7 @@
#!/bin/sh
PATH="/usr/bin:/usr/local/bin:/bin"
psql -c "UPDATE core_user SET last_login=now() WHERE username='$USER'" > /dev/null
exec "$@"

View File

@@ -17,10 +17,11 @@ INSTANCE=%{instance_path}
%{amavis_enabled}0 0 * * * root $PYTHON $INSTANCE/manage.py qcleanup
# Notifications about pending release requests
%{amavis_enabled}0 12 * * * root $PYTHON $INSTANCE/manage.py amnotify --baseurl='http://%{hostname}'
%{amavis_enabled}0 12 * * * root $PYTHON $INSTANCE/manage.py amnotify
# Logs parsing
*/5 * * * * root $PYTHON $INSTANCE/manage.py logparser &> /dev/null
0 * * * * root $PYTHON $INSTANCE/manage.py update_statistics
# Radicale rights file
%{radicale_enabled}*/2 * * * * root $PYTHON $INSTANCE/manage.py generate_rights
@@ -30,3 +31,6 @@ INSTANCE=%{instance_path}
# Public API communication
0 * * * * root $PYTHON $INSTANCE/manage.py communicate_with_public_api
# Generate DKIM keys (they will belong to the user running this job)
%{opendkim_enabled}* * * * * %{opendkim_user} $PYTHON $INSTANCE/manage.py modo manage_dkim_keys

View File

@@ -1 +1 @@
%{user} ALL=(%{dovecot_mailboxes_owner}) NOPASSWD: /usr/bin/doveadm
%{sudo_user} ALL=(%{dovecot_mailboxes_owner}) NOPASSWD: /usr/bin/doveadm

View File

@@ -42,4 +42,5 @@ server {
uwsgi_param UWSGI_SCRIPT instance.wsgi:application;
uwsgi_pass modoboa;
}
%{extra_config}
}

View File

@@ -0,0 +1,5 @@
CREATE OR REPLACE VIEW dkim AS (
SELECT id, name as domain_name, dkim_private_key_path AS private_key_path,
dkim_key_selector AS selector
FROM admin_domain WHERE enable_dkim=1
);

View File

@@ -0,0 +1,5 @@
CREATE OR REPLACE VIEW dkim AS (
SELECT id, name as domain_name, dkim_private_key_path AS private_key_path,
dkim_key_selector AS selector
FROM admin_domain WHERE enable_dkim
);

View File

@@ -0,0 +1,91 @@
# This is a basic configuration that can easily be adapted to suit a standard
# installation. For more advanced options, see opendkim.conf(5) and/or
# /usr/share/doc/opendkim/examples/opendkim.conf.sample.
# Log to syslog
Syslog yes
SyslogSuccess Yes
LogWhy Yes
LogResults Yes
# Required to use local socket with MTAs that access the socket as a non-
# privileged user (e.g. Postfix)
UMask 007
# Sign for example.com with key in /etc/dkimkeys/dkim.key using
# selector '2007' (e.g. 2007._domainkey.example.com)
#Domain example.com
#KeyFile /etc/dkimkeys/dkim.key
#Selector 2007
KeyTable dsn:%{db_driver}://%{db_user}:%{db_password}@%{dbhost}/%{db_name}/table=dkim?keycol=id?datacol=domain_name,selector,private_key_path
SigningTable dsn:%db_driver://%{db_user}:%{db_password}@%{dbhost}/%{db_name}/table=dkim?keycol=domain_name?datacol=id
# Commonly-used options; the commented-out versions show the defaults.
#Canonicalization simple
#Mode sv
SubDomains yes
Canonicalization relaxed/relaxed
# Socket smtp://localhost
#
# ## Socket socketspec
# ##
# ## Names the socket where this filter should listen for milter connections
# ## from the MTA. Required. Should be in one of these forms:
# ##
# ## inet:port@address to listen on a specific interface
# ## inet:port to listen on all interfaces
# ## local:/path/to/socket to listen on a UNIX domain socket
#
Socket inet:%{port}@localhost
#Socket local:/var/run/opendkim/opendkim.sock
## PidFile filename
### default (none)
###
### Name of the file where the filter should write its pid before beginning
### normal operations.
#
PidFile /var/run/opendkim/opendkim.pid
# Always oversign From (sign using actual From and a null From to prevent
# malicious signatures header fields (From and/or others) between the signer
# and the verifier. From is oversigned by default in the Debian pacakge
# because it is often the identity key used by reputation systems and thus
# somewhat security sensitive.
OversignHeaders From
## ResolverConfiguration filename
## default (none)
##
## Specifies a configuration file to be passed to the Unbound library that
## performs DNS queries applying the DNSSEC protocol. See the Unbound
## documentation at http://unbound.net for the expected content of this file.
## The results of using this and the TrustAnchorFile setting at the same
## time are undefined.
## In Debian, /etc/unbound/unbound.conf is shipped as part of the Suggested
## unbound package
# ResolverConfiguration /etc/unbound/unbound.conf
## TrustAnchorFile filename
## default (none)
##
## Specifies a file from which trust anchor data should be read when doing
## DNS queries and applying the DNSSEC protocol. See the Unbound documentation
## at http://unbound.net for the expected format of this file.
# TrustAnchorFile /usr/share/dns/root.key
## Userid userid
### default (none)
###
### Change to user "userid" before starting normal operation? May include
### a group ID as well, separated from the userid by a colon.
#
UserID %{user}
ExternalIgnoreList /etc/opendkim.hosts
InternalHosts /etc/opendkim.hosts

View File

@@ -0,0 +1,3 @@
127.0.0.1
::1
localhost

View File

@@ -2,7 +2,7 @@ inet_interfaces = all
inet_protocols = ipv4
myhostname = %hostname
myorigin = $myhostname
mydestination =
mydestination = $myhostname
mynetworks = 127.0.0.0/8
smtpd_banner = $myhostname ESMTP
biff = no
@@ -28,20 +28,18 @@ proxy_read_maps =
proxy:%{db_driver}:/etc/postfix/sql-domain-aliases.cf
proxy:%{db_driver}:/etc/postfix/sql-aliases.cf
proxy:%{db_driver}:/etc/postfix/sql-relaydomains.cf
proxy:%{db_driver}:/etc/postfix/sql-relaydomains-transport.cf
proxy:%{db_driver}:/etc/postfix/sql-relaydomain-aliases-transport.cf
proxy:%{db_driver}:/etc/postfix/sql-autoreplies-transport.cf
proxy:%{db_driver}:/etc/postfix/sql-maintain.cf
proxy:%{db_driver}:/etc/postfix/sql-relay-recipient-verification.cf
proxy:%{db_driver}:/etc/postfix/sql-sender-login-mailboxes.cf
proxy:%{db_driver}:/etc/postfix/sql-sender-login-aliases.cf
proxy:%{db_driver}:/etc/postfix/sql-sender-login-mailboxes-extra.cf
proxy:%{db_driver}:/etc/postfix/sql-sender-login-map.cf
proxy:%{db_driver}:/etc/postfix/sql-spliteddomains-transport.cf
proxy:%{db_driver}:/etc/postfix/sql-transport.cf
## TLS settings
#
smtpd_use_tls = yes
smtpd_tls_auth_only = no
smtpd_tls_CApath = /etc/ssl/certs
smtpd_tls_key_file = %tls_key_file
smtpd_tls_cert_file = %tls_cert_file
smtpd_tls_dh1024_param_file = ${config_directory}/dh2048.pem
@@ -61,6 +59,7 @@ smtpd_tls_exclude_ciphers = aNULL, MD5 , DES, ADH, RC4, PSD, SRP, 3DES, eNULL
smtpd_tls_eecdh_grade = strong
# Use TLS if this is supported by the remote SMTP server, otherwise use plaintext.
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_security_level = may
smtp_tls_loglevel = 1
smtp_tls_exclude_ciphers = EXPORT, LOW
@@ -79,8 +78,8 @@ virtual_alias_maps =
relay_domains =
proxy:%{db_driver}:/etc/postfix/sql-relaydomains.cf
transport_maps =
proxy:%{db_driver}:/etc/postfix/sql-transport.cf
proxy:%{db_driver}:/etc/postfix/sql-spliteddomains-transport.cf
proxy:%{db_driver}:/etc/postfix/sql-relaydomains-transport.cf
proxy:%{db_driver}:/etc/postfix/sql-autoreplies-transport.cf
## SASL authentication through Dovecot
@@ -112,11 +111,15 @@ strict_rfc821_envelopes = yes
%{dovecot_enabled} $lmtp_sasl_auth_cache_name
%{dovecot_enabled} $address_verify_map
# OpenDKIM setup
%{opendkim_enabled}smtpd_milters = inet:127.0.0.1:%{opendkim_port}
%{opendkim_enabled}non_smtpd_milters = inet:127.0.0.1:%{opendkim_port}
%{opendkim_enabled}milter_default_action = accept
%{opendkim_enabled}milter_content_timeout = 30s
# List of authorized senders
smtpd_sender_login_maps =
proxy:%{db_driver}:/etc/postfix/sql-sender-login-mailboxes.cf
proxy:%{db_driver}:/etc/postfix/sql-sender-login-aliases.cf
proxy:%{db_driver}:/etc/postfix/sql-sender-login-mailboxes-extra.cf
proxy:%{db_driver}:/etc/postfix/sql-sender-login-map.cf
# Recipient restriction rules
smtpd_recipient_restrictions =
@@ -135,6 +138,7 @@ smtpd_recipient_restrictions =
#
postscreen_access_list =
permit_mynetworks
cidr:/etc/postfix/postscreen_spf_whitelist.cidr
postscreen_blacklist_action = enforce
# Use some DNSBL

View File

@@ -0,0 +1,9 @@
#
# Postwhite specific cron jobs
#
# Update Postscreen Whitelists
@daily root /usr/local/bin/postwhite/postwhite > /dev/null 2>&1
# Update Yahoo! IPs for Postscreen Whitelists
@weekly root /usr/local/bin/postwhite/scrape_yahoo > /dev/null 2>&1

View File

@@ -0,0 +1,161 @@
# -*- mode: conf -*-
# vim:ft=cfg
# Config file for Radicale - A simple calendar server
#
# Place it into /etc/radicale/config (global)
# or ~/.config/radicale/config (user)
#
# The current values are the default ones
[server]
# CalDAV server hostnames separated by a comma
# IPv4 syntax: address:port
# IPv6 syntax: [address]:port
# For example: 0.0.0.0:9999, [::]:9999
#hosts = 127.0.0.1:5232
# Daemon flag
#daemon = False
# File storing the PID in daemon mode
#pid =
# Max parallel connections
#max_connections = 20
# Max size of request body (bytes)
#max_content_length = 10000000
# Socket timeout (seconds)
#timeout = 10
# SSL flag, enable HTTPS protocol
#ssl = False
# SSL certificate path
#certificate = /etc/ssl/radicale.cert.pem
# SSL private key
#key = /etc/ssl/radicale.key.pem
# CA certificate for validating clients. This can be used to secure
# TCP traffic between Radicale and a reverse proxy
#certificate_authority =
# SSL Protocol used. See python's ssl module for available values
#protocol = PROTOCOL_TLSv1_2
# Available ciphers. See python's ssl module for available ciphers
#ciphers =
# Reverse DNS to resolve client address in logs
#dns_lookup = True
# Message displayed in the client when a password is needed
#realm = Radicale - Password Required
[encoding]
# Encoding for responding requests
#request = utf-8
# Encoding for storing local collections
#stock = utf-8
[auth]
# Authentication method
# Value: none | htpasswd | remote_user | http_x_remote_user
type = radicale_dovecot_auth
# Htpasswd filename
# htpasswd_filename = users
# Htpasswd encryption method
# Value: plain | sha1 | ssha | crypt | bcrypt | md5
# Only bcrypt can be considered secure.
# bcrypt and md5 require the passlib library to be installed.
# htpasswd_encryption = plain
# Incorrect authentication delay (seconds)
#delay = 1
auth_socket = %{auth_socket_path}
[rights]
# Rights backend
# Value: none | authenticated | owner_only | owner_write | from_file
type = from_file
# File for rights management from_file
file = %{config_dir}/rights
[storage]
# Storage backend
# Value: multifilesystem
type = radicale_storage_by_index
radicale_storage_by_index_fields = dtstart, dtend, uid, summary
# Folder for storing local collections, created if not present
filesystem_folder = %{home_dir}/collections
# Lock the storage. Never start multiple instances of Radicale or edit the
# storage externally while Radicale is running if disabled.
#filesystem_locking = True
# Sync all changes to disk during requests. (This can impair performance.)
# Disabling it increases the risk of data loss, when the system crashes or
# power fails!
#filesystem_fsync = True
# Delete sync token that are older (seconds)
#max_sync_token_age = 2592000
# Close the lock file when no more clients are waiting.
# This option is not very useful in general, but on Windows files that are
# opened cannot be deleted.
#filesystem_close_lock_file = False
# Command that is run after changes to storage
# Example: ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "Changes by "%%(user)s)
#hook =
[web]
# Web interface backend
# Value: none | internal
type = none
[logging]
# Logging configuration file
# If no config is given, simple information is printed on the standard output
# For more information about the syntax of the configuration file, see:
# http://docs.python.org/library/logging.config.html
#config = /etc/radicale/logging
# Set the default logging level to debug
debug = False
# Store all environment variables (including those set in the shell)
#full_environment = False
# Don't include passwords in logs
#mask_passwords = True
[headers]
# Additional HTTP headers
#Access-Control-Allow-Origin = *

View File

@@ -0,0 +1,8 @@
[program:radicale]
autostart=true
autorestart=true
command=%{venv_path}/bin/radicale -C %{config_dir}/config
directory=%{home_dir}
redirect_stderr=true
user=%{user}
numprocs=1

View File

@@ -75,7 +75,3 @@ loadplugin Mail::SpamAssassin::Plugin::MIMEHeader
# ReplaceTags
#
loadplugin Mail::SpamAssassin::Plugin::ReplaceTags
# DCC - perform DCC message checks.
#
loadplugin Mail::SpamAssassin::Plugin::DCC