## Dovecot configuration file

# NOTICE FOR CPANEL SYSTEMS
# On cPanel servers this file is generated by combining a
# template at /var/cpanel/templates/dovecot/main.default
# and a datastore at /var/cpanel/conf/dovecot/main
#
# The template may be customized by making a copy of it at
# /var/cpanel/templates/dovecot/main.local
# similar to the way in which httpd.conf can be customized
#
# Direct edits of the rendered dovecot.conf file will not
# be preserved when dovecot is updated.  Use the
# "Mailserver Configuration" interface in WebHostManager instead.

# See https://doc.dovecot.org for config explanations and examples.
# We have removed most commentary from this file if a setting is unused
# for brevity's sake.

##
## GLOBAL settings
##

# NOTE: if dovecot_config_version does not equal the dovecot version,
# pigeonhole won't work and cause dovecot to fail to start.
# As far as I can tell, dovecot_storage_version does nothing, as you can
# specify 2.3 or 2.4 and it acts exactly the same way. Basically pointless.
dovecot_config_version =2.4.4
dovecot_storage_version = 2.4.4

# Protocols we want to be serving: imap pop3 sieve
# If you only want to use dovecot-auth, you can set this to "none".
protocols = lmtp imap pop3 sieve

verbose_proctitle = yes

##
## Includes
##

# SSL & SNI hosts
!include_try /etc/dovecot/ssl.conf
!include_try /etc/dovecot/sni.conf

##
## Login processes
##

##
## Mailbox locations and namespaces
##
namespace inbox {
   type = private

   # Hierarchy separator to use. You should use the same separator for all
   # namespaces or some clients get confused. '/' is usually a good one.
   # The default however depends on the underlying mail storage format.
   separator = .

   # Prefix required to access this namespace. This needs to be different for
   # all namespaces. For example "Public/".
   prefix = INBOX.

   # There can be only one INBOX, and this setting defines which namespace
   # has it.
   inbox = yes

  mailbox Drafts {
    special_use = \Drafts
    auto = subscribe
  }

  mailbox spam {
    special_use = \Junk
    auto = subscribe
  }

  mailbox Trash {
    special_use = \Trash
    auto = subscribe
    autoexpunge = 30d
    quota_ignore = yes
  }

  mailbox INBOX {
    # Workaround for legacy INBOX.INBOX double-counting issue (CPANEL-23733, CPANEL-51255)
    # The filesystem path .INBOX.INBOX appears as "INBOX" in the namespace due to the "INBOX." prefix
    # This prevents double-counting quota for migrated Courier accounts
    quota_ignore = yes
    auto = no
  }

  mailbox *@* {
    # System accounts: Ignore subaccount folders matching *@* pattern
    # These folders are created for email subaccounts and should not count toward main account quota
    quota_ignore = yes
    auto = no
  }

  mailbox Sent {
    special_use = \Sent
    auto = subscribe
  }

  mailbox "Sent Messages" {
    special_use = \Sent
    auto = no
  }

  mailbox Archive {
    special_use = \Archive
    auto = create
  }

  mailbox "Archives" {
    special_use = \Archive
    auto = no
  }
}

##
## Mail processes
##

# Valid UID range for users, defaults to 500 and above. This is mostly
# to make sure that users can't log in as daemons or other system users.
# Note that denying root logins is hardcoded to dovecot binary and can't
# be done even if first_valid_uid is set to 0.
first_valid_uid = 201

# List of plugins that *specifically need to be initialized* in the global scope.
# Plugins specific to IMAP, LDA, etc. *replace* this list in their own
# configuration scopes on Dovecot 2.4.
mail_plugins {
    mail_compress = yes
    quota         = yes
    quota_clone   = yes
}

# Set various plugin related settings we want globally after.
# Global quota configuration for Dovecot 2.4
# This stuff used to be over in Cpanel/MailAuth/Dovecot.pm, but you can't do
# that anymore per user on dovecot 2.4 other than overriding things like
# quota_driver.
quota Mailbox {
}

quota "cPanel Account" {
    driver = fs
}

# Dovecot 2.4.2: quota_clone dict path uses %{userdb:X} format for variable expansion
# Note: Changed from ${userdb:X} to %{userdb:X} syntax for Dovecot 2.4.2 compatibility
# The userdb response can still override this with quota_clone_dict_file_path if needed
quota_clone {
    dict file {
        path = %{userdb:mail_path}/dovecot-quota
    }
}

