dovecot_config_version = 2.4.0
dovecot_storage_version = 2.4.0

#
# Default limits
#
default_client_limit = 4096
default_process_limit = 500

# Limit the process's address space. When the space is reached, some memory
# allocations may start failing with "Out of memory", or the kernel may kill
# the process with signal 9. This setting is mainly intended to prevent memory
# leaks from eating up all of the memory, but there can be also legitimate
# reasons why the process reaches this limit. For example a huge mailbox may
# not be accessed if this limit is too low.
# The default value (18446744073709551615 = 2^64-1) sets the limit to
# `default_vsz_limit`, while 0 disables the limit entirely.
default_vsz_limit = unlimited

# Listen addresses.
#   - '*' means all available IPv4 addresses.
#   - '[::]' means all available IPv6 addresses.
# Listen on all available addresses by default
listen = * [::]

# Enabled mail protocols.
protocols = pop3 imap sieve lmtp

# Plugins
mail_plugins {
    acl = yes
    mail_log = yes
    notify = yes
    quota = yes
}

# Required by OpenBSD
base_dir = /run/dovecot

# User/group who owns the message files:
mail_uid = 2000
mail_gid = 2000

# Assign uid to virtual users.
first_valid_uid = 2000
last_valid_uid = 2000

# Debug
# Enables logging all failed authentication attempts.
#auth_verbose = yes

# Enables all authentication debug logging. Passwords are logged as `<hidden>`.
#log_debug = category=auth

# Removes password hiding.
#auth_debug_passwords = yes

# If authentication fails, this setting logs the used password.
# If you don't really need to know what the password itself was, but are more
# interested in knowing if the user is simply trying to use the wrong password
# every single time or if it's a brute force attack, you can set this to sha1
# and only the SHA1 of the password is logged. That's enough to know if the
# password is same or different between login attempts.
#auth_verbose_passwords = no
#auth_verbose_passwords = plain
#auth_verbose_passwords = sha1

# Enables all kinds of mail related debug logging, such as showing where
# Dovecot is looking for mails.
#log_debug = category=mail

# Enables logging SSL errors and warnings.
# Even without this setting if connection is closed because of an SSL error,
# the error is logged as the disconnection reason.
#verbose_ssl = category=ssl

#log_debug = category=fts
#log_debug = category=ldap

# logging
log_path = syslog
syslog_facility = local5

# Login log elements.
# Add '%k' for detailed SSL protocol and cipher information.
# e.g. "TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)"
#login_log_format_elements = user=<%{user}> method=%m rip=%r lip=%l %c %k

# Mail delivery log format
#deliver_log_format = from=%{from}, envelope_sender=%{from_envelope}, subject=%{subject}, msgid=%m, size=%{size}, delivery_time=%{delivery_time}ms, %$

# Authentication mechanisms.
auth_mechanisms = PLAIN LOGIN

# Authentication related settings.
# Append this domain name if client gives empty realm.
#auth_default_domain =

auth_allow_cleartext = no

# IP addresses/ranges specified by login_trusted_networks setting are assumed
# to be secure.
login_trusted_networks =

# Mailbox format and path.
mail_driver = %{userdb:mail_driver | default("maildir") | lower}
mail_path = %{userdb:mail_path | default("~/Maildir")}

# The maximum number of IMAP connections allowed for a user from each IP address.
# Maximum number of IMAP connections allowed for a user from each IP address.
# NOTE: The username is compared case-sensitively.
# Default is 10.
mail_max_userip_connections = 30


# SSL: Global settings.
# Refer to wiki site for per protocol, ip, server name SSL settings:
# http://wiki2.dovecot.org/SSL/DovecotConfiguration
ssl = required

ssl_min_protocol = TLSv1.2
# log_debug = category=ssl

ssl_server_cert_file = /etc/ssl/certs/iRedMail.crt
ssl_server_key_file = /etc/ssl/private/iRedMail.key
ssl_server_dh_file = /etc/ssl/dh2048_param.pem
ssl_server_prefer_ciphers = server
ssl_cipher_list = EECDH+CHACHA20:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH

# Master user.
# Master users are able to log in as other users. It's also possible to
# directly log in as any user using a master password, although this isn't
# recommended.
# Reference: http://wiki2.dovecot.org/Authentication/MasterUsers
auth_master_user_separator = *

passdb passwd-file {
    master = yes
    passwd_file_path = /etc/dovecot/dovecot-master-users
    result_success = continue
}

