docker-entrypoint.sh 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #!/bin/bash
  2. set -e
  3. # Wait for MySQL to warm-up
  4. while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do
  5. echo "Waiting for database to come up..."
  6. sleep 2
  7. done
  8. # Hard-code env vars to scripts due to cron not passing them to the perl script
  9. sed -i "/^\$DBUSER/c\\\$DBUSER='${DBUSER}';" /usr/local/bin/imapsync_cron.pl
  10. sed -i "/^\$DBPASS/c\\\$DBPASS='${DBPASS}';" /usr/local/bin/imapsync_cron.pl
  11. sed -i "/^\$DBNAME/c\\\$DBNAME='${DBNAME}';" /usr/local/bin/imapsync_cron.pl
  12. sed -i "s/LOG_LINES/${LOG_LINES}/g" /usr/local/bin/trim_logs.sh
  13. # Create missing directories
  14. [[ ! -d /usr/local/etc/dovecot/sql/ ]] && mkdir -p /usr/local/etc/dovecot/sql/
  15. [[ ! -d /var/vmail/_garbage ]] && mkdir -p /var/vmail/_garbage
  16. [[ ! -d /var/vmail/sieve ]] && mkdir -p /var/vmail/sieve
  17. [[ ! -d /etc/sogo ]] && mkdir -p /etc/sogo
  18. [[ ! -d /var/volatile ]] && mkdir -p /var/volatile
  19. # Set Dovecot sql config parameters, escape " in db password
  20. DBPASS=$(echo ${DBPASS} | sed 's/"/\\"/g')
  21. # Create quota dict for Dovecot
  22. cat <<EOF > /usr/local/etc/dovecot/sql/dovecot-dict-sql-quota.conf
  23. connect = "host=/var/run/mysqld/mysqld.sock dbname=${DBNAME} user=${DBUSER} password=${DBPASS}"
  24. map {
  25. pattern = priv/quota/storage
  26. table = quota2
  27. username_field = username
  28. value_field = bytes
  29. }
  30. map {
  31. pattern = priv/quota/messages
  32. table = quota2
  33. username_field = username
  34. value_field = messages
  35. }
  36. EOF
  37. # Create dict used for sieve pre and postfilters
  38. cat <<EOF > /usr/local/etc/dovecot/sql/dovecot-dict-sql-sieve_before.conf
  39. connect = "host=/var/run/mysqld/mysqld.sock dbname=${DBNAME} user=${DBUSER} password=${DBPASS}"
  40. map {
  41. pattern = priv/sieve/name/\$script_name
  42. table = sieve_before
  43. username_field = username
  44. value_field = id
  45. fields {
  46. script_name = \$script_name
  47. }
  48. }
  49. map {
  50. pattern = priv/sieve/data/\$id
  51. table = sieve_before
  52. username_field = username
  53. value_field = script_data
  54. fields {
  55. id = \$id
  56. }
  57. }
  58. EOF
  59. cat <<EOF > /usr/local/etc/dovecot/sql/dovecot-dict-sql-sieve_after.conf
  60. connect = "host=/var/run/mysqld/mysqld.sock dbname=${DBNAME} user=${DBUSER} password=${DBPASS}"
  61. map {
  62. pattern = priv/sieve/name/\$script_name
  63. table = sieve_after
  64. username_field = username
  65. value_field = id
  66. fields {
  67. script_name = \$script_name
  68. }
  69. }
  70. map {
  71. pattern = priv/sieve/data/\$id
  72. table = sieve_after
  73. username_field = username
  74. value_field = script_data
  75. fields {
  76. id = \$id
  77. }
  78. }
  79. EOF
  80. echo -n ${ACL_ANYONE} > /usr/local/etc/dovecot/acl_anyone
  81. # Create userdb dict for Dovecot
  82. cat <<EOF > /usr/local/etc/dovecot/sql/dovecot-dict-sql-userdb.conf
  83. driver = mysql
  84. connect = "host=/var/run/mysqld/mysqld.sock dbname=${DBNAME} user=${DBUSER} password=${DBPASS}"
  85. user_query = SELECT CONCAT(JSON_UNQUOTE(JSON_EXTRACT(attributes, '$.mailbox_format')), mailbox_path_prefix, '%d/%n/:VOLATILEDIR=/var/volatile/%u') AS mail, 5000 AS uid, 5000 AS gid, concat('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active = '1'
  86. iterate_query = SELECT username FROM mailbox WHERE active='1';
  87. EOF
  88. # Create pass dict for Dovecot
  89. cat <<EOF > /usr/local/etc/dovecot/sql/dovecot-dict-sql-passdb.conf
  90. driver = mysql
  91. connect = "host=/var/run/mysqld/mysqld.sock dbname=${DBNAME} user=${DBUSER} password=${DBPASS}"
  92. default_pass_scheme = SSHA256
  93. password_query = SELECT password FROM mailbox WHERE active = '1' AND username = '%u' AND domain IN (SELECT domain FROM domain WHERE domain='%d' AND active='1') AND JSON_EXTRACT(attributes, '$.force_pw_update') NOT LIKE '%%1%%'
  94. EOF
  95. # Create global sieve_after script
  96. cat /usr/local/etc/dovecot/sieve_after > /var/vmail/sieve/global.sieve
  97. # Check permissions of vmail/attachments directory.
  98. # Do not do this every start-up, it may take a very long time. So we use a stat check here.
  99. if [[ $(stat -c %U /var/vmail/) != "vmail" ]] ; then chown -R vmail:vmail /var/vmail ; fi
  100. if [[ $(stat -c %U /var/vmail/_garbage) != "vmail" ]] ; then chown -R vmail:vmail /var/vmail/_garbage ; fi
  101. if [[ $(stat -c %U /var/attachments) != "vmail" ]] ; then chown -R vmail:vmail /var/attachments ; fi
  102. # Create random master for SOGo sieve features
  103. RAND_USER=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 16 | head -n 1)
  104. RAND_PASS=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 24 | head -n 1)
  105. echo ${RAND_USER}@mailcow.local:{SHA1}$(echo -n ${RAND_PASS} | sha1sum | awk '{print $1}') > /usr/local/etc/dovecot/dovecot-master.passwd
  106. echo ${RAND_USER}@mailcow.local::5000:5000:::: > /usr/local/etc/dovecot/dovecot-master.userdb
  107. echo ${RAND_USER}@mailcow.local:${RAND_PASS} > /etc/sogo/sieve.creds
  108. # 401 is user dovecot
  109. if [[ ! -s /mail_crypt/ecprivkey.pem || ! -s /mail_crypt/ecpubkey.pem ]]; then
  110. openssl ecparam -name prime256v1 -genkey | openssl pkey -out /mail_crypt/ecprivkey.pem
  111. openssl pkey -in /mail_crypt/ecprivkey.pem -pubout -out /mail_crypt/ecpubkey.pem
  112. chown 401 /mail_crypt/ecprivkey.pem /mail_crypt/ecpubkey.pem
  113. else
  114. chown 401 /mail_crypt/ecprivkey.pem /mail_crypt/ecpubkey.pem
  115. fi
  116. # Compile sieve scripts
  117. sievec /var/vmail/sieve/global.sieve
  118. sievec /usr/local/lib/dovecot/sieve/report-spam.sieve
  119. sievec /usr/local/lib/dovecot/sieve/report-ham.sieve
  120. # Fix permissions
  121. chown root:root /usr/local/etc/dovecot/sql/*.conf
  122. chown root:dovecot /usr/local/etc/dovecot/sql/dovecot-dict-sql-sieve* /usr/local/etc/dovecot/sql/dovecot-dict-sql-quota*
  123. chmod 640 /usr/local/etc/dovecot/sql/*.conf
  124. chown -R vmail:vmail /var/vmail/sieve
  125. chown -R vmail:vmail /var/volatile
  126. adduser vmail tty
  127. chmod g+rw /dev/console
  128. # Fix more than 1 hardlink issue
  129. touch /etc/crontab /etc/cron.*/*
  130. # Clean old PID if any
  131. [[ -f /usr/local/var/run/dovecot/master.pid ]] && rm /usr/local/var/run/dovecot/master.pid
  132. # Clean stopped imapsync jobs
  133. rm -f /tmp/imapsync_busy.lock
  134. IMAPSYNC_TABLE=$(mysql --socket=/var/run/mysqld/mysqld.sock -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "SHOW TABLES LIKE 'imapsync'" -Bs)
  135. [[ ! -z ${IMAPSYNC_TABLE} ]] && mysql --socket=/var/run/mysqld/mysqld.sock -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "UPDATE imapsync SET is_running='0'"
  136. # Envsubst maildir_gc
  137. envsubst < /usr/local/bin/maildir_gc.sh > /usr/local/bin/maildir_gc.sh
  138. # Collect SA rules once now
  139. /usr/local/bin/sa-rules.sh
  140. exec "$@"