# You can execute a given command when user exceeds a specified quota limit.
# Each quota root has separate limits. Only the command for the first
# exceeded limit is executed, so put the highest limit first.
# Note that % needs to be escaped as %%, otherwise "% " expands to empty.
#   quota_warning = storage=95%% /usr/local/bin/quota-warning.sh 95
#   quota_warning2 = storage=80%% /usr/local/bin/quota-warning.sh 80
quota_exceeded_message = "Mailbox is full / Blocks limit exceeded / Inode limit exceeded"

# ACL plugin. vfile backend reads ACLs from "dovecot-acl" file from maildir
# directory. You can also optionally give a global ACL directory path where
# ACLs are applied to all users' mailboxes. The global ACL directory contains
# one file for each mailbox, eg. INBOX or sub.mailbox. cache_secs parameter
# specifies how many seconds to wait between stat()ing dovecot-acl file
# to see if it changed.
acl_driver = vfile

##
## Mailbox handling optimizations
##

# Mailbox list indexes can be used to optimize IMAP STATUS commands. They are
# also required for IMAP NOTIFY extension to be enabled.
mailbox_list_index = yes

# When IDLE command is running, mailbox is checked once in a while to see if
# there are any new mails or other changes. This setting defines the minimum
# time to wait between those checks. Dovecot can also use inotify and
# kqueue to find out immediately when changes occur.
mailbox_idle_check_interval = 30 secs

# Max number of mails to keep open and prefetch to memory. This only works with
# some mailbox formats and/or operating systems.
mail_prefetch_count = 20

protocol !indexer-worker {
}

##
## Maildir-specific settings
##

# By default LIST command returns all entries in maildir beginning with a dot.
# Enabling this option makes Dovecot return only entries which are directories.
# This is done by stat()ing each entry, so it causes more disk I/O.
# (For systems setting struct dirent->d_type, this check is free and it's
# done always regardless of this setting)
maildir_stat_dirs = yes

# When copying a message, do it with hard links whenever possible. This makes
# the performance much better, and it's unlikely to have any side effects.
maildir_copy_with_hardlinks = yes

# Assume Dovecot is the only MUA accessing Maildir: Scan cur/ directory only
# when its mtime changes unexpectedly or when we can't find the mail otherwise.
maildir_very_dirty_syncs = yes

# If enabled, Dovecot doesn't use the S=<size> in the Maildir filenames for
# getting the mail's physical size, except when recalculating Maildir++ quota.
# This can be useful in systems where a lot of the Maildir filenames have a
# broken size. The performance hit for enabling this is very small.
maildir_broken_filename_sizes = yes

# Disable the maildir breaking default behavior of
# mail_attachment_detection_options, as setting ANY flag forces you out of new/
# and into cur/
mail_attachment_detection_options =

##
## mdbox-specific settings
##

# Maximum dbox file size until it's rotated.
mdbox_rotate_size = 10M

# Maximum dbox file age until it's rotated. Typically in days. Day begins
# from midnight, so 1d = today, 2d = yesterday, etc. 0 = check disabled.
# Defined but not truthy, thus 0.
mdbox_rotate_interval = 0

##
## IMAP specific settings
##

protocol imap {
  # If nothing happens for this long while client is IDLEing, move the connection
  # to imap-hibernate process and close the old imap process. This saves memory,
  # because connections use very little memory in imap-hibernate process. The
  # downside is that recreating the imap process back uses some resources.
  imap_hibernate_timeout = 30s

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

  # Sadly, defining mail_plugins *overwrites* the global setting in this scope.
  # It is not an "append only" operation. Thus if you want anything other than
  # the globals, you need to specify what globals you want as well, making the
  # global set seem somewhat wasteful but for the fact that not doing this
  # usually leads to a broken config, as some plugins need to be *initialized*
  # in the global scope first to work properly.
  mail_plugins = acl quota imap_quota mail_compress virtual

  # IMAP logout format string:
  #  %{input} - total number of bytes read from client
  #  %{output} - total number of bytes sent to client
  #  %{fetch_hdr_count} - Number of mails with mail header data sent to client
  #  %{fetch_hdr_bytes} - Number of bytes with mail header data sent to client
  #  %{fetch_body_count} - Number of mails with mail body data sent to client
  #  %{fetch_body_bytes} - Number of bytes with mail body data sent to client
  #  %{deleted} - Number of mails where client added \Deleted flag
  #  %{expunged} - Number of mails that client expunged, which does not
  #                include automatically expunged mails
  #  %{autoexpunged} - Number of mails that were automatically expunged after
  #                    client disconnected
  #  %{trashed} - Number of mails that client copied/moved to the
  #               special_use=\Trash mailbox.
  #  %{appended} - Number of mails saved during the session
  imap_logout_format = in=%i out=%o deleted=%{deleted} expunged=%{expunged} trashed=%{trashed} hdr_count=%{fetch_hdr_count}