# `mailbox_list_index = yes` can help a lot by replying to IMAP STATUS (and
# similar) lookups from a single index without having to open each mailbox
# index separately.
# This is the default in v2.3+.
mailbox_list_index = yes

# Assume that the list index is up-to-date.
mailbox_list_index_very_dirty_syncs = yes

# Maximum IMAP command line length. Some clients generate very long command
# lines with huge mailboxes, so you may need to raise this if you get
# "Too long argument" or "IMAP command line too large" errors often.
# Defaults to 64k.
imap_max_line_length = 2m

sql_driver = mysql

mysql 127.0.0.1 {
    port = 3306
    dbname = vmail
    user = vmailadmin
    password = IdWPrT8a6Fwxc69zUCGB7TSryzbLRGAw
}


dict_server {
    dict acl {
        driver = sql

        dict_map shared/shared-boxes/user/$to/$from {
            sql_table = share_folder
            value_field dummy {
            }

            key_field from_user {
                value = $from
            }
            key_field to_user {
                value = $to
            }
        }

        dict_map shared/shared-boxes/anyone/$from {
            sql_table = anyone_shares
            value_field dummy {
            }

            key_field from_user {
                value = $from
            }
        }
    }

    dict lastlogin {
        driver = sql

        dict_map shared/last-login/imap/$user/$domain {
            sql_table = last_login
            value_field imap {
                type = uint
            }

            key_field username {
                value = $user
            }

            key_field domain {
                value = $domain
            }
        }

        dict_map shared/last-login/pop3/$user/$domain {
            sql_table = last_login
            value_field pop3 {
                type = uint
            }

            key_field username {
                value = $user
            }

            key_field domain {
                value = $domain
            }
        }

        dict_map shared/last-login/lda/$user/$domain {
            sql_table = last_login
            value_field lda {
                type = uint
            }

            key_field username {
                value = $user
            }

            key_field domain {
                value = $domain
            }
        }

        # Treat lmtp as lda
        dict_map shared/last-login/lmtp/$user/$domain {
            sql_table = last_login
            value_field lda {
                type = uint
            }

            key_field username {
                value = $user
            }

            key_field domain {
                value = $domain
            }
        }
    }
}

#
# Virtual mail accounts.
#

userdb sql {
    iterate_query = SELECT username AS user FROM mailbox

    # Use COALESCE(NULLIF(...)) to prevent empty value.
    query = SELECT \
            LOWER('%{user | lower}') AS master_user, \
            LOWER(CONCAT(mailbox.storagebasedirectory, '/', mailbox.storagenode, '/', mailbox.maildir)) AS home, \
            COALESCE(NULLIF(mailbox.mailboxformat, ''), 'maildir') AS mail_driver, \
            CONCAT("~/", COALESCE(NULLIF(mailbox.mailboxfolder, ''), 'Maildir')) AS mail_path, \
            CONCAT('*:bytes=', mailbox.quota*1048576) AS quota_rule \
        FROM mailbox,domain \
       WHERE mailbox.username='%{user | lower}' \
             AND mailbox.domain='%{user | domain | lower}' \
             AND mailbox.`enable%{protocol | lower}%{secured | lower}`=1 \
             AND mailbox.domain=domain.domain \
             AND domain.backupmx=0 \
             AND domain.active=1 \
             AND mailbox.active=1
}

passdb sql {
    query = SELECT mailbox.password, mailbox.allow_nets \
        FROM mailbox,domain \
       WHERE mailbox.username='%{user | lower}' \
             AND mailbox.`enable%{protocol | lower}%{secured | lower}`=1 \
             AND mailbox.active=1 \
             AND mailbox.domain=domain.domain \
             AND domain.active=1
}

#
# Namespaces
#
namespace inbox {
    type = private
    separator = /
    prefix =
    inbox = yes

    # Sent
    mailbox Sent {
        auto = subscribe
        special_use = \Sent
    }
    mailbox "Sent Messages" {
        auto = no
        special_use = \Sent
    }
    mailbox "Sent Items" {
        auto = no
        special_use = \Sent
    }

    mailbox Drafts {
        auto = subscribe
        special_use = \Drafts
    }

    # Trash
    mailbox Trash {
        auto = subscribe
        special_use = \Trash
    }

    mailbox "Deleted Messages" {
        auto = no
        special_use = \Trash
    }

    # Junk
    mailbox Junk {
        auto = subscribe
        special_use = \Junk
        fts_autoindex = no
    }

