[Dovecot] Fix app passwds: allow multiple pass hashes by using LUA construct
parent
851e9c8736
commit
afb43c9c5b
|
@ -69,6 +69,7 @@ RUN groupadd -g 5000 vmail \
|
||||||
libunicode-string-perl \
|
libunicode-string-perl \
|
||||||
liburi-perl \
|
liburi-perl \
|
||||||
libwww-perl \
|
libwww-perl \
|
||||||
|
lua-sql-mysql \
|
||||||
mariadb-client \
|
mariadb-client \
|
||||||
procps \
|
procps \
|
||||||
python3-pip \
|
python3-pip \
|
||||||
|
|
|
@ -7,21 +7,6 @@ while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${D
|
||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
|
|
||||||
# Hard-code env vars to scripts due to cron not passing them to the scripts
|
|
||||||
sed -i "s/__DBUSER__/${DBUSER}/g" /usr/local/bin/imapsync_cron.pl
|
|
||||||
sed -i "s/__DBPASS__/${DBPASS}/g" /usr/local/bin/imapsync_cron.pl
|
|
||||||
sed -i "s/__DBNAME__/${DBNAME}/g" /usr/local/bin/imapsync_cron.pl
|
|
||||||
|
|
||||||
sed -i "s/__DBUSER__/${DBUSER}/g" /usr/local/bin/quarantine_notify.py
|
|
||||||
sed -i "s/__DBPASS__/${DBPASS}/g" /usr/local/bin/quarantine_notify.py
|
|
||||||
sed -i "s/__DBNAME__/${DBNAME}/g" /usr/local/bin/quarantine_notify.py
|
|
||||||
|
|
||||||
sed -i "s/__DBUSER__/${DBUSER}/g" /usr/local/bin/clean_q_aged.sh
|
|
||||||
sed -i "s/__DBPASS__/${DBPASS}/g" /usr/local/bin/clean_q_aged.sh
|
|
||||||
sed -i "s/__DBNAME__/${DBNAME}/g" /usr/local/bin/clean_q_aged.sh
|
|
||||||
|
|
||||||
sed -i "s/__LOG_LINES__/${LOG_LINES}/g" /usr/local/bin/trim_logs.sh
|
|
||||||
|
|
||||||
# Create missing directories
|
# Create missing directories
|
||||||
[[ ! -d /etc/dovecot/sql/ ]] && mkdir -p /etc/dovecot/sql/
|
[[ ! -d /etc/dovecot/sql/ ]] && mkdir -p /etc/dovecot/sql/
|
||||||
[[ ! -d /var/vmail/_garbage ]] && mkdir -p /var/vmail/_garbage
|
[[ ! -d /var/vmail/_garbage ]] && mkdir -p /var/vmail/_garbage
|
||||||
|
@ -127,12 +112,35 @@ default_pass_scheme = SSHA256
|
||||||
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%%'
|
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%%'
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat <<EOF > /etc/dovecot/sql/dovecot-dict-sql-app-passdb.conf
|
cat <<EOF > /var/lib/dovecot/app-passdb.lua
|
||||||
# Autogenerated by mailcow
|
function auth_password_verify(req, pass)
|
||||||
driver = mysql
|
local cur,errorString = con:execute(string.format([[SELECT mailbox, password FROM app_passwd
|
||||||
connect = "host=/var/run/mysqld/mysqld.sock dbname=${DBNAME} user=${DBUSER} password=${DBPASS}"
|
WHERE mailbox = '%s'
|
||||||
default_pass_scheme = SSHA256
|
AND active = '1'
|
||||||
password_query = SELECT password FROM app_passwd WHERE active = '1' AND mailbox = '%u' AND domain IN (SELECT domain FROM domain WHERE domain='%d' AND active='1')
|
AND domain IN (SELECT domain FROM domain WHERE domain='%s' AND active='1')]], con:escape(req.user), con:escape(req.domain)))
|
||||||
|
local row = cur:fetch ({}, "a")
|
||||||
|
while row do
|
||||||
|
if req.password_verify(req, row.password, pass) == 1 then
|
||||||
|
req.log_warning(req, string.format("User %s logged in with app password", row.mailbox))
|
||||||
|
cur:close()
|
||||||
|
return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass
|
||||||
|
end
|
||||||
|
row = cur:fetch (row, "a")
|
||||||
|
end
|
||||||
|
return dovecot.auth.PASSDB_RESULT_USER_UNKNOWN, "no such user"
|
||||||
|
end
|
||||||
|
|
||||||
|
function script_init()
|
||||||
|
mysql = require "luasql.mysql"
|
||||||
|
env = mysql.mysql()
|
||||||
|
con = env:connect("__DBNAME__","__DBUSER__","__DBPASS__","mysql")
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function script_deinit()
|
||||||
|
con:close()
|
||||||
|
env:close()
|
||||||
|
end
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Migrate old sieve_after file
|
# Migrate old sieve_after file
|
||||||
|
@ -206,6 +214,12 @@ else
|
||||||
rm -f /etc/dovecot/sogo-sso.conf
|
rm -f /etc/dovecot/sogo-sso.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Hard-code env vars to scripts due to cron not passing them to the scripts
|
||||||
|
sed -i "s/__DBUSER__/${DBUSER}/g" /usr/local/bin/imapsync_cron.pl /usr/local/bin/quarantine_notify.py /usr/local/bin/clean_q_aged.sh /var/lib/dovecot/app-passdb.lua
|
||||||
|
sed -i "s/__DBPASS__/${DBPASS}/g" /usr/local/bin/imapsync_cron.pl /usr/local/bin/quarantine_notify.py /usr/local/bin/clean_q_aged.sh /var/lib/dovecot/app-passdb.lua
|
||||||
|
sed -i "s/__DBNAME__/${DBNAME}/g" /usr/local/bin/imapsync_cron.pl /usr/local/bin/quarantine_notify.py /usr/local/bin/clean_q_aged.sh /var/lib/dovecot/app-passdb.lua
|
||||||
|
sed -i "s/__LOG_LINES__/${LOG_LINES}/g" /usr/local/bin/trim_logs.sh
|
||||||
|
|
||||||
# 401 is user dovecot
|
# 401 is user dovecot
|
||||||
if [[ ! -s /mail_crypt/ecprivkey.pem || ! -s /mail_crypt/ecpubkey.pem ]]; then
|
if [[ ! -s /mail_crypt/ecprivkey.pem || ! -s /mail_crypt/ecpubkey.pem ]]; then
|
||||||
openssl ecparam -name prime256v1 -genkey | openssl pkey -out /mail_crypt/ecprivkey.pem
|
openssl ecparam -name prime256v1 -genkey | openssl pkey -out /mail_crypt/ecprivkey.pem
|
||||||
|
|
|
@ -56,8 +56,8 @@ passdb {
|
||||||
}
|
}
|
||||||
# try an app passwd
|
# try an app passwd
|
||||||
passdb {
|
passdb {
|
||||||
args = /etc/dovecot/sql/dovecot-dict-sql-app-passdb.conf
|
driver = lua
|
||||||
driver = sql
|
args = file=/var/lib/dovecot/app-passdb.lua blocking=yes
|
||||||
pass = yes
|
pass = yes
|
||||||
result_failure = continue
|
result_failure = continue
|
||||||
result_internalfail = continue
|
result_internalfail = continue
|
||||||
|
|
Loading…
Reference in New Issue