  # How many seconds to wait between "OK Still here" notifications when
  # client is IDLEing.
  imap_idle_notify_interval = 24 min

  namespace spam {
    prefix = spam
    separator = .
    mail_driver = virtual
    mail_path = ~/mail/virtual/%{user}/spam
    mail_cache_path = ~/mail/virtual/%{user}/spam
    list = no
    hidden = yes
  }

  namespace sent {
    prefix = sent
    separator = .
    mail_driver = virtual
    mail_path = ~/mail/virtual/%{user}/sent
    mail_cache_path = ~/mail/virtual/%{user}/sent
    list = no
    hidden = yes
  }

}

##
## POP3 specific settings
##

protocol pop3 {
  # cPanel used to set this in config to UID%v-%u, but the UI never exposed
  # this to users to change it. As such, on dovecot 2.4 we just hardcode it
  # to the 2.4 version of what our default used to be, as it isn't actually
  # configurable in a meaningful way to users apart from custom templates
  # anyways. See https://doc.dovecot.org/2.4.1/core/config/pop3.html#uidl-format
  # for the latest var names for this if you do intend to customize it.
  pop3_uidl_format = UID%{uid}-%{uidvalidity}

  # POP3 logout format string:
  #  %{input} - total number of bytes read from client
  #  %{output} - total number of bytes sent to client
  #  %{top_count} - number of TOP commands
  #  %{top_bytes} - number of bytes sent to client as a result of TOP command
  #  %{retr_count} - number of RETR commands
  #  %{retr_bytes} - number of bytes sent to client as a result of RETR command
  #  %{deleted_count} - number of deleted messages
  #  %{deleted_bytes} - number of bytes in deleted messages
  #  %{message_count} - number of messages (before deletion)
  #  %{message_bytes} - mailbox size in bytes (before deletion)
  #  %{uidl_change} - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly
  pop3_logout_format = top=%{top_count}/%{top_bytes}, retr=%{retr_count}/%{retr_bytes}, del=%{deleted_count}/%{deleted_bytes}, size=%{message_bytes}, bytes=%{input}/%{output}

  # Maximum number of POP3 connections allowed for a user from each IP address.
  # NOTE: The username is compared case-sensitively.
  mail_max_userip_connections = 20

  mail_plugins = quota virtual mail_compress

  namespace spam {
      prefix = spam
     separator = .
    # NOTE: The mail_path generally gets overridden in the userdb/passdb return.
    # The values set for this are basically placeholders under our setup.
    mail_driver = virtual
    mail_path = ~/mail/virtual/%{user}/spam
    mail_cache_path = ~/mail/virtual/%{user}/spam
    list = no
    hidden = yes
  }

  namespace sent {
      prefix = sent
     separator = .
    mail_driver = virtual
    mail_path = ~/mail/virtual/%{user}/sent
    mail_cache_path = ~/mail/virtual/%{user}/sent
    list = no
    hidden = yes
  }

}

##
## LMTP specific settings
##

protocol lmtp {
    quota_full_tempfail = no
    mail_plugins {
        quota = yes
        mail_compress = yes
        sieve = yes
    }
}

lmtp_save_to_detail_mailbox = yes
lmtp_user_concurrency_limit = 25

recipient_delimiter = +

# Verify quota before replying to RCPT TO. This adds a small overhead.
lmtp_rcpt_check_quota = yes

##
## LDA specific settings
##

protocol lda {
  quota_full_tempfail = no
  mail_plugins {
      quota = yes
      mail_compress = yes
      sieve = yes
  }
}

# Should saving a mail to a nonexistent mailbox automatically create it?
lda_mailbox_autocreate = yes


##
## Sieve specific settings
##

# Send vacation (out-of-office) responses using the mailbox owner's address
# as the envelope sender rather than an empty address. An empty envelope sender
# causes SPF authentication to fail, resulting in bounced vacation emails from
# providers that require authenticated senders (e.g. Gmail).
sieve_vacation_send_from_recipient = yes

protocol sieve {

}