    mailbox Spam {
        auto = no
        special_use = \Junk
        fts_autoindex = no
    }

    mailbox "Junk E-mail" {
        auto = no
        special_use = \Junk
        fts_autoindex = no
    }
}

namespace shared {
    type = shared
    separator = /
    prefix = Shared/$user/
    mail_driver = maildir
    mail_path = %{owner_home}/Maildir
    mail_index_private_path = ~/Maildir/shared/%{owner_user}
    # not share the index files between users
    mail_index_path = ~/Maildir/shared/%{owner_user}

    # this namespace should handle its own subscriptions or not.
    subscriptions = yes
    list = children
}

# Public mailboxes.
# https://doc.dovecot.org/2.4.1/core/config/shared_mailboxes.html#public-shared-mailboxes
#namespace {
#    type = public
#    separator = /
#    prefix = Public/
#    mail_driver = maildir
#    mail_path = /var/vmail/public
#    subscriptions = no
#
#    # Per-user \Seen Flag
#    mail_index_private_path = ~/Maildir/public
#}

#
# Protocols
#
# Store METADATA information within user's Maildir directory
mail_attribute {
    dict file {
        path = ~/dovecot-attributes
    }
}

# Avoid spending excessive time waiting for the quota calculation to finish
# when mails' vsizes aren't already cached. If this many mails are opened,
# finish the quota calculation on background in indexer-worker process. Mail
# deliveries will be assumed to succeed, and explicit quota lookups will
# return internal error.
protocol !indexer-worker {
    mail_vsize_bg_after_count = 100
}

protocol imap {
    mail_plugins {
        imap_quota = yes
        imap_acl = yes

        # This will only enable support for administrator scripts.
        imap_sieve = yes
        last_login = yes
    }

    imap_client_workarounds = tb-extra-mailbox-sep
    imap_metadata = yes
}

protocol pop3 {
    mail_plugins {
        last_login = yes
    }

    pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
    pop3_uidl_format = %{uid | hex(8)}%{uidvalidity | hex(8)}

    # POP3 logout format string:
    #  %i - total number of bytes read from client
    #  %o - total number of bytes sent to client
    #  %t - number of TOP commands
    #  %p - number of bytes sent to client as a result of TOP command
    #  %r - number of RETR commands
    #  %b - number of bytes sent to client as a result of RETR command
    #  %d - number of deleted messages
    #  %m - number of messages (before deletion)
    #  %s - mailbox size in bytes (before deletion)
    # Default format doesn't have 'in=%i, out=%o'.
    #pop3_logout_format = top=%t/%p, retr=%r/%b, del=%d/%m, size=%s, in=%i, out=%o
}

protocol lda {
    mail_plugins {
        sieve = yes
        last_login = yes
    }

    lda_mailbox_autocreate = yes
    lda_mailbox_autosubscribe = yes
}

protocol lmtp {
    mail_plugins {
        sieve = yes
        last_login = yes
    }

    # Address extension delivery
    lmtp_save_to_detail_mailbox = yes
    recipient_delimiter = +
}

#
# Services
#
# FYI: https://wiki2.dovecot.org/Authentication/Penalty
# Dovecot anvil process tracks authentication penalties for different IPs to
# slow down brute force login attempts.
service anvil {
    # there can be only one master process.
    #process_limit = 1

    unix_listener anvil-auth-penalty {
        user = vmail
        group = vmail
        # Set mode to 0 to completely disable penalty.
        mode = 0660
    }
}

service auth {
    # should be large enough to handle all the simultaneous connections.
    # Typically only login processes use long lasting auth connections, while
    # other processes do only quick lookups and disconnect afterwards.
    #client_limit = 4096

    # there can be only one auth master process
    #process_limit = 1

    # Auth socket
    unix_listener /var/spool/postfix/private/dovecot-auth {
        user = vmail
        group = vmail
        mode = 0666
    }

    unix_listener auth-master {
        user = vmail
        group = vmail
        mode = 0666
    }

    unix_listener auth-userdb {
        user = vmail
        group = vmail
        mode = 0660
    }
}

service dict {
    unix_listener dict {
        mode = 0660
        user = vmail
        group = vmail
    }
}

# Login processes. Refer to Dovecot wiki for more details:
# http://wiki2.dovecot.org/LoginProcess
service imap-login {
    # Maximum number of simultaneous client connections per process. Once this
    # number of connections is received, the next incoming connection will
    # prompt Dovecot to spawn another process.
    # If set to 0, default_client_limit is used instead.
    #client_limit = 0

    # vsz_limit should be fine at its default 64MB value
    #vsz_limit = 64M
    inet_listener imap {
        name = imap
        port = 143
    }

    inet_listener imaps {
        name = imaps
        port = 993
        ssl = yes
    }
}

