Merge branch 'dev'
commit
069c93cb64
|
@ -1,8 +1,8 @@
|
||||||
FROM debian:latest
|
FROM debian:stretch-slim
|
||||||
MAINTAINER https://m-ko.de Markus Kosmal <code@cnfg.io>
|
MAINTAINER https://m-ko.de Markus Kosmal <code@cnfg.io>
|
||||||
|
|
||||||
# Debian Base to use
|
# Debian Base to use
|
||||||
ENV DEBIAN_VERSION jessie
|
ENV DEBIAN_VERSION stretch
|
||||||
|
|
||||||
# initial install of av daemon
|
# initial install of av daemon
|
||||||
RUN echo "deb http://http.debian.net/debian/ $DEBIAN_VERSION main contrib non-free" > /etc/apt/sources.list && \
|
RUN echo "deb http://http.debian.net/debian/ $DEBIAN_VERSION main contrib non-free" > /etc/apt/sources.list && \
|
||||||
|
@ -13,15 +13,14 @@ RUN echo "deb http://http.debian.net/debian/ $DEBIAN_VERSION main contrib non-fr
|
||||||
clamav-daemon \
|
clamav-daemon \
|
||||||
clamav-freshclam \
|
clamav-freshclam \
|
||||||
libclamunrar7 \
|
libclamunrar7 \
|
||||||
wget && \
|
curl && \
|
||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# initial update of av databases
|
# initial update of av databases
|
||||||
RUN wget -O /var/lib/clamav/main.cvd http://db.local.clamav.net/main.cvd && \
|
COPY dl_files.sh /dl_files.sh
|
||||||
wget -O /var/lib/clamav/daily.cvd http://db.local.clamav.net/daily.cvd && \
|
RUN chmod +x /dl_files.sh
|
||||||
wget -O /var/lib/clamav/bytecode.cvd http://db.local.clamav.net/bytecode.cvd && \
|
RUN /dl_files.sh
|
||||||
chown clamav:clamav /var/lib/clamav/*.cvd
|
|
||||||
|
|
||||||
# permission juggling
|
# permission juggling
|
||||||
RUN mkdir /var/run/clamav && \
|
RUN mkdir /var/run/clamav && \
|
||||||
|
@ -33,9 +32,6 @@ RUN sed -i 's/^Foreground .*$/Foreground true/g' /etc/clamav/clamd.conf && \
|
||||||
echo "TCPSocket 3310" >> /etc/clamav/clamd.conf && \
|
echo "TCPSocket 3310" >> /etc/clamav/clamd.conf && \
|
||||||
sed -i 's/^Foreground .*$/Foreground true/g' /etc/clamav/freshclam.conf
|
sed -i 's/^Foreground .*$/Foreground true/g' /etc/clamav/freshclam.conf
|
||||||
|
|
||||||
# volume provision
|
|
||||||
VOLUME ["/var/lib/clamav"]
|
|
||||||
|
|
||||||
# port provision
|
# port provision
|
||||||
EXPOSE 3310
|
EXPOSE 3310
|
||||||
|
|
||||||
|
|
|
@ -1,35 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# bootstrap clam av service and clam av database updater shell script
|
trap "kill 0" SIGINT
|
||||||
# presented by mko (Markus Kosmal<code@cnfg.io>)
|
|
||||||
set -m
|
|
||||||
|
|
||||||
# start clam service itself and the updater in background as daemon
|
|
||||||
freshclam -d &
|
freshclam -d &
|
||||||
clamd &
|
clamd &
|
||||||
|
|
||||||
# recognize PIDs
|
sleep inf
|
||||||
pidlist=`jobs -p`
|
|
||||||
|
|
||||||
# initialize latest result var
|
|
||||||
latest_exit=0
|
|
||||||
|
|
||||||
# define shutdown helper
|
|
||||||
function shutdown() {
|
|
||||||
trap "" SUBS
|
|
||||||
|
|
||||||
for single in $pidlist; do
|
|
||||||
if ! kill -0 $pidlist 2>/dev/null; then
|
|
||||||
wait $pidlist
|
|
||||||
exitcode=$?
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
kill $pidlist 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# run shutdown
|
|
||||||
trap terminate SUBS
|
|
||||||
wait
|
|
||||||
|
|
||||||
# return received result
|
|
||||||
exit $latest_exit
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
declare -a DB_MIRRORS=(
|
||||||
|
"switch.clamav.net"
|
||||||
|
"clamavdb.heanet.ie"
|
||||||
|
"clamav.iol.cz"
|
||||||
|
"clamav.univ-nantes.fr"
|
||||||
|
"clamav.easynet.fr"
|
||||||
|
"clamav.begi.net"
|
||||||
|
)
|
||||||
|
declare -a DB_MIRRORS=( $(shuf -e "${DB_MIRRORS[@]}") )
|
||||||
|
|
||||||
|
DB_FILES=(
|
||||||
|
"bytecode.cvd"
|
||||||
|
"daily.cvd"
|
||||||
|
"main.cvd"
|
||||||
|
)
|
||||||
|
|
||||||
|
for i in "${DB_MIRRORS[@]}"; do
|
||||||
|
for j in "${DB_FILES[@]}"; do
|
||||||
|
[[ -f "/var/lib/clamav/${j}" && -s "/var/lib/clamav/${j}" ]] && continue;
|
||||||
|
if [[ $(curl -o /dev/null --connect-timeout 1 \
|
||||||
|
--max-time 1 \
|
||||||
|
--silent \
|
||||||
|
--head \
|
||||||
|
--write-out "%{http_code}\n" "${i}/${j}") == 200 ]]; then
|
||||||
|
curl "${i}/${j}" -o "/var/lib/clamav/${j}" -#
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
chown clamav:clamav /var/lib/clamav/*.cvd
|
|
@ -4,8 +4,8 @@ MAINTAINER Andre Peters <andre.peters@servercow.de>
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND noninteractive
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
ENV LC_ALL C
|
ENV LC_ALL C
|
||||||
ENV DOVECOT_VERSION 2.2.28
|
ENV DOVECOT_VERSION 2.2.29.1
|
||||||
ENV PIGEONHOLE_VERSION 0.4.17
|
ENV PIGEONHOLE_VERSION 0.4.18
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get -y install libpam-dev \
|
&& apt-get -y install libpam-dev \
|
||||||
|
|
|
@ -23,6 +23,7 @@ RUN apt-get install -y --no-install-recommends supervisor \
|
||||||
gnupg \
|
gnupg \
|
||||||
python-gpgme \
|
python-gpgme \
|
||||||
sudo \
|
sudo \
|
||||||
|
curl \
|
||||||
dirmngr
|
dirmngr
|
||||||
|
|
||||||
RUN addgroup --system --gid 600 zeyple
|
RUN addgroup --system --gid 600 zeyple
|
||||||
|
@ -34,6 +35,7 @@ COPY zeyple.py /usr/local/bin/zeyple.py
|
||||||
COPY zeyple.conf /etc/zeyple.conf
|
COPY zeyple.conf /etc/zeyple.conf
|
||||||
COPY supervisord.conf /etc/supervisor/supervisord.conf
|
COPY supervisord.conf /etc/supervisor/supervisord.conf
|
||||||
COPY postfix.sh /opt/postfix.sh
|
COPY postfix.sh /opt/postfix.sh
|
||||||
|
COPY whitelist_forwardinghosts.sh /usr/local/bin/whitelist_forwardinghosts.sh
|
||||||
|
|
||||||
EXPOSE 588
|
EXPOSE 588
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
while read QUERY; do
|
||||||
|
QUERY=($QUERY)
|
||||||
|
if [ "${QUERY[0]}" != "get" ]; then
|
||||||
|
echo "500 dunno"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
result=$(curl -s http://nginx:8081/forwardinghosts.php?host=${QUERY[1]})
|
||||||
|
logger -t whitelist_forwardinghosts -p mail.info "Look up ${QUERY[1]} on whitelist, result $result"
|
||||||
|
echo ${result}
|
||||||
|
done
|
|
@ -18,10 +18,9 @@ server {
|
||||||
access_log /var/log/nginx/access.log;
|
access_log /var/log/nginx/access.log;
|
||||||
root /web;
|
root /web;
|
||||||
|
|
||||||
location /api/v1/ {
|
location ~ ^/api/v1/(.*)$ {
|
||||||
try_files $uri $uri/ /json_api.php?$args;
|
try_files $uri $uri/ /json_api.php?query=$1;
|
||||||
}
|
}
|
||||||
rewrite ^/api/v1/([^/]+)/([^/]+)/?$ /json_api.php?action=$1&object=$2? last;
|
|
||||||
|
|
||||||
location ^~ /.well-known/acme-challenge/ {
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
allow all;
|
allow all;
|
||||||
|
@ -64,10 +63,6 @@ server {
|
||||||
add_header X-XSS-Protection "1; mode=block";
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
}
|
}
|
||||||
|
|
||||||
location ^~ /inc/init.sql {
|
|
||||||
deny all;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ~ /(?:a|A)utodiscover/(?:a|A)utodiscover.xml {
|
location ~ /(?:a|A)utodiscover/(?:a|A)utodiscover.xml {
|
||||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||||
fastcgi_pass phpfpm:9000;
|
fastcgi_pass phpfpm:9000;
|
||||||
|
@ -171,10 +166,9 @@ server {
|
||||||
access_log /var/log/nginx/access.log;
|
access_log /var/log/nginx/access.log;
|
||||||
root /web;
|
root /web;
|
||||||
|
|
||||||
location /api/v1/ {
|
location ~ ^/api/v1/(.*)$ {
|
||||||
try_files $uri $uri/ /json_api.php?$args;
|
try_files $uri $uri/ /json_api.php?query=$1;
|
||||||
}
|
}
|
||||||
rewrite ^/api/v1/([^/]+)/([^/]+)/?$ /json_api.php?action=$1&object=$2? last;
|
|
||||||
|
|
||||||
location ^~ /.well-known/acme-challenge/ {
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
allow all;
|
allow all;
|
||||||
|
|
|
@ -24,7 +24,7 @@ milter_default_action = accept
|
||||||
milter_protocol = 6
|
milter_protocol = 6
|
||||||
minimal_backoff_time = 300s
|
minimal_backoff_time = 300s
|
||||||
plaintext_reject_code = 550
|
plaintext_reject_code = 550
|
||||||
postscreen_access_list = permit_mynetworks, cidr:/opt/postfix/conf/postscreen_access.cidr
|
postscreen_access_list = permit_mynetworks, cidr:/opt/postfix/conf/postscreen_access.cidr, tcp:127.0.0.1:10027
|
||||||
postscreen_bare_newline_enable = no
|
postscreen_bare_newline_enable = no
|
||||||
postscreen_blacklist_action = drop
|
postscreen_blacklist_action = drop
|
||||||
postscreen_cache_cleanup_interval = 24h
|
postscreen_cache_cleanup_interval = 24h
|
||||||
|
|
|
@ -55,3 +55,5 @@ zeyple unix - n n - - pipe
|
||||||
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
||||||
-o mynetworks=127.0.0.0/8
|
-o mynetworks=127.0.0.0/8
|
||||||
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
|
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
|
||||||
|
|
||||||
|
127.0.0.1:10027 inet n n n - 0 spawn user=nobody argv=/usr/local/bin/whitelist_forwardinghosts.sh
|
||||||
|
|
|
@ -28,7 +28,6 @@ redis {
|
||||||
};
|
};
|
||||||
tempdir = /tmp;
|
tempdir = /tmp;
|
||||||
tempfiles_mode = 00600;
|
tempfiles_mode = 00600;
|
||||||
max_size = 20M;
|
|
||||||
strict_auth = yes;
|
strict_auth = yes;
|
||||||
use_dcc = no;
|
use_dcc = no;
|
||||||
limits {
|
limits {
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
header('Content-Type: text/plain');
|
||||||
|
require_once "vars.inc.php";
|
||||||
|
|
||||||
|
ini_set('error_reporting', 0);
|
||||||
|
|
||||||
|
function in_net($addr, $net)
|
||||||
|
{
|
||||||
|
$net = explode('/', $net);
|
||||||
|
if (count($net) > 1)
|
||||||
|
$mask = $net[1];
|
||||||
|
$net = inet_pton($net[0]);
|
||||||
|
$addr = inet_pton($addr);
|
||||||
|
|
||||||
|
$length = strlen($net); // 4 for IPv4, 16 for IPv6
|
||||||
|
if (strlen($net) != strlen($addr))
|
||||||
|
return FALSE;
|
||||||
|
if (!isset($mask))
|
||||||
|
$mask = $length * 8;
|
||||||
|
|
||||||
|
$addr_bin = '';
|
||||||
|
$net_bin = '';
|
||||||
|
for ($i = 0; $i < $length; ++$i)
|
||||||
|
{
|
||||||
|
$addr_bin .= str_pad(decbin(ord(substr($addr, $i, $i+1))), 8, '0', STR_PAD_LEFT);
|
||||||
|
$net_bin .= str_pad(decbin(ord(substr($net, $i, $i+1))), 8, '0', STR_PAD_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return substr($addr_bin, 0, $mask) == substr($net_bin, 0, $mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
$dsn = $database_type . ':host=' . $database_host . ';dbname=' . $database_name;
|
||||||
|
$opt = [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
|
||||||
|
$stmt = $pdo->query("SELECT host FROM `forwarding_hosts`");
|
||||||
|
$networks = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
foreach ($networks as $network)
|
||||||
|
{
|
||||||
|
if (in_net($_GET['host'], $network))
|
||||||
|
{
|
||||||
|
echo '200 permit';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo '200 dunno';
|
||||||
|
}
|
||||||
|
catch (PDOException $e) {
|
||||||
|
echo '200 dunno';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
|
@ -32,6 +32,35 @@ catch (PDOException $e) {
|
||||||
?>
|
?>
|
||||||
settings {
|
settings {
|
||||||
<?php
|
<?php
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->query("SELECT `host` FROM `forwarding_hosts`");
|
||||||
|
$rows = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
}
|
||||||
|
catch (PDOException $e) {
|
||||||
|
$rows = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rows)
|
||||||
|
{
|
||||||
|
?>
|
||||||
|
whitelist_forwarding_hosts {
|
||||||
|
priority = high;
|
||||||
|
<?php
|
||||||
|
foreach ($rows as $host) {
|
||||||
|
echo "\t\t" . 'ip = "' . $host . '";' . "\n";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
apply "default" {
|
||||||
|
actions {
|
||||||
|
reject = 999.9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
symbols [
|
||||||
|
"WHITELIST_FORWARDING_HOST"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
<?php
|
||||||
|
}
|
||||||
$stmt = $pdo->query("SELECT DISTINCT `object` FROM `filterconf` WHERE `option` = 'highspamlevel' OR `option` = 'lowspamlevel'");
|
$stmt = $pdo->query("SELECT DISTINCT `object` FROM `filterconf` WHERE `option` = 'highspamlevel' OR `option` = 'lowspamlevel'");
|
||||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
@ -207,8 +236,11 @@ while ($row = array_shift($rows)) {
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
apply "default" {
|
apply "default" {
|
||||||
MAILCOW_MOO = -999.0;
|
MAILCOW_WHITE = -999.0;
|
||||||
}
|
}
|
||||||
|
symbols [
|
||||||
|
"MAILCOW_WHITE"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
@ -302,8 +334,11 @@ while ($row = array_shift($rows)) {
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
apply "default" {
|
apply "default" {
|
||||||
MAILCOW_MOO = 999.0;
|
MAILCOW_BLACK = 999.0;
|
||||||
}
|
}
|
||||||
|
symbols [
|
||||||
|
"MAILCOW_BLACK"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
clamav {
|
||||||
|
attachments_only = false;
|
||||||
|
symbol = "CLAM_VIRUS";
|
||||||
|
type = "clamav";
|
||||||
|
log_clean = true;
|
||||||
|
servers = "clamd:3310";
|
||||||
|
}
|
|
@ -1,34 +0,0 @@
|
||||||
sign_condition =<<EOD
|
|
||||||
return function(task)
|
|
||||||
local smtp_from = task:get_from('smtp')
|
|
||||||
local mime_from = task:get_from('mime')
|
|
||||||
local rspamd_logger = require "rspamd_logger"
|
|
||||||
if smtp_from[1]['domain'] ~= nil and smtp_from[1]['domain'] ~= '' then
|
|
||||||
domain = smtp_from[1]['domain']
|
|
||||||
rspamd_logger.infox(task, "set domain found in smtp from field to %s", domain)
|
|
||||||
if not task:get_user() then
|
|
||||||
rspamd_logger.infox(task, "found domain in smtp header field, but user is not authenticated - skipped")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
elseif mime_from[1]['domain'] ~= nil and mime_from[1]['domain'] ~= '' then
|
|
||||||
domain = mime_from[1]['domain']
|
|
||||||
rspamd_logger.infox(task, "set domain found in mime from field to %s", domain)
|
|
||||||
else
|
|
||||||
rspamd_logger.infox(task, "cannot determine domain for dkim signing")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
local keyfile = io.open("/data/dkim/keys/" .. domain .. ".dkim")
|
|
||||||
if keyfile then
|
|
||||||
rspamd_logger.infox(task, "found dkim key file for domain %s", domain)
|
|
||||||
keyfile:close()
|
|
||||||
return {
|
|
||||||
key = "/data/dkim/keys/" .. domain .. ".dkim",
|
|
||||||
domain = domain,
|
|
||||||
selector = "dkim"
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rspamd_logger.infox(task, "no key file for domain %s - skipped", domain)
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
EOD;
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
# If false, messages with empty envelope from are not signed
|
||||||
|
allow_envfrom_empty = false;
|
||||||
|
# If true, envelope/header domain mismatch is ignored
|
||||||
|
allow_hdrfrom_mismatch = true;
|
||||||
|
# If true, multiple from headers are allowed (but only first is used)
|
||||||
|
allow_hdrfrom_multiple = true;
|
||||||
|
# If true, username does not need to contain matching domain
|
||||||
|
allow_username_mismatch = true;
|
||||||
|
# If false, messages from authenticated users are not selected for signing
|
||||||
|
auth_only = true;
|
||||||
|
# Default path to key, can include '$domain' and '$selector' variables
|
||||||
|
path = "/data/dkim/keys/$domain.dkim";
|
||||||
|
# Default selector to use
|
||||||
|
selector = "dkim";
|
||||||
|
# If false, messages from local networks are not selected for signing
|
||||||
|
sign_local = true;
|
||||||
|
# Symbol to add when message is signed
|
||||||
|
symbol = "DKIM_SIGNED";
|
||||||
|
# Whether to fallback to global config
|
||||||
|
try_fallback = true;
|
||||||
|
# Domain to use for DKIM signing: can be "header" or "envelope"
|
||||||
|
use_domain = "envelope";
|
||||||
|
# Whether to normalise domains to eSLD
|
||||||
|
use_esld = true;
|
||||||
|
# Whether to get keys from Redis
|
||||||
|
use_redis = false;
|
||||||
|
# Hash for DKIM keys in Redis
|
||||||
|
hash_key = "DKIM_KEYS";
|
|
@ -0,0 +1,12 @@
|
||||||
|
rules {
|
||||||
|
DKIM_FAIL {
|
||||||
|
action = "add header";
|
||||||
|
expression = "R_DKIM_REJECT & !MAILLIST & !MAILCOW_WHITE & !MAILCOW_BLACK";
|
||||||
|
require_action = ["no action", "greylist"];
|
||||||
|
}
|
||||||
|
VIRUS_FOUND {
|
||||||
|
action = "reject";
|
||||||
|
expression = "CLAM_VIRUS & !MAILCOW_WHITE";
|
||||||
|
honor_action = ["reject"];
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,10 +7,6 @@ rspamd_config.MAILCOW_AUTH = {
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
rspamd_config.MAILCOW_MOO = function (task)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
modify_subject_map = rspamd_config:add_map({
|
modify_subject_map = rspamd_config:add_map({
|
||||||
url = 'http://172.22.1.251:8081/tags.php',
|
url = 'http://172.22.1.251:8081/tags.php',
|
||||||
type = 'map',
|
type = 'map',
|
||||||
|
|
|
@ -353,7 +353,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] ==
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-offset-2 col-sm-10">
|
<div class="col-sm-offset-2 col-sm-10">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label><input type="checkbox" name="delete1" checked> <?=$lang['add']['delete1'];?></label>
|
<label><input type="checkbox" name="delete1"> <?=$lang['add']['delete1'];?></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -183,9 +183,11 @@ $tfa_data = get_tfa();
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h4><span class="glyphicon glyphicon-wrench" aria-hidden="true"></span> <?=$lang['admin']['configuration'];?></h4>
|
<h4><span class="glyphicon glyphicon-wrench" aria-hidden="true"></span> <?=$lang['admin']['configuration'];?></h4>
|
||||||
|
|
||||||
|
<div class="panel-group" id="accordion_access">
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><?=$lang['admin']['dkim_keys'];?></div>
|
<div class="panel-heading"><?=$lang['admin']['dkim_keys'];?></div>
|
||||||
<div id="collapseDKIM" class="panel-collapse">
|
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<p style="margin-bottom:40px"><?=$lang['admin']['dkim_key_hint'];?></p>
|
<p style="margin-bottom:40px"><?=$lang['admin']['dkim_key_hint'];?></p>
|
||||||
<?php
|
<?php
|
||||||
|
@ -297,7 +299,72 @@ $tfa_data = get_tfa();
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><?=$lang['admin']['forwarding_hosts'];?></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<p style="margin-bottom:40px"><?=$lang['admin']['forwarding_hosts_hint'];?></p>
|
||||||
|
<form method="post">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped" id="forwardinghoststable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="min-width: 100px;"><?=$lang['edit']['host'];?></th>
|
||||||
|
<th style="min-width: 100px;"><?=$lang['edit']['source'];?></th>
|
||||||
|
<th style="text-align: right; min-width: 200px;"><?=$lang['admin']['action'];?></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
$forwarding_hosts = get_forwarding_hosts();
|
||||||
|
if ($forwarding_hosts) {
|
||||||
|
foreach ($forwarding_hosts as $host) {
|
||||||
|
$source = $host->source;
|
||||||
|
$host = $host->host;
|
||||||
|
?>
|
||||||
|
<tr id="data">
|
||||||
|
<td><?=htmlspecialchars(strtolower($host));?></td>
|
||||||
|
<td><?=htmlspecialchars(strtolower($source));?></td>
|
||||||
|
<td style="text-align: right;">
|
||||||
|
<div class="btn-group">
|
||||||
|
<a href="delete.php?forwardinghost=<?=$host;?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['admin']['remove'];?></a>
|
||||||
</div>
|
</div>
|
||||||
|
</td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
?>
|
||||||
|
<tr id="no-data"><td colspan="4" style="text-align: center; font-style: italic;"><?=$lang['admin']['no_record'];?></td></tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<legend><?=$lang['admin']['add_forwarding_host'];?></legend>
|
||||||
|
<p class="help-block"><?=$lang['admin']['forwarding_hosts_add_hint'];?></p>
|
||||||
|
<form class="form-horizontal" role="form" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-sm-2" for="hostname"><?=$lang['edit']['host'];?>:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" name="hostname" id="hostname" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-2 col-sm-10">
|
||||||
|
<button type="submit" name="add_forwarding_host" class="btn btn-default"><?=$lang['admin']['add'];?></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
</div> <!-- /container -->
|
</div> <!-- /container -->
|
||||||
<script type='text/javascript'>
|
<script type='text/javascript'>
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -12,8 +12,25 @@ table.footable>tbody>tr.footable-empty>td {
|
||||||
overflow: visible !important;
|
overflow: visible !important;
|
||||||
}
|
}
|
||||||
.footer-add-item {
|
.footer-add-item {
|
||||||
text-align:center;
|
|
||||||
font-style: italic;
|
|
||||||
display:block;
|
display:block;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
background: #F5F5F5;
|
||||||
|
}
|
||||||
|
.mass-each-action {
|
||||||
|
padding: 0 3px 0 3px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.mass-actions {
|
||||||
|
user-select: none;
|
||||||
|
padding:10px;
|
||||||
|
}
|
||||||
|
.mass-select-all {
|
||||||
|
cursor:pointer;
|
||||||
|
color:#555;
|
||||||
|
}
|
||||||
|
#alias_table {
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
#alias_table .footable-paging {
|
||||||
|
cursor: auto;
|
||||||
}
|
}
|
|
@ -50,3 +50,8 @@ pre{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-s
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
/* Fix modal moving content left */
|
||||||
|
body.modal-open {
|
||||||
|
overflow: inherit;
|
||||||
|
padding-right: inherit !important;
|
||||||
|
}
|
||||||
|
|
|
@ -105,6 +105,23 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
|
||||||
</form>
|
</form>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
// DELETE FORWARDING HOST
|
||||||
|
elseif (isset($_GET["forwardinghost"]) &&
|
||||||
|
!empty($_GET["forwardinghost"]) &&
|
||||||
|
$_SESSION['mailcow_cc_role'] == "admin") {
|
||||||
|
$host = $_GET["forwardinghost"];
|
||||||
|
?>
|
||||||
|
<div class="alert alert-warning" role="alert"><?=sprintf($lang['delete']['remove_forwardinghost_warning'], htmlspecialchars($_GET["forwardinghost"]));?></div>
|
||||||
|
<form class="form-horizontal" role="form" method="post" action="/admin.php">
|
||||||
|
<input type="hidden" name="forwardinghost" value="<?=htmlspecialchars($host);?>">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-1 col-sm-10">
|
||||||
|
<button type="submit" name="delete_forwarding_host" class="btn btn-default btn-sm"><?=$lang['delete']['remove_button'];?></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
// DELETE MAILBOX
|
// DELETE MAILBOX
|
||||||
elseif (isset($_GET["mailbox"]) &&
|
elseif (isset($_GET["mailbox"]) &&
|
||||||
filter_var($_GET["mailbox"], FILTER_VALIDATE_EMAIL) &&
|
filter_var($_GET["mailbox"], FILTER_VALIDATE_EMAIL) &&
|
||||||
|
|
|
@ -19,6 +19,23 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admi
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="ConfirmDeleteModal" class="modal fade" role="dialog">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
<h4 class="modal-title"><?=$lang['footer']['confirm_delete'];?></h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p><?=$lang['footer']['delete_these_items'];?></p>
|
||||||
|
<ul id="ItemsToDelete"></ul>
|
||||||
|
<hr />
|
||||||
|
<button class="btn btn-sm btn-danger" id="IsConfirmed"><?=$lang['footer']['delete_now'];?></button>
|
||||||
|
<button class="btn btn-sm btn-default" id="isCanceled"><?=$lang['footer']['cancel'];?></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -62,69 +62,6 @@ function hasMailboxObjectAccess($username, $role, $object) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
function init_db_schema() {
|
|
||||||
// This will be much better in future releases...
|
|
||||||
global $pdo;
|
|
||||||
try {
|
|
||||||
$stmt = $pdo->prepare("SELECT NULL FROM `admin`, `imapsync`, `tfa`");
|
|
||||||
$stmt->execute();
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
$lines = file('/web/inc/init.sql');
|
|
||||||
$data = '';
|
|
||||||
foreach ($lines as $line) {
|
|
||||||
if (substr($line, 0, 2) == '--' || $line == '') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$data .= $line;
|
|
||||||
if (substr(trim($line), -1, 1) == ';') {
|
|
||||||
$pdo->query($data);
|
|
||||||
$data = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Create index if not exists
|
|
||||||
$stmt = $pdo->query("SHOW INDEX FROM sogo_acl WHERE KEY_NAME = 'sogo_acl_c_folder_id_idx'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("CREATE INDEX sogo_acl_c_folder_id_idx ON sogo_acl(c_folder_id)");
|
|
||||||
}
|
|
||||||
$stmt = $pdo->query("SHOW INDEX FROM sogo_acl WHERE KEY_NAME = 'sogo_acl_c_uid_idx'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("CREATE INDEX sogo_acl_c_uid_idx ON sogo_acl(c_uid)");
|
|
||||||
}
|
|
||||||
$_SESSION['return'] = array(
|
|
||||||
'type' => 'success',
|
|
||||||
'msg' => 'Database initialization completed.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Add newly added columns
|
|
||||||
$stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE 'kind'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("ALTER TABLE `mailbox` ADD `kind` VARCHAR(100) NOT NULL DEFAULT ''");
|
|
||||||
}
|
|
||||||
$stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE 'multiple_bookings'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("ALTER TABLE `mailbox` ADD `multiple_bookings` tinyint(1) NOT NULL DEFAULT '0'");
|
|
||||||
}
|
|
||||||
$stmt = $pdo->query("SHOW COLUMNS FROM `imapsync` LIKE 'delete1'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("ALTER TABLE `imapsync` ADD `delete1` tinyint(1) NOT NULL DEFAULT '0'");
|
|
||||||
}
|
|
||||||
$stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE 'wants_tagged_subject'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("ALTER TABLE `mailbox` ADD `wants_tagged_subject` tinyint(1) NOT NULL DEFAULT '0'");
|
|
||||||
}
|
|
||||||
$stmt = $pdo->query("SHOW COLUMNS FROM `tfa` LIKE 'key_id'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("ALTER TABLE `tfa` ADD `key_id` VARCHAR(255) DEFAULT 'unidentified'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function verify_ssha256($hash, $password) {
|
function verify_ssha256($hash, $password) {
|
||||||
// Remove tag if any
|
// Remove tag if any
|
||||||
$hash = ltrim($hash, '{SSHA256}');
|
$hash = ltrim($hash, '{SSHA256}');
|
||||||
|
@ -287,13 +224,11 @@ function edit_admin_account($postarray) {
|
||||||
$password_hashed = hash_password($password);
|
$password_hashed = hash_password($password);
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `admin` SET
|
$stmt = $pdo->prepare("UPDATE `admin` SET
|
||||||
`modified` = :modified,
|
|
||||||
`password` = :password_hashed,
|
`password` = :password_hashed,
|
||||||
`username` = :username1
|
`username` = :username1
|
||||||
WHERE `username` = :username2");
|
WHERE `username` = :username2");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':username1' => $username,
|
':username1' => $username,
|
||||||
':username2' => $username_now
|
':username2' => $username_now
|
||||||
));
|
));
|
||||||
|
@ -309,12 +244,10 @@ function edit_admin_account($postarray) {
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `admin` SET
|
$stmt = $pdo->prepare("UPDATE `admin` SET
|
||||||
`modified` = :modified,
|
|
||||||
`username` = :username1
|
`username` = :username1
|
||||||
WHERE `username` = :username2");
|
WHERE `username` = :username2");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':username1' => $username,
|
':username1' => $username,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':username2' => $username_now
|
':username2' => $username_now
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -608,10 +541,9 @@ function edit_user_account($postarray) {
|
||||||
}
|
}
|
||||||
$password_hashed = hash_password($password_new);
|
$password_hashed = hash_password($password_new);
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `mailbox` SET `modified` = :modified, `password` = :password_hashed WHERE `username` = :username");
|
$stmt = $pdo->prepare("UPDATE `mailbox` SET `password` = :password_hashed WHERE `username` = :username");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':username' => $username
|
':username' => $username
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -1633,13 +1565,11 @@ function add_domain_admin($postarray) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `created`, `modified`, `active`)
|
$stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `active`)
|
||||||
VALUES (:username, :password_hashed, '0', :created, :modified, :active)");
|
VALUES (:username, :password_hashed, '0', :active)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':username' => $username,
|
':username' => $username,
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2228,12 +2158,11 @@ function edit_domain_admin($postarray) {
|
||||||
}
|
}
|
||||||
$password_hashed = hash_password($password);
|
$password_hashed = hash_password($password);
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username1, `modified` = :modified, `active` = :active, `password` = :password_hashed WHERE `username` = :username2");
|
$stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username1, `active` = :active, `password` = :password_hashed WHERE `username` = :username2");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':username1' => $username,
|
':username1' => $username,
|
||||||
':username2' => $username_now,
|
':username2' => $username_now,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
if (isset($postarray['disable_tfa'])) {
|
if (isset($postarray['disable_tfa'])) {
|
||||||
|
@ -2255,11 +2184,10 @@ function edit_domain_admin($postarray) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username1, `modified` = :modified, `active` = :active WHERE `username` = :username2");
|
$stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username1, `active` = :active WHERE `username` = :username2");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':username1' => $username,
|
':username1' => $username,
|
||||||
':username2' => $username_now,
|
':username2' => $username_now,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
if (isset($postarray['disable_tfa'])) {
|
if (isset($postarray['disable_tfa'])) {
|
||||||
|
@ -2321,10 +2249,9 @@ function edit_domain_admin($postarray) {
|
||||||
}
|
}
|
||||||
$password_hashed = hash_password($password_new);
|
$password_hashed = hash_password($password_new);
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `admin` SET `modified` = :modified, `password` = :password_hashed WHERE `username` = :username");
|
$stmt = $pdo->prepare("UPDATE `admin` SET `password` = :password_hashed WHERE `username` = :username");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':username' => $username
|
':username' => $username
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2356,7 +2283,7 @@ function get_admin_details() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("SELECT `username`, `modified`, `created` FROM `admin`WHERE `superadmin`='1' AND active='1'");
|
$stmt = $pdo->prepare("SELECT `username`, `modified`, `created` FROM `admin` WHERE `superadmin`='1' AND active='1'");
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
}
|
}
|
||||||
|
@ -2601,8 +2528,8 @@ function mailbox_add_domain($postarray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `maxquota`, `quota`, `transport`, `backupmx`, `created`, `modified`, `active`, `relay_all_recipients`)
|
$stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `maxquota`, `quota`, `transport`, `backupmx`, `active`, `relay_all_recipients`)
|
||||||
VALUES (:domain, :description, :aliases, :mailboxes, :maxquota, :quota, 'virtual', :backupmx, :created, :modified, :active, :relay_all_recipients)");
|
VALUES (:domain, :description, :aliases, :mailboxes, :maxquota, :quota, 'virtual', :backupmx, :active, :relay_all_recipients)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
':description' => $description,
|
':description' => $description,
|
||||||
|
@ -2612,8 +2539,6 @@ function mailbox_add_domain($postarray) {
|
||||||
':quota' => $quota,
|
':quota' => $quota,
|
||||||
':backupmx' => $backupmx,
|
':backupmx' => $backupmx,
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':relay_all_recipients' => $relay_all_recipients
|
':relay_all_recipients' => $relay_all_recipients
|
||||||
));
|
));
|
||||||
$_SESSION['return'] = array(
|
$_SESSION['return'] = array(
|
||||||
|
@ -2678,7 +2603,7 @@ function mailbox_add_alias($postarray) {
|
||||||
$address = $local_part.'@'.$domain;
|
$address = $local_part.'@'.$domain;
|
||||||
|
|
||||||
$domaindata = mailbox_get_domain_details($domain);
|
$domaindata = mailbox_get_domain_details($domain);
|
||||||
if ($domaindata['aliases_left'] == 0) {
|
if (is_array($domaindata) && $domaindata['aliases_left'] == "0") {
|
||||||
$_SESSION['return'] = array(
|
$_SESSION['return'] = array(
|
||||||
'type' => 'danger',
|
'type' => 'danger',
|
||||||
'msg' => sprintf($lang['danger']['max_alias_exceeded'])
|
'msg' => sprintf($lang['danger']['max_alias_exceeded'])
|
||||||
|
@ -2789,16 +2714,14 @@ function mailbox_add_alias($postarray) {
|
||||||
$goto = implode(",", $gotos);
|
$goto = implode(",", $gotos);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `created`, `modified`, `active`)
|
$stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `active`)
|
||||||
VALUES (:address, :goto, :domain, :created, :modified, :active)");
|
VALUES (:address, :goto, :domain, :active)");
|
||||||
|
|
||||||
if (!filter_var($address, FILTER_VALIDATE_EMAIL) === true) {
|
if (!filter_var($address, FILTER_VALIDATE_EMAIL) === true) {
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':address' => '@'.$domain,
|
':address' => '@'.$domain,
|
||||||
':goto' => $goto,
|
':goto' => $goto,
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2807,8 +2730,6 @@ function mailbox_add_alias($postarray) {
|
||||||
':address' => $address,
|
':address' => $address,
|
||||||
':goto' => $goto,
|
':goto' => $goto,
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2909,13 +2830,11 @@ function mailbox_add_alias_domain($postarray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `alias_domain` (`alias_domain`, `target_domain`, `created`, `modified`, `active`)
|
$stmt = $pdo->prepare("INSERT INTO `alias_domain` (`alias_domain`, `target_domain`, `active`)
|
||||||
VALUES (:alias_domain, :target_domain, :created, :modified, :active)");
|
VALUES (:alias_domain, :target_domain, :active)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':alias_domain' => $alias_domain,
|
':alias_domain' => $alias_domain,
|
||||||
':target_domain' => $target_domain,
|
':target_domain' => $target_domain,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
$_SESSION['return'] = array(
|
$_SESSION['return'] = array(
|
||||||
|
@ -3118,8 +3037,8 @@ function mailbox_add_mailbox($postarray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `created`, `modified`, `active`)
|
$stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `active`)
|
||||||
VALUES (:username, :password_hashed, :name, :maildir, :quota_b, :local_part, :domain, :created, :modified, :active)");
|
VALUES (:username, :password_hashed, :name, :maildir, :quota_b, :local_part, :domain, :active)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':username' => $username,
|
':username' => $username,
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
|
@ -3128,8 +3047,6 @@ function mailbox_add_mailbox($postarray) {
|
||||||
':quota_b' => $quota_b,
|
':quota_b' => $quota_b,
|
||||||
':local_part' => $local_part,
|
':local_part' => $local_part,
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -3137,14 +3054,12 @@ function mailbox_add_mailbox($postarray) {
|
||||||
VALUES (:username, '0', '0')");
|
VALUES (:username, '0', '0')");
|
||||||
$stmt->execute(array(':username' => $username));
|
$stmt->execute(array(':username' => $username));
|
||||||
|
|
||||||
$stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `created`, `modified`, `active`)
|
$stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `active`)
|
||||||
VALUES (:username1, :username2, :domain, :created, :modified, :active)");
|
VALUES (:username1, :username2, :domain, :active)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':username1' => $username,
|
':username1' => $username,
|
||||||
':username2' => $username,
|
':username2' => $username,
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -3274,15 +3189,13 @@ function mailbox_add_resource($postarray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `created`, `modified`, `active`, `multiple_bookings`, `kind`)
|
$stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `active`, `multiple_bookings`, `kind`)
|
||||||
VALUES (:name, 'RESOURCE', :description, 'RESOURCE', 0, :local_part, :domain, :created, :modified, :active, :multiple_bookings, :kind)");
|
VALUES (:name, 'RESOURCE', :description, 'RESOURCE', 0, :local_part, :domain, :active, :multiple_bookings, :kind)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':name' => $name,
|
':name' => $name,
|
||||||
':description' => $description,
|
':description' => $description,
|
||||||
':local_part' => $local_part,
|
':local_part' => $local_part,
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
':kind' => $kind,
|
':kind' => $kind,
|
||||||
':multiple_bookings' => $multiple_bookings
|
':multiple_bookings' => $multiple_bookings
|
||||||
|
@ -3373,12 +3286,10 @@ function mailbox_edit_alias_domain($postarray) {
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `alias_domain` SET
|
$stmt = $pdo->prepare("UPDATE `alias_domain` SET
|
||||||
`alias_domain` = :alias_domain,
|
`alias_domain` = :alias_domain,
|
||||||
`active` = :active,
|
`active` = :active
|
||||||
`modified` = :modified
|
|
||||||
WHERE `alias_domain` = :alias_domain_now");
|
WHERE `alias_domain` = :alias_domain_now");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':alias_domain' => $alias_domain,
|
':alias_domain' => $alias_domain,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':alias_domain_now' => $alias_domain_now,
|
':alias_domain_now' => $alias_domain_now,
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
|
@ -3397,29 +3308,20 @@ function mailbox_edit_alias_domain($postarray) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
function mailbox_edit_alias($postarray) {
|
function mailbox_edit_alias($postarray) {
|
||||||
// Array elements
|
// We can edit multiple addresses at once, but only set one "goto" and/or "active" attribute for all
|
||||||
// address string
|
// address string or array containing strings | email | required
|
||||||
// goto string (separated by " ", "," ";" "\n") - email address or domain
|
// goto string | separated by " ", "," ";" "\n", email or domain | optional
|
||||||
// active int
|
// active set (active) or unset (inactive)
|
||||||
global $lang;
|
global $lang;
|
||||||
global $pdo;
|
global $pdo;
|
||||||
$address = $postarray['address'];
|
if (!is_array($postarray['address'])) {
|
||||||
$domain = idn_to_ascii(substr(strstr($address, '@'), 1));
|
$address_array = array();
|
||||||
$local_part = strstr($address, '@', true);
|
$address_array[] = $postarray['address'];
|
||||||
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
|
|
||||||
$_SESSION['return'] = array(
|
|
||||||
'type' => 'danger',
|
|
||||||
'msg' => sprintf($lang['danger']['access_denied'])
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (empty($postarray['goto'])) {
|
else {
|
||||||
$_SESSION['return'] = array(
|
$address_array = $postarray['address'];
|
||||||
'type' => 'danger',
|
|
||||||
'msg' => sprintf($lang['danger']['goto_empty'])
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
if (isset($postarray['goto']) || !empty($postarray['goto'])) {
|
||||||
$gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
|
$gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
|
||||||
foreach ($gotos as &$goto) {
|
foreach ($gotos as &$goto) {
|
||||||
if (empty($goto)) {
|
if (empty($goto)) {
|
||||||
|
@ -3442,7 +3344,18 @@ function mailbox_edit_alias($postarray) {
|
||||||
}
|
}
|
||||||
$gotos = array_filter($gotos);
|
$gotos = array_filter($gotos);
|
||||||
$goto = implode(",", $gotos);
|
$goto = implode(",", $gotos);
|
||||||
|
}
|
||||||
isset($postarray['active']) ? $active = '1' : $active = '0';
|
isset($postarray['active']) ? $active = '1' : $active = '0';
|
||||||
|
foreach ($address_array as $address) {
|
||||||
|
$domain = idn_to_ascii(substr(strstr($address, '@'), 1));
|
||||||
|
$local_part = strstr($address, '@', true);
|
||||||
|
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => sprintf($lang['danger']['access_denied'])
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
|
if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
|
||||||
$_SESSION['return'] = array(
|
$_SESSION['return'] = array(
|
||||||
'type' => 'danger',
|
'type' => 'danger',
|
||||||
|
@ -3450,23 +3363,27 @@ function mailbox_edit_alias($postarray) {
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (isset($goto) && !empty($goto)) {
|
||||||
$stmt = $pdo->prepare("UPDATE `alias` SET
|
$stmt = $pdo->prepare("UPDATE `alias` SET
|
||||||
`goto` = :goto,
|
`goto` = :goto,
|
||||||
`active`= :active,
|
`active`= :active
|
||||||
`modified` = :modified
|
|
||||||
WHERE `address` = :address");
|
WHERE `address` = :address");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':goto' => $goto,
|
':goto' => $goto,
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
':address' => $address,
|
':address' => $address
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
));
|
));
|
||||||
$_SESSION['return'] = array(
|
}
|
||||||
'type' => 'success',
|
else {
|
||||||
'msg' => sprintf($lang['success']['alias_modified'], htmlspecialchars($address))
|
$stmt = $pdo->prepare("UPDATE `alias` SET
|
||||||
);
|
`active`= :active
|
||||||
|
WHERE `address` = :address");
|
||||||
|
$stmt->execute(array(
|
||||||
|
':active' => $active,
|
||||||
|
':address' => $address
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (PDOException $e) {
|
catch (PDOException $e) {
|
||||||
$_SESSION['return'] = array(
|
$_SESSION['return'] = array(
|
||||||
|
@ -3475,6 +3392,11 @@ function mailbox_edit_alias($postarray) {
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'success',
|
||||||
|
'msg' => sprintf($lang['success']['alias_modified'], htmlspecialchars(implode(', ', $address_array)))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
function mailbox_edit_domain($postarray) {
|
function mailbox_edit_domain($postarray) {
|
||||||
// Array elements
|
// Array elements
|
||||||
|
@ -3506,11 +3428,9 @@ function mailbox_edit_domain($postarray) {
|
||||||
isset($postarray['active']) ? $active = '1' : $active = '0';
|
isset($postarray['active']) ? $active = '1' : $active = '0';
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `domain` SET
|
$stmt = $pdo->prepare("UPDATE `domain` SET
|
||||||
`modified`= :modified,
|
|
||||||
`description` = :description
|
`description` = :description
|
||||||
WHERE `domain` = :domain");
|
WHERE `domain` = :domain");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':description' => $description,
|
':description' => $description,
|
||||||
':domain' => $domain
|
':domain' => $domain
|
||||||
));
|
));
|
||||||
|
@ -3614,7 +3534,6 @@ function mailbox_edit_domain($postarray) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `domain` SET
|
$stmt = $pdo->prepare("UPDATE `domain` SET
|
||||||
`modified`= :modified,
|
|
||||||
`relay_all_recipients` = :relay_all_recipients,
|
`relay_all_recipients` = :relay_all_recipients,
|
||||||
`backupmx` = :backupmx,
|
`backupmx` = :backupmx,
|
||||||
`active` = :active,
|
`active` = :active,
|
||||||
|
@ -3632,7 +3551,6 @@ function mailbox_edit_domain($postarray) {
|
||||||
':maxquota' => $maxquota,
|
':maxquota' => $maxquota,
|
||||||
':mailboxes' => $mailboxes,
|
':mailboxes' => $mailboxes,
|
||||||
':aliases' => $aliases,
|
':aliases' => $aliases,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':description' => $description,
|
':description' => $description,
|
||||||
':domain' => $domain
|
':domain' => $domain
|
||||||
));
|
));
|
||||||
|
@ -3844,23 +3762,19 @@ function mailbox_edit_mailbox($postarray) {
|
||||||
$password_hashed = hash_password($password);
|
$password_hashed = hash_password($password);
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `alias` SET
|
$stmt = $pdo->prepare("UPDATE `alias` SET
|
||||||
`modified` = :modified,
|
|
||||||
`active` = :active
|
`active` = :active
|
||||||
WHERE `address` = :address");
|
WHERE `address` = :address");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':address' => $username,
|
':address' => $username,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
$stmt = $pdo->prepare("UPDATE `mailbox` SET
|
$stmt = $pdo->prepare("UPDATE `mailbox` SET
|
||||||
`modified` = :modified,
|
|
||||||
`active` = :active,
|
`active` = :active,
|
||||||
`password` = :password_hashed,
|
`password` = :password_hashed,
|
||||||
`name`= :name,
|
`name`= :name,
|
||||||
`quota` = :quota_b
|
`quota` = :quota_b
|
||||||
WHERE `username` = :username");
|
WHERE `username` = :username");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
':name' => $name,
|
':name' => $name,
|
||||||
|
@ -3883,23 +3797,19 @@ function mailbox_edit_mailbox($postarray) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `alias` SET
|
$stmt = $pdo->prepare("UPDATE `alias` SET
|
||||||
`modified` = :modified,
|
|
||||||
`active` = :active
|
`active` = :active
|
||||||
WHERE `address` = :address");
|
WHERE `address` = :address");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':address' => $username,
|
':address' => $username,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
$stmt = $pdo->prepare("UPDATE `mailbox` SET
|
$stmt = $pdo->prepare("UPDATE `mailbox` SET
|
||||||
`modified` = :modified,
|
|
||||||
`active` = :active,
|
`active` = :active,
|
||||||
`name`= :name,
|
`name`= :name,
|
||||||
`quota` = :quota_b
|
`quota` = :quota_b
|
||||||
WHERE `username` = :username");
|
WHERE `username` = :username");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':name' => $name,
|
':name' => $name,
|
||||||
':quota_b' => $quota_b,
|
':quota_b' => $quota_b,
|
||||||
':username' => $username
|
':username' => $username
|
||||||
|
@ -3962,7 +3872,6 @@ function mailbox_edit_resource($postarray) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `mailbox` SET
|
$stmt = $pdo->prepare("UPDATE `mailbox` SET
|
||||||
`modified` = :modified,
|
|
||||||
`active` = :active,
|
`active` = :active,
|
||||||
`name`= :description,
|
`name`= :description,
|
||||||
`kind`= :kind,
|
`kind`= :kind,
|
||||||
|
@ -3970,7 +3879,6 @@ function mailbox_edit_resource($postarray) {
|
||||||
WHERE `username` = :name");
|
WHERE `username` = :name");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':description' => $description,
|
':description' => $description,
|
||||||
':multiple_bookings' => $multiple_bookings,
|
':multiple_bookings' => $multiple_bookings,
|
||||||
':kind' => $kind,
|
':kind' => $kind,
|
||||||
|
@ -4199,6 +4107,17 @@ function mailbox_get_alias_details($address) {
|
||||||
':address' => $address,
|
':address' => $address,
|
||||||
));
|
));
|
||||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
$stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain");
|
||||||
|
$stmt->execute(array(
|
||||||
|
':domain' => $row['domain'],
|
||||||
|
));
|
||||||
|
$row_alias_domain = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
if (isset($row_alias_domain['target_domain']) && !empty($row_alias_domain['target_domain'])) {
|
||||||
|
$aliasdata['in_primary_domain'] = $row_alias_domain['target_domain'];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$aliasdata['in_primary_domain'] = "";
|
||||||
|
}
|
||||||
$aliasdata['domain'] = $row['domain'];
|
$aliasdata['domain'] = $row['domain'];
|
||||||
$aliasdata['goto'] = $row['goto'];
|
$aliasdata['goto'] = $row['goto'];
|
||||||
$aliasdata['address'] = $row['address'];
|
$aliasdata['address'] = $row['address'];
|
||||||
|
@ -4315,6 +4234,15 @@ function mailbox_get_domain_details($domain) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
$stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain");
|
||||||
|
$stmt->execute(array(
|
||||||
|
':domain' => $domain
|
||||||
|
));
|
||||||
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
if (!empty($row)) {
|
||||||
|
$domain = $row['target_domain'];
|
||||||
|
}
|
||||||
|
|
||||||
$stmt = $pdo->prepare("SELECT
|
$stmt = $pdo->prepare("SELECT
|
||||||
`domain`,
|
`domain`,
|
||||||
`description`,
|
`description`,
|
||||||
|
@ -4330,14 +4258,18 @@ function mailbox_get_domain_details($domain) {
|
||||||
CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
|
CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
|
||||||
FROM `domain` WHERE `domain`= :domain");
|
FROM `domain` WHERE `domain`= :domain");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':domain' => $domain,
|
':domain' => $domain
|
||||||
));
|
));
|
||||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
if (empty($row)) {
|
if (empty($row)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt = $pdo->prepare("SELECT COUNT(*) AS `count`, COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND `domain` = :domain");
|
$stmt = $pdo->prepare("SELECT COUNT(*) AS `count`,
|
||||||
|
COALESCE(SUM(`quota`), 0) AS `in_use`
|
||||||
|
FROM `mailbox`
|
||||||
|
WHERE `kind` NOT REGEXP 'location|thing|group'
|
||||||
|
AND `domain` = :domain");
|
||||||
$stmt->execute(array(':domain' => $row['domain']));
|
$stmt->execute(array(':domain' => $row['domain']));
|
||||||
$MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
|
$MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
@ -4362,12 +4294,13 @@ function mailbox_get_domain_details($domain) {
|
||||||
$domaindata['relay_all_recipients_int'] = $row['relay_all_recipients_int'];
|
$domaindata['relay_all_recipients_int'] = $row['relay_all_recipients_int'];
|
||||||
|
|
||||||
$stmt = $pdo->prepare("SELECT COUNT(*) AS `alias_count` FROM `alias`
|
$stmt = $pdo->prepare("SELECT COUNT(*) AS `alias_count` FROM `alias`
|
||||||
WHERE `domain`= :domain
|
WHERE (`domain`= :domain OR `domain` = (SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = :domain2))
|
||||||
AND `address` NOT IN (
|
AND `address` NOT IN (
|
||||||
SELECT `username` FROM `mailbox`
|
SELECT `username` FROM `mailbox`
|
||||||
)");
|
)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
|
':domain2' => $domain
|
||||||
));
|
));
|
||||||
$AliasDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
|
$AliasDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
(isset($AliasDataDomain['alias_count'])) ? $domaindata['aliases_in_domain'] = $AliasDataDomain['alias_count'] : $domaindata['aliases_in_domain'] = "0";
|
(isset($AliasDataDomain['alias_count'])) ? $domaindata['aliases_in_domain'] = $AliasDataDomain['alias_count'] : $domaindata['aliases_in_domain'] = "0";
|
||||||
|
@ -4607,9 +4540,17 @@ function mailbox_delete_domain($postarray) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
function mailbox_delete_alias($postarray) {
|
function mailbox_delete_alias($postarray) {
|
||||||
|
// $postarray['address'] can be a single element or an array
|
||||||
global $lang;
|
global $lang;
|
||||||
global $pdo;
|
global $pdo;
|
||||||
$address = $postarray['address'];
|
if (!is_array($postarray['address'])) {
|
||||||
|
$address_array = array();
|
||||||
|
$address_array[] = $postarray['address'];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$address_array = $postarray['address'];
|
||||||
|
}
|
||||||
|
foreach ($address_array as $address) {
|
||||||
$local_part = strstr($address, '@', true);
|
$local_part = strstr($address, '@', true);
|
||||||
$domain = mailbox_get_alias_details($address)['domain'];
|
$domain = mailbox_get_alias_details($address)['domain'];
|
||||||
try {
|
try {
|
||||||
|
@ -4645,10 +4586,11 @@ function mailbox_delete_alias($postarray) {
|
||||||
'msg' => 'MySQL: '.$e
|
'msg' => 'MySQL: '.$e
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$_SESSION['return'] = array(
|
$_SESSION['return'] = array(
|
||||||
'type' => 'success',
|
'type' => 'success',
|
||||||
'msg' => sprintf($lang['success']['alias_removed'], htmlspecialchars($address))
|
'msg' => sprintf($lang['success']['alias_removed'], htmlspecialchars(implode(', ', $address_array)))
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4796,12 +4738,10 @@ function mailbox_delete_mailbox($postarray) {
|
||||||
}
|
}
|
||||||
$gotos_rebuild = implode(',', $goto_exploded);
|
$gotos_rebuild = implode(',', $goto_exploded);
|
||||||
$stmt = $pdo->prepare("UPDATE `alias` SET
|
$stmt = $pdo->prepare("UPDATE `alias` SET
|
||||||
`goto` = :goto,
|
`goto` = :goto
|
||||||
`modified` = :modified,
|
|
||||||
WHERE `address` = :address");
|
WHERE `address` = :address");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':goto' => $gotos_rebuild,
|
':goto' => $gotos_rebuild,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':address' => $gotos['address']
|
':address' => $gotos['address']
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -5039,4 +4979,93 @@ function get_u2f_registrations($username) {
|
||||||
$sel->execute(array($username));
|
$sel->execute(array($username));
|
||||||
return $sel->fetchAll(PDO::FETCH_OBJ);
|
return $sel->fetchAll(PDO::FETCH_OBJ);
|
||||||
}
|
}
|
||||||
|
function get_forwarding_hosts() {
|
||||||
|
global $pdo;
|
||||||
|
$sel = $pdo->prepare("SELECT host, source FROM `forwarding_hosts`");
|
||||||
|
$sel->execute();
|
||||||
|
return $sel->fetchAll(PDO::FETCH_OBJ);
|
||||||
|
}
|
||||||
|
function add_forwarding_host($postarray) {
|
||||||
|
require_once 'spf.inc.php';
|
||||||
|
global $pdo;
|
||||||
|
global $lang;
|
||||||
|
if ($_SESSION['mailcow_cc_role'] != "admin") {
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => sprintf($lang['danger']['access_denied'])
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$source = $postarray['hostname'];
|
||||||
|
$host = $postarray['hostname'];
|
||||||
|
$hosts = array();
|
||||||
|
if (preg_match('/^[0-9a-fA-F:\/]+$/', $host)) { // IPv6 address
|
||||||
|
$hosts = array($host);
|
||||||
|
}
|
||||||
|
elseif (preg_match('/^[0-9\.\/]+$/', $host)) { // IPv4 address
|
||||||
|
$hosts = array($host);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$hosts = get_outgoing_hosts_best_guess($host);
|
||||||
|
}
|
||||||
|
if (!$hosts)
|
||||||
|
{
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => 'Invalid host specified: '. htmlspecialchars($host)
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
foreach ($hosts as $host) {
|
||||||
|
if ($source == $host)
|
||||||
|
$source = '';
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->prepare("INSERT IGNORE INTO `forwarding_hosts` (`host`, `source`) VALUES (:host, :source)");
|
||||||
|
$stmt->execute(array(
|
||||||
|
':host' => $host,
|
||||||
|
':source' => $source,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
catch (PDOException $e) {
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => 'MySQL: '.$e
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'success',
|
||||||
|
'msg' => sprintf($lang['success']['forwarding_host_added'], htmlspecialchars(implode(', ', $hosts)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function delete_forwarding_host($postarray) {
|
||||||
|
global $pdo;
|
||||||
|
global $lang;
|
||||||
|
if ($_SESSION['mailcow_cc_role'] != "admin") {
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => sprintf($lang['danger']['access_denied'])
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$host = $postarray['forwardinghost'];
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM `forwarding_hosts` WHERE `host` = :host");
|
||||||
|
$stmt->execute(array(
|
||||||
|
':host' => $host,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
catch (PDOException $e) {
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => 'MySQL: '.$e
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'success',
|
||||||
|
'msg' => sprintf($lang['success']['forwarding_host_removed'], htmlspecialchars($host))
|
||||||
|
);
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,281 +0,0 @@
|
||||||
CREATE TABLE IF NOT EXISTS `admin` (
|
|
||||||
`username` VARCHAR(255) NOT NULL,
|
|
||||||
`password` VARCHAR(255) NOT NULL,
|
|
||||||
`superadmin` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
PRIMARY KEY (`username`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `alias` (
|
|
||||||
`address` VARCHAR(255) NOT NULL,
|
|
||||||
`goto` TEXT NOT NULL,
|
|
||||||
`domain` VARCHAR(255) NOT NULL,
|
|
||||||
`created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
PRIMARY KEY (`address`),
|
|
||||||
KEY `domain` (`domain`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `sender_acl` (
|
|
||||||
`logged_in_as` VARCHAR(255) NOT NULL,
|
|
||||||
`send_as` VARCHAR(255) NOT NULL
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `spamalias` (
|
|
||||||
`address` VARCHAR(255) NOT NULL,
|
|
||||||
`goto` TEXT NOT NULL,
|
|
||||||
`validity` INT(11) NOT NULL,
|
|
||||||
PRIMARY KEY (`address`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `alias_domain` (
|
|
||||||
`alias_domain` VARCHAR(255) NOT NULL,
|
|
||||||
`target_domain` VARCHAR(255) NOT NULL,
|
|
||||||
`created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
PRIMARY KEY (`alias_domain`),
|
|
||||||
KEY `active` (`active`),
|
|
||||||
KEY `target_domain` (`target_domain`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `domain` (
|
|
||||||
`domain` VARCHAR(255) NOT NULL,
|
|
||||||
`description` VARCHAR(255),
|
|
||||||
`aliases` INT(10) NOT NULL DEFAULT '0',
|
|
||||||
`mailboxes` INT(10) NOT NULL DEFAULT '0',
|
|
||||||
`maxquota` BIGINT(20) NOT NULL DEFAULT '0',
|
|
||||||
`quota` BIGINT(20) NOT NULL DEFAULT '0',
|
|
||||||
`transport` VARCHAR(255) NOT NULL,
|
|
||||||
`backupmx` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`relay_all_recipients` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
PRIMARY KEY (`domain`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `domain_admins` (
|
|
||||||
`username` VARCHAR(255) NOT NULL,
|
|
||||||
`domain` VARCHAR(255) NOT NULL,
|
|
||||||
`created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
KEY `username` (`username`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `mailbox` (
|
|
||||||
`username` VARCHAR(255) NOT NULL,
|
|
||||||
`password` VARCHAR(255) NOT NULL,
|
|
||||||
`name` VARCHAR(255),
|
|
||||||
`maildir` VARCHAR(255) NOT NULL,
|
|
||||||
`quota` BIGINT(20) NOT NULL DEFAULT '0',
|
|
||||||
`local_part` VARCHAR(255) NOT NULL,
|
|
||||||
`domain` VARCHAR(255) NOT NULL,
|
|
||||||
`created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`tls_enforce_in` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`tls_enforce_out` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`kind` VARCHAR(100) NOT NULL DEFAULT '',
|
|
||||||
`multiple_bookings` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`wants_tagged_subject` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
PRIMARY KEY (`username`),
|
|
||||||
KEY `domain` (`domain`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `quota2` (
|
|
||||||
`username` VARCHAR(100) NOT NULL,
|
|
||||||
`bytes` BIGINT(20) NOT NULL DEFAULT '0',
|
|
||||||
`messages` INT(11) NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`username`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `filterconf` (
|
|
||||||
`object` VARCHAR(100) NOT NULL DEFAULT '',
|
|
||||||
`option` VARCHAR(50) NOT NULL DEFAULT '',
|
|
||||||
`value` VARCHAR(100) NOT NULL DEFAULT '',
|
|
||||||
`prefid` INT(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
PRIMARY KEY (`prefid`),
|
|
||||||
KEY `object` (`object`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `imapsync` (
|
|
||||||
`id` INT NOT NULL AUTO_INCREMENT,
|
|
||||||
`user2` VARCHAR(255) NOT NULL,
|
|
||||||
`host1` VARCHAR(255) NOT NULL,
|
|
||||||
`authmech1` ENUM('PLAIN','LOGIN','CRAM-MD5') DEFAULT 'PLAIN',
|
|
||||||
`regextrans2` VARCHAR(255) DEFAULT '',
|
|
||||||
`authmd51` TINYINT(1) NOT NULL DEFAULT 0,
|
|
||||||
`domain2` VARCHAR(255) NOT NULL DEFAULT '',
|
|
||||||
`subfolder2` VARCHAR(255) NOT NULL DEFAULT '',
|
|
||||||
`user1` VARCHAR(255) NOT NULL,
|
|
||||||
`password1` VARCHAR(255) NOT NULL,
|
|
||||||
`exclude` VARCHAR(500) NOT NULL DEFAULT '',
|
|
||||||
`maxage` SMALLINT NOT NULL DEFAULT '0',
|
|
||||||
`mins_interval` VARCHAR(50) NOT NULL,
|
|
||||||
`port1` SMALLINT NOT NULL,
|
|
||||||
`enc1` ENUM('TLS','SSL','PLAIN') DEFAULT 'TLS',
|
|
||||||
`delete2duplicates` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
`returned_text` TEXT,
|
|
||||||
`last_run` TIMESTAMP NULL DEFAULT NULL,
|
|
||||||
`created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `tfa` (
|
|
||||||
`id` INT NOT NULL AUTO_INCREMENT,
|
|
||||||
`username` VARCHAR(255) NOT NULL,
|
|
||||||
`authmech` ENUM('yubi_otp', 'u2f', 'hotp', 'totp'),
|
|
||||||
`secret` VARCHAR(255) DEFAULT NULL,
|
|
||||||
`keyHandle` VARCHAR(255) DEFAULT NULL,
|
|
||||||
`publicKey` VARCHAR(255) DEFAULT NULL,
|
|
||||||
`counter` INT NOT NULL DEFAULT '0',
|
|
||||||
`certificate` TEXT,
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
DROP VIEW IF EXISTS grouped_mail_aliases;
|
|
||||||
DROP VIEW IF EXISTS grouped_sender_acl;
|
|
||||||
DROP VIEW IF EXISTS grouped_domain_alias_address;
|
|
||||||
|
|
||||||
CREATE VIEW grouped_mail_aliases (username, aliases) AS
|
|
||||||
SELECT goto, IFNULL(GROUP_CONCAT(address SEPARATOR ' '), '') AS address FROM alias
|
|
||||||
WHERE address!=goto
|
|
||||||
AND active = '1'
|
|
||||||
AND address NOT LIKE '@%'
|
|
||||||
GROUP BY goto;
|
|
||||||
|
|
||||||
CREATE VIEW grouped_sender_acl (username, send_as) AS
|
|
||||||
SELECT logged_in_as, IFNULL(GROUP_CONCAT(send_as SEPARATOR ' '), '') AS send_as FROM sender_acl
|
|
||||||
WHERE send_as NOT LIKE '@%'
|
|
||||||
GROUP BY logged_in_as;
|
|
||||||
|
|
||||||
CREATE VIEW grouped_domain_alias_address (username, ad_alias) AS
|
|
||||||
SELECT username, IFNULL(GROUP_CONCAT(local_part, '@', alias_domain SEPARATOR ' '), '') AS ad_alias FROM mailbox
|
|
||||||
LEFT OUTER JOIN alias_domain on target_domain=domain GROUP BY username;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_acl (
|
|
||||||
c_folder_id INTEGER NOT NULL,
|
|
||||||
c_object character varying(255) NOT NULL,
|
|
||||||
c_uid character varying(255) NOT NULL,
|
|
||||||
c_role character varying(80) NOT NULL
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_alarms_folder (
|
|
||||||
c_path VARCHAR(255) NOT NULL,
|
|
||||||
c_name VARCHAR(255) NOT NULL,
|
|
||||||
c_uid VARCHAR(255) NOT NULL,
|
|
||||||
c_recurrence_id INT(11) DEFAULT NULL,
|
|
||||||
c_alarm_number INT(11) NOT NULL,
|
|
||||||
c_alarm_date INT(11) NOT NULL
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_cache_folder (
|
|
||||||
c_uid VARCHAR(255) NOT NULL,
|
|
||||||
c_path VARCHAR(255) NOT NULL,
|
|
||||||
c_parent_path VARCHAR(255) DEFAULT NULL,
|
|
||||||
c_type TINYINT(3) unsigned NOT NULL,
|
|
||||||
c_creationdate INT(11) NOT NULL,
|
|
||||||
c_lastmodified INT(11) NOT NULL,
|
|
||||||
c_version INT(11) NOT NULL DEFAULT '0',
|
|
||||||
c_deleted TINYINT(4) NOT NULL DEFAULT '0',
|
|
||||||
c_content longTEXT,
|
|
||||||
PRIMARY KEY (c_uid,c_path)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_folder_info (
|
|
||||||
c_folder_id BIGINT(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
||||||
c_path VARCHAR(255) NOT NULL,
|
|
||||||
c_path1 VARCHAR(255) NOT NULL,
|
|
||||||
c_path2 VARCHAR(255) DEFAULT NULL,
|
|
||||||
c_path3 VARCHAR(255) DEFAULT NULL,
|
|
||||||
c_path4 VARCHAR(255) DEFAULT NULL,
|
|
||||||
c_foldername VARCHAR(255) NOT NULL,
|
|
||||||
c_location INTeger NULL,
|
|
||||||
c_quick_location VARCHAR(2048) DEFAULT NULL,
|
|
||||||
c_acl_location VARCHAR(2048) DEFAULT NULL,
|
|
||||||
c_folder_type VARCHAR(255) NOT NULL,
|
|
||||||
PRIMARY KEY (c_path),
|
|
||||||
UNIQUE KEY c_folder_id (c_folder_id)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_quick_appointment (
|
|
||||||
c_folder_id INTeger NOT NULL,
|
|
||||||
c_name character varying(255) NOT NULL,
|
|
||||||
c_uid character varying(255) NOT NULL,
|
|
||||||
c_startdate INTeger,
|
|
||||||
c_enddate INTeger,
|
|
||||||
c_cycleenddate INTeger,
|
|
||||||
c_title character varying(1000) NOT NULL,
|
|
||||||
c_participants TEXT,
|
|
||||||
c_isallday INTeger,
|
|
||||||
c_iscycle INTeger,
|
|
||||||
c_cycleinfo TEXT,
|
|
||||||
c_classification INTeger NOT NULL,
|
|
||||||
c_isopaque INTeger NOT NULL,
|
|
||||||
c_status INTeger NOT NULL,
|
|
||||||
c_priority INTeger,
|
|
||||||
c_location character varying(255),
|
|
||||||
c_orgmail character varying(255),
|
|
||||||
c_partmails TEXT,
|
|
||||||
c_partstates TEXT,
|
|
||||||
c_category character varying(255),
|
|
||||||
c_sequence INTeger,
|
|
||||||
c_component character varying(10) NOT NULL,
|
|
||||||
c_nextalarm INTeger,
|
|
||||||
c_description TEXT,
|
|
||||||
CONSTRAINT sogo_quick_appointment_pkey PRIMARY KEY (c_folder_id, c_name)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_quick_contact (
|
|
||||||
c_folder_id INTeger NOT NULL,
|
|
||||||
c_name character varying(255) NOT NULL,
|
|
||||||
c_givenname character varying(255),
|
|
||||||
c_cn character varying(255),
|
|
||||||
c_sn character varying(255),
|
|
||||||
c_screenname character varying(255),
|
|
||||||
c_l character varying(255),
|
|
||||||
c_mail character varying(255),
|
|
||||||
c_o character varying(255),
|
|
||||||
c_ou character varying(255),
|
|
||||||
c_telephonenumber character varying(255),
|
|
||||||
c_categories character varying(255),
|
|
||||||
c_component character varying(10) NOT NULL,
|
|
||||||
CONSTRAINT sogo_quick_contact_pkey PRIMARY KEY (c_folder_id, c_name)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_sessions_folder (
|
|
||||||
c_id VARCHAR(255) NOT NULL,
|
|
||||||
c_value VARCHAR(255) NOT NULL,
|
|
||||||
c_creationdate INT(11) NOT NULL,
|
|
||||||
c_lastseen INT(11) NOT NULL,
|
|
||||||
PRIMARY KEY (c_id)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_store (
|
|
||||||
c_folder_id INTeger NOT NULL,
|
|
||||||
c_name character varying(255) NOT NULL,
|
|
||||||
c_content mediumTEXT NOT NULL,
|
|
||||||
c_creationdate INTeger NOT NULL,
|
|
||||||
c_lastmodified INTeger NOT NULL,
|
|
||||||
c_version INTeger NOT NULL,
|
|
||||||
c_deleted INTeger,
|
|
||||||
CONSTRAINT sogo_store_pkey PRIMARY KEY (c_folder_id, c_name)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_user_profile (
|
|
||||||
c_uid VARCHAR(255) NOT NULL,
|
|
||||||
c_defaults TEXT,
|
|
||||||
c_settings TEXT,
|
|
||||||
PRIMARY KEY (c_uid)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
INSERT INTO `admin` (username, password, superadmin, created, modified, active) SELECT 'admin', '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1 WHERE NOT EXISTS (SELECT * FROM `admin`);
|
|
||||||
DELETE FROM `domain_admins`;
|
|
||||||
INSERT INTO `domain_admins` (username, domain, created, active) SELECT `username`, 'ALL', NOW(), 1 FROM `admin` WHERE superadmin='1' AND `username` NOT IN (SELECT `username` FROM `domain_admins`);
|
|
|
@ -0,0 +1,596 @@
|
||||||
|
<?php
|
||||||
|
function init_db_schema() {
|
||||||
|
try {
|
||||||
|
global $pdo;
|
||||||
|
|
||||||
|
$db_version = "23042017_1807";
|
||||||
|
|
||||||
|
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
if ($num_results != 0) {
|
||||||
|
$stmt = $pdo->query("SELECT `version` FROM `versions`");
|
||||||
|
if ($stmt->fetch(PDO::FETCH_ASSOC)['version'] == $db_version) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$views = array(
|
||||||
|
"grouped_mail_aliases" => "CREATE VIEW grouped_mail_aliases (username, aliases) AS
|
||||||
|
SELECT goto, IFNULL(GROUP_CONCAT(address SEPARATOR ' '), '') AS address FROM alias
|
||||||
|
WHERE address!=goto
|
||||||
|
AND active = '1'
|
||||||
|
AND address NOT LIKE '@%'
|
||||||
|
GROUP BY goto;",
|
||||||
|
"grouped_sender_acl" => "CREATE VIEW grouped_sender_acl (username, send_as) AS
|
||||||
|
SELECT logged_in_as, IFNULL(GROUP_CONCAT(send_as SEPARATOR ' '), '') AS send_as FROM sender_acl
|
||||||
|
WHERE send_as NOT LIKE '@%'
|
||||||
|
GROUP BY logged_in_as;",
|
||||||
|
"grouped_domain_alias_address" => "CREATE VIEW grouped_domain_alias_address (username, ad_alias) AS
|
||||||
|
SELECT username, IFNULL(GROUP_CONCAT(local_part, '@', alias_domain SEPARATOR ' '), '') AS ad_alias FROM mailbox
|
||||||
|
LEFT OUTER JOIN alias_domain on target_domain=domain GROUP BY username;"
|
||||||
|
);
|
||||||
|
|
||||||
|
$tables = array(
|
||||||
|
"versions" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"application" => "VARCHAR(255) NOT NULL",
|
||||||
|
"version" => "VARCHAR(100) NOT NULL",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("application")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"admin" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"username" => "VARCHAR(255) NOT NULL",
|
||||||
|
"password" => "VARCHAR(255) NOT NULL",
|
||||||
|
"superadmin" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"modified" => "DATETIME ON UPDATE NOW(0)",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("username")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"alias" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"address" => "VARCHAR(255) NOT NULL",
|
||||||
|
"goto" => "TEXT NOT NULL",
|
||||||
|
"domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("address")
|
||||||
|
),
|
||||||
|
"key" => array(
|
||||||
|
"domain" => array("domain")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sender_acl" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"logged_in_as" => "VARCHAR(255) NOT NULL",
|
||||||
|
"send_as" => "VARCHAR(255) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"domain" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"description" => "VARCHAR(255)",
|
||||||
|
"aliases" => "INT(10) NOT NULL DEFAULT '0'",
|
||||||
|
"mailboxes" => "INT(10) NOT NULL DEFAULT '0'",
|
||||||
|
"maxquota" => "BIGINT(20) NOT NULL DEFAULT '0'",
|
||||||
|
"quota" => "BIGINT(20) NOT NULL DEFAULT '0'",
|
||||||
|
"transport" => "VARCHAR(255) NOT NULL",
|
||||||
|
"backupmx" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"relay_all_recipients" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("domain")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"alias_domain" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"alias_domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"target_domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("alias_domain")
|
||||||
|
),
|
||||||
|
"key" => array(
|
||||||
|
"active" => array("active"),
|
||||||
|
"target_domain" => array("target_domain")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"spamalias" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"address" => "VARCHAR(255) NOT NULL",
|
||||||
|
"goto" => "TEXT NOT NULL",
|
||||||
|
"validity" => "INT(11) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("address")
|
||||||
|
),
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"filterconf" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"object" => "VARCHAR(255) NOT NULL DEFAULT ''",
|
||||||
|
"option" => "VARCHAR(50) NOT NULL DEFAULT ''",
|
||||||
|
"value" => "VARCHAR(100) NOT NULL DEFAULT ''",
|
||||||
|
"prefid" => "INT(11) NOT NULL AUTO_INCREMENT"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("prefid")
|
||||||
|
),
|
||||||
|
"key" => array(
|
||||||
|
"object" => array("object")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"quota2" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"username" => "VARCHAR(255) NOT NULL",
|
||||||
|
"bytes" => "BIGINT(20) NOT NULL DEFAULT '0'",
|
||||||
|
"messages" => "BIGINT(20) NOT NULL DEFAULT '0'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("username")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"mailbox" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"username" => "VARCHAR(255) NOT NULL",
|
||||||
|
"password" => "VARCHAR(255) NOT NULL",
|
||||||
|
"name" => "VARCHAR(255)",
|
||||||
|
"maildir" => "VARCHAR(255) NOT NULL",
|
||||||
|
"quota" => "BIGINT(20) NOT NULL DEFAULT '0'",
|
||||||
|
"local_part" => "VARCHAR(255) NOT NULL",
|
||||||
|
"domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"tls_enforce_in" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"tls_enforce_out" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"kind" => "VARCHAR(100) NOT NULL DEFAULT ''",
|
||||||
|
"multiple_bookings" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"wants_tagged_subject" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("username")
|
||||||
|
),
|
||||||
|
"key" => array(
|
||||||
|
"domain" => array("domain")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"domain_admins" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"username" => "VARCHAR(255) NOT NULL",
|
||||||
|
"domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"key" => array(
|
||||||
|
"username" => array("username")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"imapsync" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"id" => "INT NOT NULL AUTO_INCREMENT",
|
||||||
|
"user2" => "VARCHAR(255) NOT NULL",
|
||||||
|
"host1" => "VARCHAR(255) NOT NULL",
|
||||||
|
"authmech1" => "ENUM('PLAIN','LOGIN','CRAM-MD5') DEFAULT 'PLAIN'",
|
||||||
|
"regextrans2" => "VARCHAR(255) DEFAULT ''",
|
||||||
|
"authmd51" => "TINYINT(1) NOT NULL DEFAULT 0",
|
||||||
|
"domain2" => "VARCHAR(255) NOT NULL DEFAULT ''",
|
||||||
|
"subfolder2" => "VARCHAR(255) NOT NULL DEFAULT ''",
|
||||||
|
"user1" => "VARCHAR(255) NOT NULL",
|
||||||
|
"password1" => "VARCHAR(255) NOT NULL",
|
||||||
|
"exclude" => "VARCHAR(500) NOT NULL DEFAULT ''",
|
||||||
|
"maxage" => "SMALLINT NOT NULL DEFAULT '0'",
|
||||||
|
"mins_interval" => "VARCHAR(50) NOT NULL",
|
||||||
|
"port1" => "SMALLINT NOT NULL",
|
||||||
|
"enc1" => "ENUM('TLS','SSL','PLAIN') DEFAULT 'TLS'",
|
||||||
|
"delete2duplicates" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||||
|
"returned_text" => "TEXT",
|
||||||
|
"last_run" => "TIMESTAMP NULL DEFAULT NULL",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '0'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("id")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"tfa" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"id" => "INT NOT NULL AUTO_INCREMENT",
|
||||||
|
"username" => "VARCHAR(255) NOT NULL",
|
||||||
|
"authmech" => "ENUM('yubi_otp', 'u2f', 'hotp', 'totp')",
|
||||||
|
"secret" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"keyHandle" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"publicKey" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"counter" => "INT NOT NULL DEFAULT '0'",
|
||||||
|
"certificate" => "TEXT",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '0'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("id")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"forwarding_hosts" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"host" => "VARCHAR(255) NOT NULL",
|
||||||
|
"source" => "VARCHAR(255) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("host")
|
||||||
|
),
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_acl" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_folder_id" => "INT NOT NULL",
|
||||||
|
"c_object" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_uid" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_role" => "VARCHAR(80) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"key" => array(
|
||||||
|
"sogo_acl_c_folder_id_idx" => array("c_folder_id"),
|
||||||
|
"sogo_acl_c_uid_idx" => array("c_uid")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_alarms_folder" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_path" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_name" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_uid" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_recurrence_id" => "INT(11) DEFAULT NULL",
|
||||||
|
"c_alarm_number" => "INT(11) NOT NULL",
|
||||||
|
"c_alarm_date" => "INT(11) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_cache_folder" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_uid" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_path" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_parent_path" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"c_type" => "TINYINT(3) unsigned NOT NULL",
|
||||||
|
"c_creationdate" => "INT(11) NOT NULL",
|
||||||
|
"c_lastmodified" => "INT(11) NOT NULL",
|
||||||
|
"c_version" => "INT(11) NOT NULL DEFAULT '0'",
|
||||||
|
"c_deleted" => "TINYINT(4) NOT NULL DEFAULT '0'",
|
||||||
|
"c_content" => "LONGTEXT"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_uid", "c_path")
|
||||||
|
),
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_folder_info" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_folder_id" => "BIGINT(20) unsigned NOT NULL AUTO_INCREMENT",
|
||||||
|
"c_path" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_path1" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_path2" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"c_path3" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"c_path4" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"c_foldername" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_location" => "INT NULL",
|
||||||
|
"c_quick_location" => "VARCHAR(2048) DEFAULT NULL",
|
||||||
|
"c_acl_location" => "VARCHAR(2048) DEFAULT NULL",
|
||||||
|
"c_folder_type" => "VARCHAR(255) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_path")
|
||||||
|
),
|
||||||
|
"unique" => array(
|
||||||
|
"c_folder_id" => array("c_folder_id")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_quick_appointment" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_folder_id" => "INT NOT NULL",
|
||||||
|
"c_name" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_uid" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_startdate" => "INT",
|
||||||
|
"c_enddate" => "INT",
|
||||||
|
"c_cycleenddate" => "INT",
|
||||||
|
"c_title" => "VARCHAR(1000) NOT NULL",
|
||||||
|
"c_participants" => "TEXT",
|
||||||
|
"c_isallday" => "INT",
|
||||||
|
"c_iscycle" => "INT",
|
||||||
|
"c_cycleinfo" => "TEXT",
|
||||||
|
"c_classification" => "INT NOT NULL",
|
||||||
|
"c_isopaque" => "INT NOT NULL",
|
||||||
|
"c_status" => "INT NOT NULL",
|
||||||
|
"c_priority" => "INT",
|
||||||
|
"c_location" => "VARCHAR(255)",
|
||||||
|
"c_orgmail" => "VARCHAR(255)",
|
||||||
|
"c_partmails" => "TEXT",
|
||||||
|
"c_partstates" => "TEXT",
|
||||||
|
"c_category" => "VARCHAR(255)",
|
||||||
|
"c_sequence" => "INT",
|
||||||
|
"c_component" => "VARCHAR(10) NOT NULL",
|
||||||
|
"c_nextalarm" => "INT",
|
||||||
|
"c_description" => "TEXT"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_folder_id", "c_name")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_quick_contact" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_folder_id" => "INT NOT NULL",
|
||||||
|
"c_name" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_givenname" => "VARCHAR(255)",
|
||||||
|
"c_cn" => "VARCHAR(255)",
|
||||||
|
"c_sn" => "VARCHAR(255)",
|
||||||
|
"c_screenname" => "VARCHAR(255)",
|
||||||
|
"c_l" => "VARCHAR(255)",
|
||||||
|
"c_mail" => "VARCHAR(255)",
|
||||||
|
"c_o" => "VARCHAR(255)",
|
||||||
|
"c_ou" => "VARCHAR(255)",
|
||||||
|
"c_telephonenumber" => "VARCHAR(255)",
|
||||||
|
"c_categories" => "VARCHAR(255)",
|
||||||
|
"c_component" => "VARCHAR(10) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_folder_id", "c_name")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_sessions_folder" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_id" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_value" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_creationdate" => "INT(11) NOT NULL",
|
||||||
|
"c_lastseen" => "INT(11) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_id")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_store" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_folder_id" => "INT NOT NULL",
|
||||||
|
"c_name" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_content" => "MEDIUMTEXT NOT NULL",
|
||||||
|
"c_creationdate" => "INT NOT NULL",
|
||||||
|
"c_lastmodified" => "INT NOT NULL",
|
||||||
|
"c_version" => "INT NOT NULL",
|
||||||
|
"c_deleted" => "INT"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_folder_id", "c_name")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_user_profile" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_uid" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_defaults" => "TEXT",
|
||||||
|
"c_settings" => "TEXT"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_uid")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($tables as $table => $properties) {
|
||||||
|
$stmt = $pdo->query("SHOW TABLES LIKE '" . $table . "'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
if ($num_results != 0) {
|
||||||
|
foreach($properties['cols'] as $column => $type) {
|
||||||
|
$stmt = $pdo->query("SHOW COLUMNS FROM `" . $table . "` LIKE '" . $column . "'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
if ($num_results == 0) {
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` ADD `" . $column . "` " . $type);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` MODIFY COLUMN `" . $column . "` " . $type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach($properties['keys'] as $key_type => $key_content) {
|
||||||
|
if (strtolower($key_type) == 'primary') {
|
||||||
|
foreach ($key_content as $key_values) {
|
||||||
|
$fields = "`" . implode("`, `", $key_values) . "`";
|
||||||
|
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = 'PRIMARY'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
$is_drop = ($num_results != 0) ? "DROP PRIMARY KEY, " : "";
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` " . $is_drop . "ADD PRIMARY KEY (" . $fields . ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strtolower($key_type) == 'key') {
|
||||||
|
foreach ($key_content as $key_name => $key_values) {
|
||||||
|
$fields = "`" . implode("`, `", $key_values) . "`";
|
||||||
|
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = '" . $key_name . "'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
$is_drop = ($num_results != 0) ? "DROP INDEX `" . $key_name . "`, " : "";
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` " . $is_drop . "ADD KEY `" . $key_name . "` (" . $fields . ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strtolower($key_type) == 'unique') {
|
||||||
|
foreach ($key_content as $key_name => $key_values) {
|
||||||
|
$fields = "`" . implode("`, `", $key_values) . "`";
|
||||||
|
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = '" . $key_name . "'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
$is_drop = ($num_results != 0) ? "DROP INDEX `" . $key_name . "`, " : "";
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` " . $is_drop . "ADD UNIQUE KEY `" . $key_name . "` (" . $fields . ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Drop all vanished columns
|
||||||
|
$stmt = $pdo->query("SHOW COLUMNS FROM `" . $table . "`");
|
||||||
|
$cols_in_table = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
while ($row = array_shift($cols_in_table)) {
|
||||||
|
if (!array_key_exists($row['Field'], $properties['cols'])) {
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` DROP COLUMN `" . $row['Field'] . "`;");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 1: Get all non-primary keys, that currently exist and those that should exist
|
||||||
|
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE `Key_name` != 'PRIMARY'");
|
||||||
|
$keys_in_table = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$keys_to_exist = array();
|
||||||
|
if (isset($properties['keys']['unique']) && is_array($properties['keys']['unique'])) {
|
||||||
|
foreach ($properties['keys']['unique'] as $key_name => $key_values) {
|
||||||
|
$keys_to_exist[] = $key_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isset($properties['keys']['key']) && is_array($properties['keys']['key'])) {
|
||||||
|
foreach ($properties['keys']['key'] as $key_name => $key_values) {
|
||||||
|
$keys_to_exist[] = $key_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Step 2: Drop all vanished indexes
|
||||||
|
while ($row = array_shift($keys_in_table)) {
|
||||||
|
if (!in_array($row['Key_name'], $keys_to_exist)) {
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` DROP INDEX `" . $row['Key_name'] . "`");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Step 3: Drop all vanished primary keys
|
||||||
|
if (!isset($properties['keys']['primary'])) {
|
||||||
|
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = 'PRIMARY'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
if ($num_results != 0) {
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` DROP PRIMARY KEY");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Create table if it is missing
|
||||||
|
$sql = "CREATE TABLE IF NOT EXISTS `" . $table . "` (";
|
||||||
|
foreach($properties['cols'] as $column => $type) {
|
||||||
|
$sql .= $column . " " . $type . ",";
|
||||||
|
}
|
||||||
|
foreach($properties['keys'] as $key_type => $key_content) {
|
||||||
|
if (strtolower($key_type) == 'primary') {
|
||||||
|
foreach ($key_content as $key_values) {
|
||||||
|
$fields = "`" . implode("`, `", $key_values) . "`";
|
||||||
|
$sql .= "PRIMARY KEY (" . $fields . ")" . ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (strtolower($key_type) == 'key') {
|
||||||
|
foreach ($key_content as $key_name => $key_values) {
|
||||||
|
$fields = "`" . implode("`, `", $key_values) . "`";
|
||||||
|
$sql .= "KEY `" . $key_name . "` (" . $fields . ")" . ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (strtolower($key_type) == 'unique') {
|
||||||
|
foreach ($key_content as $key_name => $key_values) {
|
||||||
|
$fields = "`" . implode("`, `", $key_values) . "`";
|
||||||
|
$sql .= "UNIQUE KEY `" . $key_name . "` (" . $fields . ")" . ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sql = rtrim($sql, ",");
|
||||||
|
$sql .= ") " . $properties['attr'];
|
||||||
|
$pdo->query($sql);
|
||||||
|
}
|
||||||
|
// Reset table attributes
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` " . $properties['attr'] . ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recreate SQL views
|
||||||
|
foreach ($views as $view => $create) {
|
||||||
|
$pdo->query("DROP VIEW IF EXISTS `" . $view . "`;");
|
||||||
|
$pdo->query($create);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inject admin if not exists
|
||||||
|
$stmt = $pdo->query("INSERT INTO `admin` (`username`, `password`, `superadmin`, `created`, `modified`, `active`)
|
||||||
|
SELECT 'admin', '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1
|
||||||
|
WHERE NOT EXISTS (SELECT * FROM `admin`);");
|
||||||
|
$stmt = $pdo->query("DELETE FROM `domain_admins`;");
|
||||||
|
$stmt = $pdo->query("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
|
||||||
|
SELECT `username`, 'ALL', NOW(), 1 FROM `admin`
|
||||||
|
WHERE superadmin='1' AND `username` NOT IN (SELECT `username` FROM `domain_admins`);");
|
||||||
|
|
||||||
|
// Insert new DB schema version
|
||||||
|
$stmt = $pdo->query("REPLACE INTO `versions` (`application`, `version`) VALUES ('db_schema', '" . $db_version . "');");
|
||||||
|
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'success',
|
||||||
|
'msg' => 'Database initialisation completed'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (PDOException $e) {
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => 'Database initialisation failed: ' . $e->getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -29,18 +29,28 @@ require_once 'inc/lib/U2F.php';
|
||||||
$u2f = new u2flib_server\U2F('https://' . $_SERVER['SERVER_NAME']);
|
$u2f = new u2flib_server\U2F('https://' . $_SERVER['SERVER_NAME']);
|
||||||
|
|
||||||
// PDO
|
// PDO
|
||||||
$dsn = "$database_type:host=$database_host;dbname=$database_name";
|
// Calculate offset
|
||||||
|
$now = new DateTime();
|
||||||
|
$mins = $now->getOffset() / 60;
|
||||||
|
$sgn = ($mins < 0 ? -1 : 1);
|
||||||
|
$mins = abs($mins);
|
||||||
|
$hrs = floor($mins / 60);
|
||||||
|
$mins -= $hrs * 60;
|
||||||
|
$offset = sprintf('%+d:%02d', $hrs*$sgn, $mins);
|
||||||
|
|
||||||
|
$dsn = $database_type . ":host=" . $database_host . ";dbname=" . $database_name;
|
||||||
$opt = [
|
$opt = [
|
||||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
PDO::ATTR_EMULATE_PREPARES => false,
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
|
PDO::MYSQL_ATTR_INIT_COMMAND => "SET time_zone = '" . $offset . "'",
|
||||||
];
|
];
|
||||||
try {
|
try {
|
||||||
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
|
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
|
||||||
}
|
}
|
||||||
catch (PDOException $e) {
|
catch (PDOException $e) {
|
||||||
?>
|
?>
|
||||||
<center style='font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;'>🐮 Connection failed, database may be in warm-up state, please try again later.<br /><br />The following error was reported:<br/> <?=$e->getMessage();?></center>
|
<center style='font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;'>?? Connection failed, database may be in warm-up state, please try again later.<br /><br />The following error was reported:<br/> <?=$e->getMessage();?></center>
|
||||||
<?php
|
<?php
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
@ -106,5 +116,6 @@ if (isset($_GET['lang'])) {
|
||||||
require_once 'lang/lang.en.php';
|
require_once 'lang/lang.en.php';
|
||||||
include 'lang/lang.'.$_SESSION['mailcow_locale'].'.php';
|
include 'lang/lang.'.$_SESSION['mailcow_locale'].'.php';
|
||||||
require_once 'inc/functions.inc.php';
|
require_once 'inc/functions.inc.php';
|
||||||
|
require_once 'inc/init_db.inc.php';
|
||||||
require_once 'inc/triggers.inc.php';
|
require_once 'inc/triggers.inc.php';
|
||||||
(!isset($_SESSION['mailcow_cc_username'])) ? init_db_schema() : null;
|
init_db_schema();
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
<?php
|
||||||
|
function get_spf_allowed_hosts($domain)
|
||||||
|
{
|
||||||
|
$hosts = array();
|
||||||
|
|
||||||
|
$records = dns_get_record($domain, DNS_TXT);
|
||||||
|
foreach ($records as $record)
|
||||||
|
{
|
||||||
|
$txt = explode(' ', $record['entries'][0]);
|
||||||
|
if (array_shift($txt) != 'v=spf1') // only handle SPF records
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach ($txt as $mech)
|
||||||
|
{
|
||||||
|
$qual = substr($mech, 0, 1);
|
||||||
|
if ($qual == '-' || $qual == '~') // only handle pass or neutral records
|
||||||
|
continue(2);
|
||||||
|
|
||||||
|
if ($qual == '+' || $qual == '?')
|
||||||
|
$mech = substr($mech, 1); // remove the qualifier
|
||||||
|
|
||||||
|
if (strpos($mech, '=') !== FALSE) // handle a modifier
|
||||||
|
{
|
||||||
|
$mod = explode('=', $mech);
|
||||||
|
if ($mod[0] == 'redirect') // handle a redirect
|
||||||
|
{
|
||||||
|
$hosts = get_spf_allowed_hosts($mod[1]);
|
||||||
|
return $hosts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($cidr);
|
||||||
|
if (strpos($mech, ':') !== FALSE) // handle a domain specification
|
||||||
|
{
|
||||||
|
$split = explode(':', $mech);
|
||||||
|
$mech = array_shift($split);
|
||||||
|
$domain = implode(':', $split);
|
||||||
|
if (strpos($domain, '/') !== FALSE) // remove CIDR specification
|
||||||
|
{
|
||||||
|
$split = explode('/', $domain);
|
||||||
|
$domain = $split[0];
|
||||||
|
$cidr = $split[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_hosts = array();
|
||||||
|
if ($mech == 'include') // handle an inclusion
|
||||||
|
{
|
||||||
|
$new_hosts = get_spf_allowed_hosts($domain);
|
||||||
|
}
|
||||||
|
elseif ($mech == 'a') // handle a mechanism
|
||||||
|
{
|
||||||
|
$new_hosts = get_a_hosts($domain);
|
||||||
|
}
|
||||||
|
elseif ($mech == 'mx') // handle mx mechanism
|
||||||
|
{
|
||||||
|
$new_hosts = get_mx_hosts($domain);
|
||||||
|
}
|
||||||
|
elseif ($mech == 'ip4' || $mech == 'ip6') // handle ip mechanism
|
||||||
|
{
|
||||||
|
$new_hosts = array($domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($cidr)) // add CIDR specification if present
|
||||||
|
{
|
||||||
|
foreach ($new_hosts as &$host)
|
||||||
|
{
|
||||||
|
$host .= '/' . $cidr;
|
||||||
|
}
|
||||||
|
unset($host);
|
||||||
|
}
|
||||||
|
|
||||||
|
$hosts = array_unique(array_merge($hosts,$new_hosts), SORT_REGULAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_mx_hosts($domain)
|
||||||
|
{
|
||||||
|
$hosts = array();
|
||||||
|
|
||||||
|
$mx_records = dns_get_record($domain, DNS_MX);
|
||||||
|
foreach ($mx_records as $mx_record)
|
||||||
|
{
|
||||||
|
$new_hosts = get_a_hosts($mx_record['target']);
|
||||||
|
$hosts = array_unique(array_merge($hosts,$new_hosts), SORT_REGULAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_a_hosts($domain)
|
||||||
|
{
|
||||||
|
$hosts = array();
|
||||||
|
|
||||||
|
$a_records = dns_get_record($domain, DNS_A);
|
||||||
|
foreach ($a_records as $a_record)
|
||||||
|
{
|
||||||
|
$hosts[] = $a_record['ip'];
|
||||||
|
}
|
||||||
|
$a_records = dns_get_record($domain, DNS_AAAA);
|
||||||
|
foreach ($a_records as $a_record)
|
||||||
|
{
|
||||||
|
$hosts[] = $a_record['ipv6'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_outgoing_hosts_best_guess($domain)
|
||||||
|
{
|
||||||
|
// try the SPF record to get hosts that are allowed to send outgoing mails for this domain
|
||||||
|
$hosts = get_spf_allowed_hosts($domain);
|
||||||
|
if ($hosts) return $hosts;
|
||||||
|
|
||||||
|
// try the MX record to get mail servers for this domain
|
||||||
|
$hosts = get_mx_hosts($domain);
|
||||||
|
if ($hosts) return $hosts;
|
||||||
|
|
||||||
|
// fall back to the A record to get the host name for this domain
|
||||||
|
return get_a_hosts($domain);
|
||||||
|
}
|
||||||
|
?>
|
|
@ -72,6 +72,12 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admi
|
||||||
if (isset($_POST["delete_domain_admin"])) {
|
if (isset($_POST["delete_domain_admin"])) {
|
||||||
delete_domain_admin($_POST);
|
delete_domain_admin($_POST);
|
||||||
}
|
}
|
||||||
|
if (isset($_POST["add_forwarding_host"])) {
|
||||||
|
add_forwarding_host($_POST);
|
||||||
|
}
|
||||||
|
if (isset($_POST["delete_forwarding_host"])) {
|
||||||
|
delete_forwarding_host($_POST);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "user") {
|
if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "user") {
|
||||||
if (isset($_POST["edit_user_account"])) {
|
if (isset($_POST["edit_user_account"])) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ $(document).ready(function() {
|
||||||
// add.php
|
// add.php
|
||||||
// Get max. possible quota for a domain when domain field changes
|
// Get max. possible quota for a domain when domain field changes
|
||||||
$('#addSelectDomain').on('change', function() {
|
$('#addSelectDomain').on('change', function() {
|
||||||
$.get("/api/v1/domain/" + this.value, function(data){
|
$.get("/api/v1/get/domain/" + this.value, function(data){
|
||||||
var result = jQuery.parseJSON( data );
|
var result = jQuery.parseJSON( data );
|
||||||
max_new_mailbox_quota = ( result.max_new_mailbox_quota / 1048576);
|
max_new_mailbox_quota = ( result.max_new_mailbox_quota / 1048576);
|
||||||
if (max_new_mailbox_quota != '0') {
|
if (max_new_mailbox_quota != '0') {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
url: '/api/v1/domain-admin/all',
|
url: '/api/v1/get/domain-admin/all',
|
||||||
jsonp: false,
|
jsonp: false,
|
||||||
error: function () {
|
error: function () {
|
||||||
alert('Cannot draw domain administrator table');
|
alert('Cannot draw domain administrator table');
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -15,7 +15,7 @@ $(document).ready(function() {
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
url: '/api/v1/domain/all',
|
url: '/api/v1/get/domain/all',
|
||||||
jsonp: false,
|
jsonp: false,
|
||||||
error: function () {
|
error: function () {
|
||||||
alert('Cannot draw domain table');
|
alert('Cannot draw domain table');
|
||||||
|
@ -24,7 +24,7 @@ $(document).ready(function() {
|
||||||
$.each(data, function (i, item) {
|
$.each(data, function (i, item) {
|
||||||
item.aliases = item.aliases_in_domain + " / " + item.max_num_aliases_for_domain;
|
item.aliases = item.aliases_in_domain + " / " + item.max_num_aliases_for_domain;
|
||||||
item.mailboxes = item.mboxes_in_domain + " / " + item.max_num_mboxes_for_domain;
|
item.mailboxes = item.mboxes_in_domain + " / " + item.max_num_mboxes_for_domain;
|
||||||
item.quota = humanFileSize(item.quota_used_in_domain) + " / " + humanFileSize(item.max_quota_for_domain);
|
item.quota = item.quota_used_in_domain + "/" + item.max_quota_for_domain;
|
||||||
item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
|
item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
|
||||||
if (role == "admin") {
|
if (role == "admin") {
|
||||||
item.action = '<div class="btn-group">' +
|
item.action = '<div class="btn-group">' +
|
||||||
|
@ -43,7 +43,15 @@ $(document).ready(function() {
|
||||||
{"sorted": true,"name":"domain_name","title":lang.domain,"style":{"width":"250px"}},
|
{"sorted": true,"name":"domain_name","title":lang.domain,"style":{"width":"250px"}},
|
||||||
{"name":"aliases","title":lang.aliases,"breakpoints":"xs sm"},
|
{"name":"aliases","title":lang.aliases,"breakpoints":"xs sm"},
|
||||||
{"name":"mailboxes","title":lang.mailboxes},
|
{"name":"mailboxes","title":lang.mailboxes},
|
||||||
{"name":"quota","title":lang.domain_quota},
|
{"name":"quota","style":{"whiteSpace":"nowrap"},"title":lang.domain_quota,"formatter": function(value){
|
||||||
|
res = value.split("/");
|
||||||
|
return humanFileSize(res[0]) + " / " + humanFileSize(res[1]);
|
||||||
|
},
|
||||||
|
"sortValue": function(value){
|
||||||
|
res = value.split("/");
|
||||||
|
return res[0];
|
||||||
|
},
|
||||||
|
},
|
||||||
{"name":"max_quota_for_mbox","title":lang.mailbox_quota,"breakpoints":"xs sm"},
|
{"name":"max_quota_for_mbox","title":lang.mailbox_quota,"breakpoints":"xs sm"},
|
||||||
{"name":"backupmx","filterable": false,"style":{"maxWidth":"120px","width":"120px"},"title":lang.backup_mx,"breakpoints":"xs sm"},
|
{"name":"backupmx","filterable": false,"style":{"maxWidth":"120px","width":"120px"},"title":lang.backup_mx,"breakpoints":"xs sm"},
|
||||||
{"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active},
|
{"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active},
|
||||||
|
@ -70,14 +78,14 @@ $(document).ready(function() {
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
url: '/api/v1/mailbox/all',
|
url: '/api/v1/get/mailbox/all',
|
||||||
jsonp: false,
|
jsonp: false,
|
||||||
error: function () {
|
error: function () {
|
||||||
alert('Cannot draw mailbox table');
|
alert('Cannot draw mailbox table');
|
||||||
},
|
},
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
$.each(data, function (i, item) {
|
$.each(data, function (i, item) {
|
||||||
item.quota = humanFileSize(item.quota_used) + " / " + humanFileSize(item.quota);
|
item.quota = item.quota_used + "/" + item.quota;
|
||||||
item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
|
item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
|
||||||
if (role == "admin") {
|
if (role == "admin") {
|
||||||
item.action = '<div class="btn-group">' +
|
item.action = '<div class="btn-group">' +
|
||||||
|
@ -102,7 +110,15 @@ $(document).ready(function() {
|
||||||
{"sorted": true,"name":"username","title":lang.username,"style":{"width":"250px"}},
|
{"sorted": true,"name":"username","title":lang.username,"style":{"width":"250px"}},
|
||||||
{"name":"name","title":lang.fname,"breakpoints":"xs sm"},
|
{"name":"name","title":lang.fname,"breakpoints":"xs sm"},
|
||||||
{"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
|
{"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
|
||||||
{"name":"quota","style":{"whiteSpace":"nowrap"},"title":lang.domain_quota},
|
{"name":"quota","style":{"whiteSpace":"nowrap"},"title":lang.domain_quota,"formatter": function(value){
|
||||||
|
res = value.split("/");
|
||||||
|
return humanFileSize(res[0]) + " / " + humanFileSize(res[1]);
|
||||||
|
},
|
||||||
|
"sortValue": function(value){
|
||||||
|
res = value.split("/");
|
||||||
|
return res[0];
|
||||||
|
},
|
||||||
|
},
|
||||||
{"name":"spam_aliases","filterable": false,"title":lang.spam_aliases,"breakpoints":"xs sm md"},
|
{"name":"spam_aliases","filterable": false,"title":lang.spam_aliases,"breakpoints":"xs sm md"},
|
||||||
{"name":"in_use","filterable": false,"style":{"whiteSpace":"nowrap"},"type":"html","title":lang.in_use},
|
{"name":"in_use","filterable": false,"style":{"whiteSpace":"nowrap"},"type":"html","title":lang.in_use},
|
||||||
{"name":"messages","filterable": false,"style":{"whiteSpace":"nowrap"},"title":lang.msg_num,"breakpoints":"xs sm md"},
|
{"name":"messages","filterable": false,"style":{"whiteSpace":"nowrap"},"title":lang.msg_num,"breakpoints":"xs sm md"},
|
||||||
|
@ -130,7 +146,7 @@ $(document).ready(function() {
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
url: '/api/v1/resource/all',
|
url: '/api/v1/get/resource/all',
|
||||||
jsonp: false,
|
jsonp: false,
|
||||||
error: function () {
|
error: function () {
|
||||||
alert('Cannot draw resource table');
|
alert('Cannot draw resource table');
|
||||||
|
@ -172,7 +188,7 @@ $(document).ready(function() {
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
url: '/api/v1/alias-domain/all',
|
url: '/api/v1/get/alias-domain/all',
|
||||||
jsonp: false,
|
jsonp: false,
|
||||||
error: function () {
|
error: function () {
|
||||||
alert('Cannot draw alias domain table');
|
alert('Cannot draw alias domain table');
|
||||||
|
@ -212,23 +228,28 @@ $(document).ready(function() {
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
url: '/api/v1/alias/all',
|
url: '/api/v1/get/alias/all',
|
||||||
jsonp: false,
|
jsonp: false,
|
||||||
error: function () {
|
error: function () {
|
||||||
alert('Cannot draw alias table');
|
alert('Cannot draw alias table');
|
||||||
},
|
},
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
$.each(data, function (i, item) {
|
$.each(data, function (i, item) {
|
||||||
|
item.action = '<div class="btn-group">' +
|
||||||
|
'<a href="/edit.php?alias=' + encodeURI(item.address) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
|
||||||
|
'<a href="/delete.php?alias=' + encodeURI(item.address) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-pencil"></span> ' + lang.remove + '</a>' +
|
||||||
|
'</div>';
|
||||||
|
item.chkbox = '<input type="checkbox" class="alias_item" name="sel_aliases" value="' + item.address + '" />';
|
||||||
if (item.is_catch_all == 1) {
|
if (item.is_catch_all == 1) {
|
||||||
item.address = '<div class="label label-default">Catch-All</div> ' + item.address;
|
item.address = '<div class="label label-default">Catch-All</div> ' + item.address;
|
||||||
}
|
}
|
||||||
item.action = '<div class="btn-group">' +
|
if (item.in_primary_domain !== "") {
|
||||||
'<a href="/edit.php?alias=' + encodeURI(item.address) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
|
item.domain = "↳ " + item.domain + " (" + item.in_primary_domain + ")";
|
||||||
'<a href="/delete.php?alias=' + encodeURI(item.address) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
|
}
|
||||||
'</div>';
|
|
||||||
});
|
});
|
||||||
$('#alias_table').footable({
|
ft_aliases = FooTable.init("#alias_table", {
|
||||||
"columns": [
|
"columns": [
|
||||||
|
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
|
||||||
{"sorted": true,"name":"address","title":lang.alias,"style":{"width":"250px"}},
|
{"sorted": true,"name":"address","title":lang.alias,"style":{"width":"250px"}},
|
||||||
{"name":"goto","title":lang.target_address},
|
{"name":"goto","title":lang.target_address},
|
||||||
{"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
|
{"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
|
||||||
|
@ -251,6 +272,98 @@ $(document).ready(function() {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var selected_aliases = [];
|
||||||
|
|
||||||
|
$(document).on('click', 'tr', function(e) {
|
||||||
|
if (e.target.type == "checkbox") {
|
||||||
|
e.stopPropagation();
|
||||||
|
} else {
|
||||||
|
var checkbox = $(this).find(':checkbox');
|
||||||
|
checkbox.trigger('click');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(document).on('change', 'input[name=sel_aliases]:checkbox', function() {
|
||||||
|
if ($(this).is(':checked')) {
|
||||||
|
selected_aliases.push($(this).val());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
selected_aliases.splice($.inArray($(this).val(), selected_aliases),1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '#select_all_aliases', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var alias_chkbxs = $("input[name=sel_aliases]");
|
||||||
|
alias_chkbxs.prop("checked", !alias_chkbxs.prop("checked")).change();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '#activate_selected_alias', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (selected_aliases.length !== 0) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
data: { "address": JSON.stringify(selected_aliases), "active": "1" },
|
||||||
|
url: '/api/v1/edit/alias',
|
||||||
|
jsonp: false,
|
||||||
|
complete: function (data) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '#deactivate_selected_alias', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (Object.keys(selected_aliases).length !== 0) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
data: { "address": JSON.stringify(selected_aliases), "active": "0" },
|
||||||
|
url: '/api/v1/edit/alias',
|
||||||
|
jsonp: false,
|
||||||
|
complete: function (data) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '#delete_selected_alias', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (Object.keys(selected_aliases).length !== 0) {
|
||||||
|
$(document).on('show.bs.modal','#ConfirmDeleteModal', function () {
|
||||||
|
$("#ItemsToDelete").empty();
|
||||||
|
for (var i in selected_aliases) {
|
||||||
|
$("#ItemsToDelete").append("<li>" + selected_aliases[i] + "</li>");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$('#ConfirmDeleteModal').modal({
|
||||||
|
backdrop: 'static',
|
||||||
|
keyboard: false
|
||||||
|
})
|
||||||
|
.one('click', '#IsConfirmed', function(e) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
data: { "address": JSON.stringify(selected_aliases) },
|
||||||
|
url: '/api/v1/delete/alias',
|
||||||
|
jsonp: false,
|
||||||
|
complete: function (data) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.one('click', '#isCanceled', function(e) {
|
||||||
|
$('#ConfirmDeleteModal').modal('hide');
|
||||||
|
});;
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +1,31 @@
|
||||||
<?php
|
<?php
|
||||||
|
/*
|
||||||
|
edit/alias => POST data:
|
||||||
|
{
|
||||||
|
address: {a, b, c}, (where a, b, c represent alias addresses)
|
||||||
|
active: 1 (0 or 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
delete/alias => POST data:
|
||||||
|
{
|
||||||
|
address: {a, b, c}, (where a, b, c represent alias addresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
header('Content-Type: application/json');
|
||||||
require_once 'inc/prerequisites.inc.php';
|
require_once 'inc/prerequisites.inc.php';
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_username'])) {
|
if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_username'])) {
|
||||||
if (isset($_GET['action']) && isset($_GET['object'])) {
|
if (isset($_GET['query'])) {
|
||||||
$action = filter_input(INPUT_GET, 'action', FILTER_SANITIZE_STRING);
|
|
||||||
$object = filter_input(INPUT_GET, 'object', FILTER_SANITIZE_STRING);
|
$query = explode('/', $_GET['query']);
|
||||||
|
$action = (isset($query[0])) ? $query[0] : null;
|
||||||
|
$category = (isset($query[1])) ? $query[1] : null;
|
||||||
|
$object = (isset($query[2])) ? $query[2] : null;
|
||||||
|
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
|
case "get":
|
||||||
|
switch ($category) {
|
||||||
case "domain":
|
case "domain":
|
||||||
switch ($object) {
|
switch ($object) {
|
||||||
case "all":
|
case "all":
|
||||||
|
@ -239,5 +259,63 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
|
||||||
echo '{}';
|
echo '{}';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case "delete":
|
||||||
|
switch ($category) {
|
||||||
|
case "alias":
|
||||||
|
if (isset($_POST['address'])) {
|
||||||
|
$address = json_decode($_POST['address'], true);
|
||||||
|
if (is_array($address)) {
|
||||||
|
if (mailbox_delete_alias(array('address' => $address)) === false) {
|
||||||
|
echo json_encode(array(
|
||||||
|
'type' => 'error',
|
||||||
|
'message' => 'Deletion of item failed'
|
||||||
|
));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
echo json_encode(array(
|
||||||
|
'type' => 'success',
|
||||||
|
'message' => 'Task completed'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo json_encode(array(
|
||||||
|
'type' => 'error',
|
||||||
|
'message' => 'Cannot find address array in post data'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "edit":
|
||||||
|
switch ($category) {
|
||||||
|
case "alias":
|
||||||
|
if (isset($_POST['address']) && isset($_POST['active'])) {
|
||||||
|
$address = json_decode($_POST['address'], true);
|
||||||
|
if (is_array($address)) {
|
||||||
|
if (mailbox_edit_alias(array('address' => $address, 'active' => ($_POST['active'] == "1") ? $active = 1 : null)) === false) {
|
||||||
|
echo json_encode(array(
|
||||||
|
'type' => 'error',
|
||||||
|
'message' => 'Edit item failed'
|
||||||
|
));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
echo json_encode(array(
|
||||||
|
'type' => 'success',
|
||||||
|
'message' => 'Task completed'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo json_encode(array(
|
||||||
|
'type' => 'error',
|
||||||
|
'message' => 'Cannot find address array in post data'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,6 +9,12 @@ $lang['header']['restart_sogo'] = 'SOGo neustarten';
|
||||||
$lang['footer']['restart_sogo'] = 'SOGo neustarten';
|
$lang['footer']['restart_sogo'] = 'SOGo neustarten';
|
||||||
$lang['footer']['restart_now'] = 'Jetzt neustarten';
|
$lang['footer']['restart_now'] = 'Jetzt neustarten';
|
||||||
$lang['footer']['restart_sogo_info'] = 'Einige Änderungen an Domains benötigen einen Neustart SOGos. Hier können Sie SOGo neustarten.<br /><br /><b>Wichtig:</b> Ein korrekter Neustart SOGos kann eine Weile in Anspruch nehmen, bitte warten Sie, bis der Prozess vollständig beendet wurde.';
|
$lang['footer']['restart_sogo_info'] = 'Einige Änderungen an Domains benötigen einen Neustart SOGos. Hier können Sie SOGo neustarten.<br /><br /><b>Wichtig:</b> Ein korrekter Neustart SOGos kann eine Weile in Anspruch nehmen, bitte warten Sie, bis der Prozess vollständig beendet wurde.';
|
||||||
|
|
||||||
|
$lang['footer']['confirm_delete'] = 'Löschen bestätigen';
|
||||||
|
$lang['footer']['delete_these_items'] = 'Sind Sie sicher, dass die folgenden Elemente entfernt werden sollen?';
|
||||||
|
$lang['footer']['delete_now'] = 'Jetzt löschen';
|
||||||
|
$lang['footer']['cancel'] = 'Abbrechen';
|
||||||
|
|
||||||
$lang['dkim']['confirm'] = 'Sind Sie sicher?';
|
$lang['dkim']['confirm'] = 'Sind Sie sicher?';
|
||||||
$lang['danger']['dkim_not_found'] = 'DKIM-Key nicht gefunden';
|
$lang['danger']['dkim_not_found'] = 'DKIM-Key nicht gefunden';
|
||||||
$lang['danger']['dkim_remove_failed'] = 'Kann DKIM-Key nicht entfernen';
|
$lang['danger']['dkim_remove_failed'] = 'Kann DKIM-Key nicht entfernen';
|
||||||
|
@ -249,9 +255,12 @@ $lang['mailbox']['add_mailbox'] = 'Mailbox hinzufügen';
|
||||||
$lang['mailbox']['add_resource'] = 'Ressource hinzufügen';
|
$lang['mailbox']['add_resource'] = 'Ressource hinzufügen';
|
||||||
$lang['mailbox']['add_alias'] = 'Alias hinzufügen';
|
$lang['mailbox']['add_alias'] = 'Alias hinzufügen';
|
||||||
$lang['mailbox']['empty'] = 'Keine Einträge vorhanden';
|
$lang['mailbox']['empty'] = 'Keine Einträge vorhanden';
|
||||||
|
$lang['mailbox']['toggle_all'] = 'Alle';
|
||||||
|
$lang['mailbox']['quick_actions'] = 'Aktionen';
|
||||||
|
$lang['mailbox']['activate'] = 'Aktivieren';
|
||||||
|
$lang['mailbox']['deactivate'] = 'Deaktivieren';
|
||||||
|
|
||||||
$lang['info']['no_action'] = 'Keine Aktion anwendbar';
|
$lang['info']['no_action'] = 'Keine Aktion anwendbar';
|
||||||
|
|
||||||
$lang['delete']['title'] = 'Objekt entfernen';
|
$lang['delete']['title'] = 'Objekt entfernen';
|
||||||
$lang['delete']['remove_domain_warning'] = '<b>Warnung:</b> Sie entfernen die Domain <b>%s</b>!';
|
$lang['delete']['remove_domain_warning'] = '<b>Warnung:</b> Sie entfernen die Domain <b>%s</b>!';
|
||||||
$lang['delete']['remove_domainalias_warning'] = '<b>Warnung:</b> Sie entfernen die Alias-Domain <b>%s</b>!';
|
$lang['delete']['remove_domainalias_warning'] = '<b>Warnung:</b> Sie entfernen die Alias-Domain <b>%s</b>!';
|
||||||
|
@ -450,11 +459,20 @@ $lang['admin']['unchanged_if_empty'] = 'Unverändert, wenn leer';
|
||||||
$lang['admin']['yes'] = '✔';
|
$lang['admin']['yes'] = '✔';
|
||||||
$lang['admin']['no'] = '✘';
|
$lang['admin']['no'] = '✘';
|
||||||
$lang['admin']['access'] = 'Zugang';
|
$lang['admin']['access'] = 'Zugang';
|
||||||
$lang['admin']['invalid_max_msg_size'] = 'Invalid max. message size'; // NEEDS TRANSLATION
|
$lang['admin']['invalid_max_msg_size'] = 'Ungültige maximale Nachrichtengröße';
|
||||||
$lang['admin']['site_not_found'] = 'Kann mailcow Site-Konfiguration nicht finden';
|
$lang['admin']['site_not_found'] = 'Kann mailcow Site-Konfiguration nicht finden';
|
||||||
$lang['admin']['public_folder_empty'] = 'Public folder name must not be empty'; // NEEDS TRANSLATION
|
$lang['admin']['public_folder_empty'] = 'Name des öffentlichen Ordners darf nicht leer sein';
|
||||||
$lang['admin']['set_rr_failed'] = 'Kann Postfix Restriktionen nicht setzen';
|
$lang['admin']['set_rr_failed'] = 'Kann Postfix Restriktionen nicht setzen';
|
||||||
$lang['admin']['no_record'] = 'Kein Eintrag';
|
$lang['admin']['no_record'] = 'Kein Eintrag';
|
||||||
$lang['admin']['filter_table'] = 'Tabelle Filtern';
|
$lang['admin']['filter_table'] = 'Tabelle Filtern';
|
||||||
$lang['admin']['empty'] = 'Keine Einträge vorhanden';
|
$lang['admin']['empty'] = 'Keine Einträge vorhanden';
|
||||||
|
$lang['admin']['forwarding_hosts'] = 'Weiterleitungs-Hosts';
|
||||||
|
$lang['admin']['forwarding_hosts_hint'] = 'Eingehende Nachrichten werden von den hier gelisteten Hosts bedingungslos akzeptiert. Diese Hosts werden dann nicht mit DNSBLs abgeglichen oder Greylisting unterworfen. Von ihnen empfangener Spam wird nie abgelehnt und immer in den Spam-Ordner einsortiert. Die übliche Verwendung für diese Funktion ist, um Mailserver anzugeben, auf denen eine Weiterleitung zu Ihrem Mailcow-Server eingerichtet wurde.';
|
||||||
|
$lang['admin']['forwarding_hosts_add_hint'] = 'Sie können entweder IPv4/IPv6-Adressen, Netzwerke in CIDR-Notation, Hostnamen (die zu IP-Adressen aufgelöst werden), oder Domainnamen (die zu IP-Adressen aufgelöst werden, indem ihr SPF-Record abgefragt wird oder, in dessen Abwesenheit, ihre MX-Records) angeben.';
|
||||||
|
$lang['edit']['host'] = 'Host';
|
||||||
|
$lang['edit']['source'] = 'Quelle';
|
||||||
|
$lang['admin']['add_forwarding_host'] = 'Weiterleitungs-Host hinzufügen';
|
||||||
|
$lang['delete']['remove_forwardinghost_warning'] = '<b>Warnung:</b> Sie entfernen den Weiterleitungs-Host <b>%s</b>!';
|
||||||
|
$lang['success']['forwarding_host_removed'] = "Weiterleitungs-Host %s wurde entfernt";
|
||||||
|
$lang['success']['forwarding_host_added'] = "Weiterleitungs-Host %s wurde hinzugefügt";
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -9,6 +9,12 @@ $lang['header']['restart_sogo'] = 'Restart SOGo';
|
||||||
$lang['footer']['restart_sogo'] = 'Restart SOGo';
|
$lang['footer']['restart_sogo'] = 'Restart SOGo';
|
||||||
$lang['footer']['restart_now'] = 'Restart now';
|
$lang['footer']['restart_now'] = 'Restart now';
|
||||||
$lang['footer']['restart_sogo_info'] = 'Some tasks, e.g. adding a domain, require you to restart SOGo to catch changes made in the mailcow UI.<br /><br /><b>Important:</b> A graceful restart may take a while to complete, please wait for it to finish.';
|
$lang['footer']['restart_sogo_info'] = 'Some tasks, e.g. adding a domain, require you to restart SOGo to catch changes made in the mailcow UI.<br /><br /><b>Important:</b> A graceful restart may take a while to complete, please wait for it to finish.';
|
||||||
|
|
||||||
|
$lang['footer']['confirm_delete'] = 'Confirm deletion';
|
||||||
|
$lang['footer']['delete_these_items'] = 'Are you sure you want to delete the following items?';
|
||||||
|
$lang['footer']['delete_now'] = 'Delete now';
|
||||||
|
$lang['footer']['cancel'] = 'Cancel';
|
||||||
|
|
||||||
$lang['dkim']['confirm'] = "Are you sure?";
|
$lang['dkim']['confirm'] = "Are you sure?";
|
||||||
$lang['danger']['dkim_not_found'] = "DKIM key not found";
|
$lang['danger']['dkim_not_found'] = "DKIM key not found";
|
||||||
$lang['danger']['dkim_remove_failed'] = "Cannot remove selected DKIM key";
|
$lang['danger']['dkim_remove_failed'] = "Cannot remove selected DKIM key";
|
||||||
|
@ -40,7 +46,7 @@ $lang['danger']['alias_goto_identical'] = "Alias and goto address must not be id
|
||||||
$lang['danger']['aliasd_targetd_identical'] = "Alias domain must not be equal to target domain";
|
$lang['danger']['aliasd_targetd_identical'] = "Alias domain must not be equal to target domain";
|
||||||
$lang['danger']['maxquota_empty'] = 'Max. quota per mailbox must not be 0.';
|
$lang['danger']['maxquota_empty'] = 'Max. quota per mailbox must not be 0.';
|
||||||
$lang['success']['alias_added'] = "Alias address/es has/have been added";
|
$lang['success']['alias_added'] = "Alias address/es has/have been added";
|
||||||
$lang['success']['alias_modified'] = "Changes to alias have been saved";
|
$lang['success']['alias_modified'] = "Changes to alias/es %s have been saved";
|
||||||
$lang['success']['aliasd_modified'] = "Changes to alias domain have been saved";
|
$lang['success']['aliasd_modified'] = "Changes to alias domain have been saved";
|
||||||
$lang['success']['mailbox_modified'] = "Changes to mailbox %s have been saved";
|
$lang['success']['mailbox_modified'] = "Changes to mailbox %s have been saved";
|
||||||
$lang['success']['resource_modified'] = "Changes to mailbox %s have been saved";
|
$lang['success']['resource_modified'] = "Changes to mailbox %s have been saved";
|
||||||
|
@ -79,7 +85,7 @@ $lang['danger']['mailbox_quota_left_exceeded'] = "Not enough space left (space l
|
||||||
$lang['success']['mailbox_added'] = "Mailbox %s has been added";
|
$lang['success']['mailbox_added'] = "Mailbox %s has been added";
|
||||||
$lang['success']['resource_added'] = "Resource %s has been added";
|
$lang['success']['resource_added'] = "Resource %s has been added";
|
||||||
$lang['success']['domain_removed'] = "Domain %s has been removed";
|
$lang['success']['domain_removed'] = "Domain %s has been removed";
|
||||||
$lang['success']['alias_removed'] = "Alias-Adresse %s has been removed";
|
$lang['success']['alias_removed'] = "Alias %s has been removed";
|
||||||
$lang['success']['alias_domain_removed'] = "Alias domain %s has been removed";
|
$lang['success']['alias_domain_removed'] = "Alias domain %s has been removed";
|
||||||
$lang['success']['domain_admin_removed'] = "Domain administrator %s has been removed";
|
$lang['success']['domain_admin_removed'] = "Domain administrator %s has been removed";
|
||||||
$lang['success']['mailbox_removed'] = "Mailbox %s has been removed";
|
$lang['success']['mailbox_removed'] = "Mailbox %s has been removed";
|
||||||
|
@ -252,6 +258,10 @@ $lang['mailbox']['add_resource'] = 'Add resource';
|
||||||
$lang['mailbox']['add_alias'] = 'Add alias';
|
$lang['mailbox']['add_alias'] = 'Add alias';
|
||||||
$lang['mailbox']['add_domain_record_first'] = 'Please add a domain first';
|
$lang['mailbox']['add_domain_record_first'] = 'Please add a domain first';
|
||||||
$lang['mailbox']['empty'] = 'No results';
|
$lang['mailbox']['empty'] = 'No results';
|
||||||
|
$lang['mailbox']['toggle_all'] = 'Toggle all';
|
||||||
|
$lang['mailbox']['quick_actions'] = 'Quick actions';
|
||||||
|
$lang['mailbox']['activate'] = 'Activate';
|
||||||
|
$lang['mailbox']['deactivate'] = 'Deactivate';
|
||||||
|
|
||||||
$lang['info']['no_action'] = 'No action applicable';
|
$lang['info']['no_action'] = 'No action applicable';
|
||||||
|
|
||||||
|
@ -468,4 +478,13 @@ $lang['admin']['set_rr_failed'] = 'Cannot set Postfix restrictions';
|
||||||
$lang['admin']['no_record'] = 'No record';
|
$lang['admin']['no_record'] = 'No record';
|
||||||
$lang['admin']['filter_table'] = 'Filter table';
|
$lang['admin']['filter_table'] = 'Filter table';
|
||||||
$lang['admin']['empty'] = 'No results';
|
$lang['admin']['empty'] = 'No results';
|
||||||
|
$lang['admin']['forwarding_hosts'] = 'Forwarding Hosts';
|
||||||
|
$lang['admin']['forwarding_hosts_hint'] = 'Incoming messages are unconditionally accepted from any hosts listed here. These hosts are then not checked against DNSBLs or subjected to greylisting. Spam received from them is never rejected and always filed into the Junk folder. The most common use for this is to specify mail servers on which you have set up a rule that forwards incoming emails to your Mailcow server.';
|
||||||
|
$lang['admin']['forwarding_hosts_add_hint'] = 'You can either specify IPv4/IPv6 addresses, networks in CIDR notation, host names (which will be resolved to IP addresses), or domain names (which will be resolved to IP addresses by querying SPF records or, in their absence, MX records).';
|
||||||
|
$lang['edit']['host'] = 'Host';
|
||||||
|
$lang['edit']['source'] = 'Source';
|
||||||
|
$lang['admin']['add_forwarding_host'] = 'Add Forwarding Host';
|
||||||
|
$lang['delete']['remove_forwardinghost_warning'] = '<b>Warning:</b> You are about to remove the forwarding host <b>%s</b>!';
|
||||||
|
$lang['success']['forwarding_host_removed'] = "Forwarding host %s has been removed";
|
||||||
|
$lang['success']['forwarding_host_added'] = "Forwarding host %s has been added";
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -6,8 +6,25 @@ require_once "inc/header.inc.php";
|
||||||
$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
||||||
?>
|
?>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
|
<li role="presentation" class="active"><a href="#tab-domains" aria-controls="tab-domains" role="tab" data-toggle="tab"><?=$lang['mailbox']['domains'];?></a></li>
|
||||||
|
<li role="presentation"><a href="#tab-mailboxes" aria-controls="tab-mailboxes" role="tab" data-toggle="tab"><?=$lang['mailbox']['mailboxes'];?></a></li>
|
||||||
|
<li role="presentation"><a href="#tab-resources" aria-controls="tab-resources" role="tab" data-toggle="tab"><?=$lang['mailbox']['resources'];?></a></li>
|
||||||
|
<li class="dropdown">
|
||||||
|
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['aliases'];?>
|
||||||
|
<span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li role="presentation"><a href="#tab-mbox-aliases" aria-controls="tab-mbox-aliases" role="tab" data-toggle="tab"><?=$lang['mailbox']['aliases'];?></a></li>
|
||||||
|
<li role="presentation"><a href="#tab-domain-aliases" aria-controls="tab-domain-aliases" role="tab" data-toggle="tab"><?=$lang['mailbox']['domain_aliases'];?></a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
|
<div class="tab-content" style="padding-top:20px">
|
||||||
|
<div role="tabpanel" class="tab-pane active" id="tab-domains">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
|
@ -27,10 +44,8 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
||||||
<span class="footer-add-item"><a href="/add.php?domain"><?=$lang['mailbox']['add_domain'];?></a></span>
|
<span class="footer-add-item"><a href="/add.php?domain"><?=$lang['mailbox']['add_domain'];?></a></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
<div role="tabpanel" class="tab-pane" id="tab-mailboxes">
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
|
@ -44,10 +59,8 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
||||||
<span class="footer-add-item"><a href="/add.php?mailbox"><?=$lang['mailbox']['add_mailbox'];?></a></span>
|
<span class="footer-add-item"><a href="/add.php?mailbox"><?=$lang['mailbox']['add_mailbox'];?></a></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
<div role="tabpanel" class="tab-pane" id="tab-resources">
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
|
@ -58,12 +71,11 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table id="resources_table" class="table table-striped"></table>
|
<table id="resources_table" class="table table-striped"></table>
|
||||||
</div>
|
</div>
|
||||||
<span class="footer-add-item"><a href="/add.php?resource"><?=$lang['mailbox']['add_resource'];?></a></span> </div>
|
<span class="footer-add-item"><a href="/add.php?resource"><?=$lang['mailbox']['add_resource'];?></a></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div role="tabpanel" class="tab-pane" id="tab-domain-aliases">
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
|
@ -74,26 +86,39 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table id="aliasdomain_table" class="table table-striped"></table>
|
<table id="aliasdomain_table" class="table table-striped"></table>
|
||||||
</div>
|
</div>
|
||||||
<span class="footer-add-item"><a href="/add.php?aliasdomain"><?=$lang['mailbox']['add_domain_alias'];?></a></span> </div>
|
<span class="footer-add-item"><a href="/add.php?aliasdomain"><?=$lang['mailbox']['add_domain_alias'];?></a></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div role="tabpanel" class="tab-pane" id="tab-mbox-aliases">
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<div class="pull-right">
|
<a class="pull-right" href="/add.php?alias"><span class="glyphicon glyphicon-plus"></span></a>
|
||||||
<a href="/add.php?alias"><span class="glyphicon glyphicon-plus"></span></a>
|
|
||||||
</div>
|
|
||||||
<h3 class="panel-title"><?=$lang['mailbox']['aliases'];?></h3>
|
<h3 class="panel-title"><?=$lang['mailbox']['aliases'];?></h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table id="alias_table" class="table table-striped"></table>
|
<table id="alias_table" class="table table-striped"></table>
|
||||||
</div>
|
</div>
|
||||||
<span class="footer-add-item"><a href="/add.php?alias"><?=$lang['mailbox']['add_alias'];?></a></span> </div>
|
<div class="mass-actions">
|
||||||
|
<p id="select_all_aliases" class="mass-select-all">
|
||||||
|
↪ <?=$lang['mailbox']['toggle_all'];?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="footer-add-item">
|
||||||
|
<a class="pull-right" href="/add.php?alias"><span class="glyphicon glyphicon-plus"></span></a>
|
||||||
|
<b><?=$lang['mailbox']['quick_actions'];?>:</b>
|
||||||
|
<a id="delete_selected_alias" href="#" class="mass-each-action"><?=$lang['mailbox']['remove'];?></a> |
|
||||||
|
<a id="activate_selected_alias" href="#" class="mass-each-action"><?=$lang['mailbox']['activate'];?></a> |
|
||||||
|
<a id="deactivate_selected_alias" href="#" class="mass-each-action"><?=$lang['mailbox']['deactivate'];?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div> <!-- /tab-content -->
|
||||||
|
</div> <!-- /col-md-12 -->
|
||||||
|
</div> <!-- /row -->
|
||||||
</div> <!-- /container -->
|
</div> <!-- /container -->
|
||||||
|
|
||||||
<script type='text/javascript'>
|
<script type='text/javascript'>
|
||||||
<?php
|
<?php
|
||||||
$lang_mailbox = json_encode($lang['mailbox']);
|
$lang_mailbox = json_encode($lang['mailbox']);
|
||||||
|
|
|
@ -1,156 +0,0 @@
|
||||||
<?php
|
|
||||||
require_once('inc/prerequisites.inc.php');
|
|
||||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
|
|
||||||
|
|
||||||
$u2f = new u2flib_server\U2F('https://' . $_SERVER['SERVER_NAME']);
|
|
||||||
|
|
||||||
function getRegs($username) {
|
|
||||||
global $pdo;
|
|
||||||
$sel = $pdo->prepare("select * from tfa where username = ?");
|
|
||||||
$sel->execute(array($username));
|
|
||||||
return $sel->fetchAll();
|
|
||||||
}
|
|
||||||
function addReg($username, $reg) {
|
|
||||||
global $pdo;
|
|
||||||
$ins = $pdo->prepare("INSERT INTO `tfa` (`username`, `keyHandle`, `publicKey`, `certificate`, `counter`) values (?, ?, ?, ?, ?)");
|
|
||||||
$ins->execute(array($username, $reg->keyHandle, $reg->publicKey, $reg->certificate, $reg->counter));
|
|
||||||
}
|
|
||||||
function updateReg($reg) {
|
|
||||||
global $pdo;
|
|
||||||
$upd = $pdo->prepare("update tfa set counter = ? where id = ?");
|
|
||||||
$upd->execute(array($reg->counter, $reg->id));
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<script src="js/u2f-api.js"></script>
|
|
||||||
<?php
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
||||||
if ((empty($_POST['u2f_username'])) || (!isset($_POST['action']) && !isset($_POST['u2f_register_data']) && !isset($_POST['u2f_auth_data']))) {
|
|
||||||
print_r($_POST);
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$username = $_POST['u2f_username'];
|
|
||||||
if (isset($_POST['action'])) {
|
|
||||||
switch($_POST['action']) {
|
|
||||||
case 'register':
|
|
||||||
try {
|
|
||||||
$data = $u2f->getRegisterData(getRegs($username));
|
|
||||||
list($req, $sigs) = $data;
|
|
||||||
$_SESSION['regReq'] = json_encode($req);
|
|
||||||
?>
|
|
||||||
<script>
|
|
||||||
var req = <?=json_encode($req);?>;
|
|
||||||
var sigs = <?=json_encode($sigs);?>;
|
|
||||||
var username = "<?=$username;?>";
|
|
||||||
setTimeout(function() {
|
|
||||||
console.log("Register: ", req);
|
|
||||||
u2f.register([req], sigs, function(data) {
|
|
||||||
var form = document.getElementById('u2f_form');
|
|
||||||
var reg = document.getElementById('u2f_register_data');
|
|
||||||
var user = document.getElementById('u2f_username');
|
|
||||||
var status = document.getElementById('u2f_status');
|
|
||||||
console.log("Register callback", data);
|
|
||||||
if (data.errorCode && data.errorCode != 0) {
|
|
||||||
var div = document.getElementById('u2f_return_code');
|
|
||||||
div.innerHTML = 'Error code: ' + data.errorCode;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
reg.value = JSON.stringify(data);
|
|
||||||
user.value = username;
|
|
||||||
status.value = "1";
|
|
||||||
form.submit();
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
</script>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
catch( Exception $e ) {
|
|
||||||
echo "U2F error: " . $e->getMessage();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'authenticate':
|
|
||||||
try {
|
|
||||||
$reqs = json_encode($u2f->getAuthenticateData(getRegs($username)));
|
|
||||||
$_SESSION['authReq'] = $reqs;
|
|
||||||
?>
|
|
||||||
<script>
|
|
||||||
var req = <?=$reqs;?>;
|
|
||||||
var username = "<?=$username;?>";
|
|
||||||
setTimeout(function() {
|
|
||||||
console.log("sign: ", req);
|
|
||||||
u2f.sign(req, function(data) {
|
|
||||||
var form = document.getElementById('u2f_form');
|
|
||||||
var auth = document.getElementById('u2f_auth_data');
|
|
||||||
var user = document.getElementById('u2f_username');
|
|
||||||
console.log("Authenticate callback", data);
|
|
||||||
auth.value = JSON.stringify(data);
|
|
||||||
user.value = username;
|
|
||||||
form.submit();
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
</script>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
echo "U2F error: " . $e->getMessage();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!empty($_POST['u2f_register_data'])) {
|
|
||||||
try {
|
|
||||||
$reg = $u2f->doRegister(json_decode($_SESSION['regReq']), json_decode($_POST['u2f_register_data']));
|
|
||||||
addReg($username, $reg);
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
echo "U2F error: " . $e->getMessage();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
echo "Success";
|
|
||||||
$_SESSION['regReq'] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!empty($_POST['u2f_auth_data'])) {
|
|
||||||
try {
|
|
||||||
$reg = $u2f->doAuthenticate(json_decode($_SESSION['authReq']), getRegs($username), json_decode($_POST['u2f_auth_data']));
|
|
||||||
updateReg($reg);
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
echo "U2F error: " . $e->getMessage();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
echo "Success";
|
|
||||||
$_SESSION['authReq'] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="u2f_return_code"></div>
|
|
||||||
<form method="POST" id="u2f_form">
|
|
||||||
<input type="hidden" name="u2f_register_data" id="u2f_register_data"/>
|
|
||||||
<input type="hidden" name="u2f_auth_data" id="u2f_auth_data"/>
|
|
||||||
<input type="hidden" name="u2f_username" id="u2f_username"/><br/>
|
|
||||||
<input type="hidden" name="u2f_status" id="u2f_status"/><br/>
|
|
||||||
</form>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
?>
|
|
||||||
<form method="POST" id="post_form">
|
|
||||||
Username: <input name="u2f_username" id="u2f_username"/><br/><hr>
|
|
||||||
Action: <br />
|
|
||||||
<input value="register" name="action" type="radio"/> Register<br/>
|
|
||||||
<input value="authenticate" name="action" type="radio"/> Authenticate<br/>
|
|
||||||
<button type="submit">Submit!</button>
|
|
||||||
</form>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -55,6 +55,18 @@ services:
|
||||||
aliases:
|
aliases:
|
||||||
- redis
|
- redis
|
||||||
|
|
||||||
|
clamd-mailcow:
|
||||||
|
image: mailcow/clamd
|
||||||
|
build: ./data/Dockerfiles/clamav
|
||||||
|
restart: always
|
||||||
|
dns:
|
||||||
|
- 172.22.1.254
|
||||||
|
dns_search: mailcow-network
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- clamd
|
||||||
|
|
||||||
rspamd-mailcow:
|
rspamd-mailcow:
|
||||||
image: mailcow/rspamd
|
image: mailcow/rspamd
|
||||||
build: ./data/Dockerfiles/rspamd
|
build: ./data/Dockerfiles/rspamd
|
||||||
|
|
|
@ -17,9 +17,9 @@ This is just an example of how to obtain certificates with certbot. There are se
|
||||||
wget https://dl.eff.org/certbot-auto -O /usr/local/sbin/certbot && chmod +x /usr/local/sbin/certbot
|
wget https://dl.eff.org/certbot-auto -O /usr/local/sbin/certbot && chmod +x /usr/local/sbin/certbot
|
||||||
```
|
```
|
||||||
|
|
||||||
2\. Make sure you set `HTTP_BIND=0.0.0.0` and `HTTP_PORT=80` in `mailcow.conf` or setup a reverse proxy to enable connections to port 80. If you changed HTTP_BIND, then restart Nginx:
|
2\. Make sure you set `HTTP_BIND=0.0.0.0` and `HTTP_PORT=80` in `mailcow.conf` or setup a reverse proxy to enable connections to port 80. If you changed HTTP_BIND, then rebuild Nginx:
|
||||||
``` bash
|
``` bash
|
||||||
docker-compose restart nginx-mailcow
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
3\. Request the certificate with the webroot method:
|
3\. Request the certificate with the webroot method:
|
||||||
|
@ -36,6 +36,8 @@ certbot certonly \
|
||||||
--agree-tos
|
--agree-tos
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Remember to replace the example.org domain with your own domain, this command will not work if you dont.**
|
||||||
|
|
||||||
4\. Create hard links to the full path of the new certificates. Assuming you are still in the mailcow root folder:
|
4\. Create hard links to the full path of the new certificates. Assuming you are still in the mailcow root folder:
|
||||||
``` bash
|
``` bash
|
||||||
mv data/assets/ssl/cert.{pem,pem.backup}
|
mv data/assets/ssl/cert.{pem,pem.backup}
|
||||||
|
@ -158,6 +160,99 @@ docker-compose exec postfix-mailcow chmod 660 /opt/postfix/conf/smarthost_passwd
|
||||||
docker-compose exec postfix-mailcow postfix reload
|
docker-compose exec postfix-mailcow postfix reload
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Helper script
|
||||||
|
|
||||||
|
There is a helper script `mailcow-setup-relayhost.sh` you can run to setup a relayhost.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
Setup a relayhost:
|
||||||
|
./mailcow-setup-relayhost.sh relayhost port (username) (password)
|
||||||
|
Username and password are optional parameters.
|
||||||
|
|
||||||
|
Reset to defaults:
|
||||||
|
./mailcow-setup-relayhost.sh reset
|
||||||
|
```
|
||||||
|
|
||||||
|
## Optional: Log to Syslog
|
||||||
|
|
||||||
|
Enable Rsyslog to receive logs on 524/tcp:
|
||||||
|
|
||||||
|
```
|
||||||
|
# This setting depends on your Rsyslog version and configuration format.
|
||||||
|
# For most Debian derivates it will work like this...
|
||||||
|
$ModLoad imtcp
|
||||||
|
$TCPServerAddress 127.0.0.1
|
||||||
|
$InputTCPServerRun 524
|
||||||
|
|
||||||
|
# ...while for Ubuntu 16.04 it looks like this:
|
||||||
|
module(load="imtcp")
|
||||||
|
input(type="imtcp" address="127.0.0.1" port="524")
|
||||||
|
|
||||||
|
# No matter your Rsyslog version, you should set this option to off
|
||||||
|
# if you plan to use Fail2ban
|
||||||
|
$RepeatedMsgReduction off
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart rsyslog after enabling the TCP listener.
|
||||||
|
|
||||||
|
Now setup Docker daemon to start with the syslog driver.
|
||||||
|
This enables the syslog driver for all containers!
|
||||||
|
|
||||||
|
Debian users can change the startup configuration in `/etc/default/docker` while CentOS users find it in `/etc/sysconfig/docker`:
|
||||||
|
```
|
||||||
|
...
|
||||||
|
DOCKER_OPTS="--log-driver=syslog --log-opt syslog-address=tcp://127.0.0.1:524"
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Caution:** For some reason Ubuntu 16.04 and some, but not all, systemd based distros do not read the defaults file parameters.
|
||||||
|
|
||||||
|
Just run `systemctl edit docker.service` and add the following content to fix it.
|
||||||
|
|
||||||
|
**Note:** If "systemctl edit" is not available, just copy the content to `/etc/systemd/system/docker.service.d/override.conf`.
|
||||||
|
|
||||||
|
The first empty ExecStart parameter is not a mistake.
|
||||||
|
|
||||||
|
```
|
||||||
|
[Service]
|
||||||
|
EnvironmentFile=/etc/default/docker
|
||||||
|
ExecStart=
|
||||||
|
ExecStart=/usr/bin/docker daemon -H fd:// $DOCKER_OPTS
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart the Docker daemon and run `docker-compose down && docker-compose up -d` to recreate the containers.
|
||||||
|
|
||||||
|
### Use Fail2ban
|
||||||
|
|
||||||
|
**This is a subsection of "Log to Syslog", which is required for Fail2ban to work.**
|
||||||
|
|
||||||
|
Open `/etc/fail2ban/filter.d/common.conf` and search for the prefix_line parameter, change it to ".*":
|
||||||
|
|
||||||
|
```
|
||||||
|
__prefix_line = .*
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `/etc/fail2ban/jail.d/dovecot.conf`...
|
||||||
|
```
|
||||||
|
[dovecot]
|
||||||
|
enabled = true
|
||||||
|
filter = dovecot
|
||||||
|
logpath = /var/log/syslog
|
||||||
|
chain = FORWARD
|
||||||
|
```
|
||||||
|
|
||||||
|
and `jail.d/postfix-sasl.conf`:
|
||||||
|
```
|
||||||
|
[postfix-sasl]
|
||||||
|
enabled = true
|
||||||
|
filter = postfix-sasl
|
||||||
|
logpath = /var/log/syslog
|
||||||
|
chain = FORWARD
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart Fail2ban.
|
||||||
|
|
||||||
## Install a local MTA
|
## Install a local MTA
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# mailcow: dockerized - 🐮 + 🐋 = 💕
|
# mailcow: dockerized - 🐮 + 🐋 = 💕
|
||||||
|
|
||||||
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=JWBSYHF4SMC68)
|
[![Servercow](https://www.servercow.de/img/cow_globe_200.svg)](https://www.servercow.de)
|
||||||
|
|
||||||
|
If you want to support mailcow, consider hosting mailcow on a Servercow virtual machine @ Servercow!
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
|
@ -8,9 +10,11 @@ You can find screenshots [on Imgur](http://imgur.com/a/oewYt).
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
mailcow dockerized comes with **11 containers** linked in **one bridged network**.
|
mailcow dockerized comes with **12 containers** linked in **one bridged network**.
|
||||||
|
Each container represents a single application.
|
||||||
|
|
||||||
- Dovecot
|
- Dovecot
|
||||||
|
- ClamAV
|
||||||
- Memcached
|
- Memcached
|
||||||
- Redis
|
- Redis
|
||||||
- MySQL
|
- MySQL
|
||||||
|
@ -22,7 +26,7 @@ mailcow dockerized comes with **11 containers** linked in **one bridged network*
|
||||||
- Rspamd
|
- Rspamd
|
||||||
- SOGo
|
- SOGo
|
||||||
|
|
||||||
**6 volumes** to keep dynamic data - take care of them!
|
**7 volumes** to keep dynamic data - take care of them!
|
||||||
|
|
||||||
- vmail-vol-1
|
- vmail-vol-1
|
||||||
- dkim-vol-1
|
- dkim-vol-1
|
||||||
|
@ -30,6 +34,7 @@ mailcow dockerized comes with **11 containers** linked in **one bridged network*
|
||||||
- mysql-vol-1
|
- mysql-vol-1
|
||||||
- rspamd-vol-1
|
- rspamd-vol-1
|
||||||
- postfix-vol-1
|
- postfix-vol-1
|
||||||
|
- crypt-vol-1
|
||||||
|
|
||||||
The integrated **mailcow UI** allows administrative work on your mail server instance as well as separated domain administrator and mailbox user access:
|
The integrated **mailcow UI** allows administrative work on your mail server instance as well as separated domain administrator and mailbox user access:
|
||||||
|
|
||||||
|
@ -43,6 +48,6 @@ The integrated **mailcow UI** allows administrative work on your mail server ins
|
||||||
- imapsync to migrate or pull remote mailboxes regularly
|
- imapsync to migrate or pull remote mailboxes regularly
|
||||||
- TFA: Yubi OTP and U2F USB (Google Chrome and derivates only)
|
- TFA: Yubi OTP and U2F USB (Google Chrome and derivates only)
|
||||||
- Add domains, mailboxes, aliases, domain aliases and SOGo resources
|
- Add domains, mailboxes, aliases, domain aliases and SOGo resources
|
||||||
|
- Add whitelisted hosts to forward mail to mailcow
|
||||||
|
|
||||||
*[Looking for a farm to host your cow?](https://www.servercow.de)*
|
*[Looking for a farm to host your cow?](https://www.servercow.de)*
|
||||||
|
|
|
@ -75,7 +75,7 @@ Beware that a mailbox user can login to mailcow and override a domain policy fil
|
||||||
Make your changes in `data/Dockerfiles/$service` and build the image locally:
|
Make your changes in `data/Dockerfiles/$service` and build the image locally:
|
||||||
|
|
||||||
```
|
```
|
||||||
docker build data/Dockerfiles/service -t andryyy/mailcow-dockerized:$service
|
docker build data/Dockerfiles/service -t mailcow/$service
|
||||||
```
|
```
|
||||||
|
|
||||||
Now auto-recreate modified containers:
|
Now auto-recreate modified containers:
|
||||||
|
@ -311,14 +311,11 @@ Running `docker-compose down -v` will **destroy all mailcow: dockerized volumes*
|
||||||
## Reset admin password
|
## Reset admin password
|
||||||
Reset mailcow admin to `admin:moohoo`:
|
Reset mailcow admin to `admin:moohoo`:
|
||||||
|
|
||||||
1\. Drop admin table
|
|
||||||
```
|
```
|
||||||
source mailcow.conf
|
cd mailcow_path
|
||||||
docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DROP TABLE admin;"
|
bash reset_admin.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
2\. Open mailcow UI to auto-init the db
|
|
||||||
|
|
||||||
## Rspamd
|
## Rspamd
|
||||||
|
|
||||||
### Learn spam and ham
|
### Learn spam and ham
|
||||||
|
@ -521,6 +518,14 @@ map $http_upgrade $connection_upgrade {
|
||||||
|
|
||||||
Now you can simply navigate to https://${MAILCOW_HOSTNAME}/portainer/ to view your Portainer container monitoring page. You’ll then be prompted to specify a new password for the **admin** account. After specifying your password, you’ll then be able to connect to the Portainer UI.
|
Now you can simply navigate to https://${MAILCOW_HOSTNAME}/portainer/ to view your Portainer container monitoring page. You’ll then be prompted to specify a new password for the **admin** account. After specifying your password, you’ll then be able to connect to the Portainer UI.
|
||||||
|
|
||||||
|
## Change autodiscover setup type
|
||||||
|
|
||||||
|
This disables ActiveSync in the autodiscover service for Outlook and configures it with IMAP and SMTP instead:
|
||||||
|
|
||||||
|
Open `data/web/autodiscover.php` and set `'useEASforOutlook' => 'yes'` to `'useEASforOutlook' => 'no'`.
|
||||||
|
|
||||||
|
To always use IMAP and SMTP instead of EAS, set `'autodiscoverType' => 'imap'`.
|
||||||
|
|
||||||
## Why Bind?
|
## Why Bind?
|
||||||
|
|
||||||
For DNS blacklist lookups and DNSSEC.
|
For DNS blacklist lookups and DNSSEC.
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
#/bin/bash
|
||||||
|
if [[ ! -f mailcow.conf ]]; then
|
||||||
|
echo "Cannot find mailcow.conf, make sure this script is run from within the mailcow folder."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "Checking MySQL service... "
|
||||||
|
docker-compose ps -q mysql-mailcow > /dev/null 2>&1
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "failed"
|
||||||
|
echo "MySQL (mysql-mailcow) is not up and running, exiting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "OK"
|
||||||
|
read -r -p "Are you sure you want to reset the mailcow administrator account? [y/N] " response
|
||||||
|
response=${response,,} # tolower
|
||||||
|
if [[ "$response" =~ ^(yes|y)$ ]]; then
|
||||||
|
echo -e "\nWorking, please wait..."
|
||||||
|
source mailcow.conf
|
||||||
|
docker-compose exec -T mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM admin;"
|
||||||
|
docker-compose exec -T mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "INSERT INTO admin (username, password, superadmin, created, modified, active) VALUES ('admin', '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1);"
|
||||||
|
docker-compose exec -T mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM domain_admins WHERE username='admin';"
|
||||||
|
docker-compose exec -T mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "INSERT INTO domain_admins (username, domain, created, active) VALUES ('admin', 'ALL', NOW(), 1);"
|
||||||
|
docker-compose exec -T mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM tfa WHERE username='admin';"
|
||||||
|
echo "
|
||||||
|
Reset credentials:
|
||||||
|
---
|
||||||
|
Username: admin
|
||||||
|
Password: moohoo
|
||||||
|
TFA: none
|
||||||
|
"
|
||||||
|
else
|
||||||
|
echo "Operation canceled."
|
||||||
|
fi
|
|
@ -0,0 +1,76 @@
|
||||||
|
#/bin/bash
|
||||||
|
if [[ ! -f mailcow.conf ]]; then
|
||||||
|
echo "Cannot find mailcow.conf, make sure this script is run from within the mailcow folder."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "Checking Postfix service... "
|
||||||
|
docker-compose ps -q postfix-mailcow > /dev/null 2>&1
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "failed"
|
||||||
|
echo "Postfix (postifx-mailcow) is not up and running, exiting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "OK"
|
||||||
|
|
||||||
|
if [[ -z ${1} ]]; then
|
||||||
|
echo "Usage:"
|
||||||
|
echo
|
||||||
|
echo "Setup a relayhost:"
|
||||||
|
echo "${0} relayhost port (username) (password)"
|
||||||
|
echo "Username and password are optional parameters."
|
||||||
|
echo
|
||||||
|
echo "Reset to defaults:"
|
||||||
|
echo "${0} reset"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${1} == "reset" ]]; then
|
||||||
|
# Reset modified values to their defaults
|
||||||
|
sed -i "s/^relayhost\ \=.*/relayhost\ \=/" data/conf/postfix/main.cf
|
||||||
|
sed -i "s/^smtp\_sasl\_password\_maps.*/smtp\_sasl\_password\_maps\ \=/" data/conf/postfix/main.cf
|
||||||
|
sed -i "s/^smtp\_sasl\_security\_options.*/smtp\_sasl\_security\_options\ \=\ noplaintext\,\ noanonymous/" data/conf/postfix/main.cf
|
||||||
|
sed -i "s/^smtp\_sasl\_auth\_enable.*/smtp\_sasl\_auth\_enable\ \=\ no/" data/conf/postfix/main.cf
|
||||||
|
# Also delete the plaintext password file
|
||||||
|
rm -f data/conf/postfix/smarthost_passwd*
|
||||||
|
docker-compose exec postfix-mailcow postfix reload
|
||||||
|
# Exit with dc exit code
|
||||||
|
exit $?
|
||||||
|
else
|
||||||
|
# Try a simple connection to host:port but don't recieve any data
|
||||||
|
# Abort after 3 seconds
|
||||||
|
if ! nc -z -v -w3 ${1} ${2} 2>/dev/null; then
|
||||||
|
echo "Connection to relayhost ${1} failed, aborting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# Use exact hostname as relayhost, don't lookup the MX record of relayhost
|
||||||
|
sed -i "s/relayhost\ \=.*/relayhost\ \=\ \[${1}\]\:${2}/" data/conf/postfix/main.cf
|
||||||
|
if grep -q "smtp_sasl_password_maps" data/conf/postfix/main.cf
|
||||||
|
then
|
||||||
|
sed -i "s/^smtp\_sasl\_password\_maps.*/smtp\_sasl\_password\_maps\ \=\ hash\:\/opt\/postfix\/conf\/smarthost\_passwd/" data/conf/postfix/main.cf
|
||||||
|
else
|
||||||
|
echo "smtp_sasl_password_maps = hash:/opt/postfix/conf/smarthost_passwd" >> data/conf/postfix/main.cf
|
||||||
|
fi
|
||||||
|
if grep -q "smtp_sasl_auth_enable" data/conf/postfix/main.cf
|
||||||
|
then
|
||||||
|
sed -i "s/^smtp\_sasl\_auth\_enable.*/smtp\_sasl\_auth\_enable\ \=\ yes/" data/conf/postfix/main.cf
|
||||||
|
else
|
||||||
|
echo "smtp_sasl_auth_enable = yes" >> data/conf/postfix/main.cf
|
||||||
|
fi
|
||||||
|
if grep -q "smtp_sasl_security_options" data/conf/postfix/main.cf
|
||||||
|
then
|
||||||
|
sed -i "s/^smtp\_sasl\_security\_options.*/smtp\_sasl\_security\_options\ \=/" data/conf/postfix/main.cf
|
||||||
|
else
|
||||||
|
echo "smtp_sasl_security_options =" >> data/conf/postfix/main.cf
|
||||||
|
fi
|
||||||
|
if [[ ! -z ${3} ]]; then
|
||||||
|
echo ${1} ${3}:${4} > data/conf/postfix/smarthost_passwd
|
||||||
|
docker-compose exec postfix-mailcow postmap /opt/postfix/conf/smarthost_passwd
|
||||||
|
fi
|
||||||
|
docker-compose exec postfix-mailcow chown root:postfix /opt/postfix/conf/smarthost_passwd /opt/postfix/conf/smarthost_passwd.db
|
||||||
|
docker-compose exec postfix-mailcow chmod 660 /opt/postfix/conf/smarthost_passwd /opt/postfix/conf/smarthost_passwd.db
|
||||||
|
docker-compose exec postfix-mailcow postfix reload
|
||||||
|
exit $?
|
||||||
|
fi
|
Loading…
Reference in New Issue