##
## Authentication processes
##

# Disable LOGIN command and all other plaintext authentications unless
# SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP
# matches the local IP (ie. you're connecting from the same computer), the
# connection is considered secure and plaintext authentication is allowed.
# See also ssl=required setting.
# Note: disable_plaintext_auth replaced by auth_allow_cleartext in Dovecot 2.4.1
auth_allow_cleartext = yes

# Allow weak authentication schemes such as MD5.
# When set to "no", only secure password hashing will be permitted.
# See https://doc.dovecot.org/main/core/config/auth/schemes.html
# for more information.
auth_allow_weak_schemes = yes

# Auth cache settings

# Authentication cache size (e.g. 10M). 0 means it's disabled. Note that
# bsdauth, PAM and vpopmail require cache_key to be set for caching to be used.
auth_cache_size = 999M

# Time to live for cached data. After TTL expires the cached record is no
# longer used, *except* if the main database lookup returns internal failure.
# We also try to handle password changes automatically: If user's previous
# authentication was successful, but this one wasn't, the cache isn't used.
# For now this works only with plaintext authentication.
auth_cache_ttl = 3600 sec

# TTL for negative hits (user not found, password mismatch).
# 0 disables caching them completely.
auth_cache_negative_ttl = 3600 sec

# List of allowed characters in username. If the user-given username contains
# a character not listed in here, the login automatically fails. This is just
# an extra check to make sure user can't exploit any potential quote escaping
# vulnerabilities with SQL/LDAP databases. If you want to allow all characters,
# set this value to empty.
#Allow + in usernames
auth_username_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$-=?^_{}~./@+%"

# Space separated list of wanted authentication mechanisms:
#   plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp skey
#   gss-spnego
# NOTE: See also auth_allow_cleartext setting.
auth_mechanisms = plain login

##
## Password and user databases
##
passdb pamrbld {
    driver = pam
    service_name = dovecot
    deny = yes
}

passdb cpauthd {
  driver = lua
  lua_file = /usr/local/cpanel/etc/dovecot/cpauthd.lua
  lua_settings {
      socket = /usr/local/cpanel/var/cpdoveauthd.sock
  }
  result_internalfail = continue
  result_failure = return-fail
}
userdb cpauthd {
  driver = lua
  lua_file = /usr/local/cpanel/etc/dovecot/cpauthd.lua
  lua_settings {
      socket = /usr/local/cpanel/var/cpdoveauthd.sock
  }
}

##
## Logging verbosity and debugging.
##

##
## Log formatting.
##

##
## Services
##

service config {
    vsz_limit = 2024 M
}

service quota-status {
  vsz_limit = 1024 M
  executable = quota-status -p postfix
  unix_listener quota-status {
    path = quota-status
    mode = 0666
  }
}

service auth {
  unix_listener auth-client {

    # auth-legacy Required for exim on Dovecot 2.4
    type = auth-legacy
    path = auth-client
    mode = 0666
  }
  vsz_limit = 512 M

}

service stats {
  vsz_limit = 1024 M
  unix_listener stats-writer {
    mode = 0666
  }
}

mail_access_groups = dovecot

service dict {
  vsz_limit = 1024 M
  unix_listener dict {
    mode = 0660
      group = dovecot
  }
}

service lmtp {
# Set max. process size in megabytes. Most of the memory goes to mmap()ing
# files, so it shouldn't harm much even if this limit is set pretty high.
    vsz_limit = 512 M

    #We always want this. Otherwise one connection could block another
    #connection that shares the same process.
    client_limit = 1

    process_limit = 500

    unix_listener lmtp {
       user = mailnull
       group = mail
       mode = 0660
    }
}

service imap-login {
  # Maximum number of connections allowed per each login process. This setting
  # is used only if login_process_per_connection=no. Once the limit is reached,
  # the process notifies master so that it can create a new login process.
  client_limit = 500

  # Maximum number of login processes to create. The listening process count
  # usually stays at login_processes_count, but when multiple users start logging
  # in at the same time more extra processes are created. To prevent fork-bombing
  # we check only once in a second if new processes should be created - if all
  # of them are used at the time, we double their amount until the limit set by
  # this setting is reached.
  process_limit = 50

  # Number of login processes to keep for listening new connections.
  process_min_avail = 5

  # Should each login be processed in its own process (yes), or should one
  # login process be allowed to process multiple connections (no)? Yes is more
  # secure, espcially with SSL/TLS enabled. No is faster since there's no need
  # to create processes all the time.
  service_restart_request_count = unlimited

  # Set max. process size in megabytes. If you don't use
  # login_process_per_connection you might need to grow this.
  vsz_limit = 512 M

  # IP or host address where to listen in for non-SSL connections. Defaults
  # to above if not specified.
  listen = *

  # IP or host address where to listen in for SSL connections. Defaults
  # to above if not specified.
  listen = *

}