service imap {
    #process_limit = 4096

    # required by imap-hibernate
    unix_listener imap-master {
        user = vmail
        group = vmail
        mode = 0666
    }
}

service pop3 {
    #process_limit = 4096
}

# LMTP server (Local Mail Transfer Protocol).
# Reference: http://wiki2.dovecot.org/LMTP
service lmtp {
    user = vmail

    # For higher volume sites, it may be desirable to increase the number of
    # active listener processes. A range of 5 to 20 is probably good for most
    # sites.
    process_min_avail = 5

    # Logging.
    # Require 'log_path =' in 'protocol lmtp {}' block.
    executable = lmtp -L

    # Listening on socket file and TCP
    #unix_listener dovecot-lmtp {
    #    user = postfix
    #    group = postfix
    #    mode = 0600
    #}

    inet_listener lmtp {
        listen = 127.0.0.1
        port = 24
    }
}

service managesieve-login {
    inet_listener sieve {
        listen = 127.0.0.1
        port = 4190
    }
}

service pop3-login {
    #client_limit = 0
    #process_limit = 0
    #process_min_avail =

    inet_listener pop3 {
        name = pop3
        port = 110
    }

    inet_listener pop3s {
        name = pop3s
        port = 995
        ssl = yes
    }
}

service quota-warning {
    executable = script /usr/local/bin/dovecot-quota-warning.sh
    user = vmail

    unix_listener quota-warning {
        user = vmail
        group = vmail
        mode = 0660
    }
}

# quota plugin: count
# `count` driver doesn't have any additional parameters.
quota "User quota" {
}
# Allows message deliveries to exceed quota once by this amount.
# After the quota is already over the limit, the grace no longer applies.
quota_storage_grace = 30M

# Quota warning.
# Configure the highest limits first.
quota user {
  warning warn-95 {
    quota_storage_percentage = 95
    execute quota-warning {
      args = 95 %{user}
    }
  }
  warning warn-90 {
    quota_storage_percentage = 90
    execute quota-warning {
      args = 90 %{user}
    }
  }
  warning warn-85 {
    quota_storage_percentage = 85
    execute quota-warning {
      args = 85 %{user}
    }
  }
  warning warn-under {
    quota_storage_percentage = 100
    # user is no longer over quota
    threshold = under
    execute quota-warning {
      args = below %{user}
    }
  }
}

# The maximum number of redirect actions that can be performed during a single
# script execution.
sieve_max_redirects = 30

# Use recipient as vacation message sender instead of null sender (<>).
sieve_vacation_send_from_recipient = yes

# Specifies what envelope sender address is used for redirected messages.
# Requires pigeonhole v0.4.4+.
#
# Normally, the Sieve "redirect" command copies the sender address for the
# redirected message from the processed message. So, the redirected message
# appears to originate from the original sender.
sieve_redirect_envelope_from = recipient

sieve_duplicate_default_period = 1h
sieve_duplicate_max_period = 1d

sieve_script global {
    type = global
    driver = file
    path = /var/vmail/sieve
}

sieve_script before {
    type = before
    driver = file
    path = /var/vmail/sieve/dovecot.sieve
}

sieve_script personal {
    type = personal
    driver = file
    path = ~/sieve/dovecot.sieve
}

# plugin: mail_log
# https://doc.dovecot.org/main/core/plugins/mail_log.html
mail_log_events = delete undelete expunge copy save mailbox_create mailbox_delete mailbox_rename
mail_log_fields = uid box msgid size from subject flags
#mail_log_cached_only = yes

# plugin: acl
# https://doc.dovecot.org/main/core/plugins/imap_acl.html
# ACL and share folder
acl_driver = vfile
acl_globals_only = no

acl_sharing_map {
    dict proxy {
        name = acl
    }
}

# By default Dovecot doesn't allow using the IMAP "anyone" or
# "authenticated" identifier, because it would be an easy way to spam
# other users in the system. If you wish to allow it,
#imap_acl_allow_anyone = no

# plugin: last-login.
# https://doc.dovecot.org/main/core/plugins/last_login.html
last_login {
    dict proxy {
        name = lastlogin
    }
    key = last-login/%{service}/%{user}/%{user | domain}
}