service imap {
  # Maximum number of running mail processes. When this limit is reached,
  # new users aren't allowed to log in.
  process_limit = 1024

  # Set max. process size in megabytes. Most of the memory goes to mmap()ing
  # files, so it shouldn't harm much even if this limit is set pretty high.
  vsz_limit = 512 M


  unix_listener imap-master {
    user = dovecot
  }
  extra_groups = dovecot


}


service imap-hibernate {
  unix_listener imap-hibernate {
    mode = 0660
    group = dovecot
  }
  vsz_limit = 1024 M
}


service managesieve-login {
  # Maximum number of connections allowed per each login process. This setting
  # is used only if login_process_per_connection=no. Once the limit is reached,
  # the process notifies master so that it can create a new login process.
  client_limit = 500

  # Maximum number of login processes to create. The listening process count
  # usually stays at login_processes_count, but when multiple users start logging
  # in at the same time more extra processes are created. To prevent fork-bombing
  # we check only once in a second if new processes should be created - if all
  # of them are used at the time, we double their amount until the limit set by
  # this setting is reached.
  process_limit = 50

  # Number of login processes to keep for listening new connections.
  process_min_avail = 5

  # Should each login be processed in its own process (yes), or should one
  # login process be allowed to process multiple connections (no)? Yes is more
  # secure, espcially with SSL/TLS enabled. No is faster since there's no need
  # to create processes all the time.
  service_restart_request_count = unlimited

  # Set max. process size in megabytes. If you don't use
  # login_process_per_connection you might need to grow this.
  vsz_limit = 512 M


  listen = *
  inet_listener sieve {
    port = 4190
  }

}

service managesieve {
  # Maximum number of running mail processes. When this limit is reached,
  # new users aren't allowed to log in.
  process_limit = 1024

  # Set max. process size in megabytes. Most of the memory goes to mmap()ing
  # files, so it shouldn't harm much even if this limit is set pretty high.
  vsz_limit = 512 M


}

service pop3-login {
  # Maximum number of connections allowed per each login process. This setting
  # is used only if login_process_per_connection=no. Once the limit is reached,
  # the process notifies master so that it can create a new login process.
  client_limit = 500

  # Maximum number of login processes to create. The listening process count
  # usually stays at login_processes_count, but when multiple users start logging
  # in at the same time more extra processes are created. To prevent fork-bombing
  # we check only once in a second if new processes should be created - if all
  # of them are used at the time, we double their amount until the limit set by
  # this setting is reached.
  process_limit = 50

  # Number of login processes to keep for listening new connections.
  process_min_avail = 5

  # Should each login be processed in its own process (yes), or should one
  # login process be allowed to process multiple connections (no)? Yes is more
  # secure, espcially with SSL/TLS enabled. No is faster since there's no need
  # to create processes all the time.
  service_restart_request_count = unlimited

  # Set max. process size in megabytes. If you don't use
  # login_process_per_connection you might need to grow this.
  vsz_limit = 512 M

  # IP or host address where to listen in for non-SSL connections. Defaults
  # to above if not specified.
  listen = *

  # IP or host address where to listen in for SSL connections. Defaults
  # to above if not specified.
  listen = *
}

service pop3 {
  # Maximum number of running mail processes. When this limit is reached,
  # new users aren't allowed to log in.
  process_limit = 1024
  # Set max. process size in megabytes. Most of the memory goes to mmap()ing
  # files, so it shouldn't harm much even if this limit is set pretty high.
  vsz_limit = 512 M
}

# Setup doveadm
service doveadm {
  unix_listener doveadm-server {
      user = dovecot
  }
  vsz_limit = 1024 M
}

# Pre-setup for a few new services just to set vsz_limit
#
default_vsz_limit = 1024 M

service indexer {
  vsz_limit = 1024 M
}

service indexer-worker {
  vsz_limit = 1024 M
}

service auth-worker {
  vsz_limit = 1024 M
}

service anvil {
  vsz_limit = 1024 M
}

service log {
  vsz_limit = 1024 M
}
