initial commit
This commit is contained in:
commit
bef09f6e33
19
LICENSE
Normal file
19
LICENSE
Normal file
|
@ -0,0 +1,19 @@
|
|||
MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
92
bin/roundcubemail-settings-export.php
Executable file
92
bin/roundcubemail-settings-export.php
Executable file
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
$virtualhost = $argv[1];
|
||||
|
||||
if ($virtualhost == "") {
|
||||
echo "usage:\n";
|
||||
echo " $argv[0] virtualhost\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!is_dir("/var/www/$virtualhost")) {
|
||||
echo "$virtualhost is not installed\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
$roundcubemail = array();
|
||||
|
||||
$dbPass = trim(`grep -m 1 password /etc/mysql/debian.cnf |cut -d = -f 2|cut -d ' ' -f 2`);
|
||||
$dbLink = mysqli_connect('localhost', 'root', "$dbPass", 'vmail');
|
||||
|
||||
|
||||
$dbQuery = "SELECT * FROM rc_users WHERE username LIKE '%@$virtualhost'";
|
||||
$dbResult = mysqli_query($dbLink, $dbQuery);
|
||||
while ($row_users = mysqli_fetch_assoc($dbResult)) {
|
||||
|
||||
$user_id=$row_users['user_id'];
|
||||
unset($row_users['user_id']);
|
||||
foreach($row_users as $kusers=>$vusers) {
|
||||
if (is_null($vusers)) {
|
||||
$vusers = 'NULL';
|
||||
}
|
||||
$roundcubemail["$virtualhost"]["users"][$user_id][$kusers] = $vusers;
|
||||
}
|
||||
|
||||
/* identities */
|
||||
$dbQuery_identities = "SELECT * FROM `rc_identities` WHERE `user_id` = '$user_id'";
|
||||
$dbResult_identities = mysqli_query($dbLink, $dbQuery_identities);
|
||||
while ($row_identities = mysqli_fetch_assoc($dbResult_identities)) {
|
||||
|
||||
$identity_id=$row_identities['identity_id'];
|
||||
unset($row_identities['identity_id']);
|
||||
foreach($row_identities as $kidentities=>$videntities) {
|
||||
if (is_null($videntities)) {
|
||||
$videntities = 'NULL';
|
||||
}
|
||||
$roundcubemail["$virtualhost"]["users"][$user_id]['identities'][$identity_id][$kidentities] = $videntities;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* contacts */
|
||||
$dbQuery_contacts = "SELECT * FROM `rc_contacts` WHERE `user_id` = '$user_id'";
|
||||
$dbResult_contacts = mysqli_query($dbLink, $dbQuery_contacts);
|
||||
while ($row_contacts = mysqli_fetch_assoc($dbResult_contacts)) {
|
||||
|
||||
$contact_id=$row_contacts['contact_id'];
|
||||
unset($row_contacts['contact_id']);
|
||||
foreach($row_contacts as $kcontacts=>$vcontacts) {
|
||||
if (is_null($vcontacts)) {
|
||||
$vcontacts = 'NULL';
|
||||
}
|
||||
$roundcubemail["$virtualhost"]["users"][$user_id]['contacts'][$contact_id][$kcontacts] = $vcontacts;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* contactgroups */
|
||||
$dbQuery_contactgroups = "SELECT * FROM `rc_contactgroups` WHERE `user_id` = '$user_id'";
|
||||
$dbResult_contactgroups = mysqli_query($dbLink, $dbQuery_contactgroups);
|
||||
while ($row_contactgroups = mysqli_fetch_assoc($dbResult_contactgroups)) {
|
||||
|
||||
$contactgroup_id=$row_contactgroups['contactgroup_id'];
|
||||
unset($row_contactgroups['contactgroup_id']);
|
||||
foreach($row_contactgroups as $kcontactgroups=>$vcontactgroups) {
|
||||
if (is_null($vcontactgroups)) {
|
||||
$vcontactgroups = 'NULL';
|
||||
}
|
||||
$roundcubemail["$virtualhost"]["users"][$user_id]['contactgroups'][$contactgroup_id][$kcontactgroups] = $vcontactgroups;
|
||||
}
|
||||
|
||||
/* contactgroupmembers */
|
||||
$dbQuery_contactgroupmembers = "SELECT * FROM `rc_contactgroupmembers` WHERE `contactgroup_id` = '$contactgroup_id'";
|
||||
$dbResult_contactgroupmembers = mysqli_query($dbLink, $dbQuery_contactgroupmembers);
|
||||
while ($row_contactgroupmembers = mysqli_fetch_assoc($dbResult_contactgroupmembers)) {
|
||||
$roundcubemail["$virtualhost"]["users"][$user_id]['contactgroups'][$contactgroup_id]['contactgroupmembers'][] = $row_contactgroupmembers;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
file_put_contents("/var/www/$virtualhost/roundcubemail", serialize($roundcubemail));
|
160
bin/roundcubemail-settings-import.php
Executable file
160
bin/roundcubemail-settings-import.php
Executable file
|
@ -0,0 +1,160 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
$virtualhost = $argv[1];
|
||||
|
||||
if ($virtualhost == "") {
|
||||
echo "usage:\n";
|
||||
echo " $argv[0] virtualhost\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!is_file("/var/www/$virtualhost/roundcubemail")) {
|
||||
echo "$virtualhost roundcubemail file does not exist\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
$roundcubemail = unserialize(file_get_contents("/var/www/$virtualhost/roundcubemail"));
|
||||
|
||||
$dbPass = trim(`grep -m 1 password /etc/mysql/debian.cnf |cut -d = -f 2|cut -d ' ' -f 2`);
|
||||
$dbLink = mysqli_connect('localhost', 'root', "$dbPass", 'vmail');
|
||||
|
||||
$user_id_new = 0;
|
||||
$identity_id_new = 0;
|
||||
$contact_id_new = 0;
|
||||
$contactgroup_id_new = 0;
|
||||
$contact_id_array_map = array();
|
||||
|
||||
foreach ($roundcubemail as $virtualhost=>$users_array) {
|
||||
foreach ($users_array['users'] as $user_id => $user_array) {
|
||||
$username = $user_array['username'];
|
||||
$dbQuery = "SELECT user_id FROM rc_users WHERE username LIKE '$username'";
|
||||
$dbResult = mysqli_query($dbLink, $dbQuery);
|
||||
$dbAffectedRows = mysqli_affected_rows($dbLink);
|
||||
|
||||
if ($dbAffectedRows == 0) {
|
||||
echo "adding $username\n";
|
||||
|
||||
$dbQuery = "INSERT INTO rc_users SET";
|
||||
foreach ($user_array as $kusers=>$vusers) {
|
||||
if (!is_array($vusers)) {
|
||||
if ($vusers == 'NULL') {
|
||||
$dbQuery .= " `$kusers` = $vusers,";
|
||||
} else {
|
||||
$vusers = mysqli_escape_string($dbLink, $vusers);
|
||||
$dbQuery .= " `$kusers` = '$vusers',";
|
||||
}
|
||||
}
|
||||
}
|
||||
$dbQuery = rtrim($dbQuery, ",");
|
||||
$dbResult = mysqli_query($dbLink, $dbQuery);
|
||||
$dbAffectedRows = mysqli_affected_rows($dbLink);
|
||||
if ($dbAffectedRows != '1') {
|
||||
echo "ERROR: $dbResult = $dbAffectedRows\n";
|
||||
}
|
||||
$user_id_new = mysqli_insert_id($dbLink);
|
||||
|
||||
/* identities */
|
||||
if (!empty($users_array['users'][$user_id]['identities'])) {
|
||||
foreach ($users_array['users'][$user_id]['identities'] as $identity_id => $identity_array) {
|
||||
$identity_array['user_id'] = $user_id_new;
|
||||
$dbQuery = "INSERT INTO rc_identities SET";
|
||||
foreach ($identity_array as $kidentities=>$videntities) {
|
||||
if (!is_array($videntities)) {
|
||||
if ($videntities == 'NULL') {
|
||||
$dbQuery .= " `$kidentities` = $videntities,";
|
||||
} else {
|
||||
$videntities = mysqli_escape_string($dbLink, $videntities);
|
||||
$dbQuery .= " `$kidentities` = '$videntities',";
|
||||
}
|
||||
}
|
||||
}
|
||||
$dbQuery = rtrim($dbQuery, ",");
|
||||
$dbResult = mysqli_query($dbLink, $dbQuery);
|
||||
$dbAffectedRows = mysqli_affected_rows($dbLink);
|
||||
if ($dbAffectedRows != '1') {
|
||||
echo "ERROR: $dbResult = $dbAffectedRows\n";
|
||||
}
|
||||
$identity_id_new = mysqli_insert_id($dbLink);
|
||||
}
|
||||
}
|
||||
|
||||
/* contacts */
|
||||
if (!empty($users_array['users'][$user_id]['contacts'])) {
|
||||
foreach ($users_array['users'][$user_id]['contacts'] as $contacts_id => $contacts_array) {
|
||||
$contacts_array['user_id'] = $user_id_new;
|
||||
$dbQuery = "INSERT INTO rc_contacts SET";
|
||||
foreach ($contacts_array as $kcontacts=>$vcontacts) {
|
||||
if (!is_array($vcontacts)) {
|
||||
if ($vcontacts == 'NULL') {
|
||||
$dbQuery .= " `$kidentities` = $vcontacts,";
|
||||
} else {
|
||||
$vcontacts = mysqli_escape_string($dbLink, $vcontacts);
|
||||
$dbQuery .= " `$kcontacts` = '$vcontacts',";
|
||||
}
|
||||
}
|
||||
}
|
||||
$dbQuery = rtrim($dbQuery, ",");
|
||||
$dbResult = mysqli_query($dbLink, $dbQuery);
|
||||
$dbAffectedRows = mysqli_affected_rows($dbLink);
|
||||
if ($dbAffectedRows != '1') {
|
||||
echo "ERROR: $dbResult = $dbAffectedRows\n";
|
||||
}
|
||||
$contact_id_new = mysqli_insert_id($dbLink);
|
||||
$contact_id_array_map[$contacts_id] = $contact_id_new;
|
||||
}
|
||||
}
|
||||
|
||||
/* contactgroups */
|
||||
if (!empty($users_array['users'][$user_id]['contactgroups'])) {
|
||||
foreach ($users_array['users'][$user_id]['contactgroups'] as $contactgroups_id => $contactgroups_array) {
|
||||
$contactgroups_array['user_id'] = $user_id_new;
|
||||
$dbQuery = "INSERT INTO rc_contactgroups SET";
|
||||
foreach ($contactgroups_array as $kcontactgroups=>$vcontactgroups) {
|
||||
if (!is_array($vcontactgroups)) {
|
||||
if ($vcontactgroups == 'NULL') {
|
||||
$dbQuery .= " `$kidentities` = $vcontactgroups,";
|
||||
} else {
|
||||
$vcontactgroups = mysqli_escape_string($dbLink, $vcontactgroups);
|
||||
$dbQuery .= " `$kcontactgroups` = \"$vcontactgroups\",";
|
||||
}
|
||||
}
|
||||
}
|
||||
$dbQuery = rtrim($dbQuery, ",");
|
||||
$dbResult = mysqli_query($dbLink, $dbQuery);
|
||||
$dbAffectedRows = mysqli_affected_rows($dbLink);
|
||||
if ($dbAffectedRows != '1') {
|
||||
echo "ERROR: $dbResult = $dbAffectedRows\n";
|
||||
}
|
||||
$contactgoup_id_new = mysqli_insert_id($dbLink);
|
||||
|
||||
/* contactgroupmembers */
|
||||
if (!empty($users_array['users'][$user_id]['contactgroups'][$contactgroups_id]['contactgroupmembers'])) {
|
||||
foreach ($users_array['users'][$user_id]['contactgroups'][$contactgroups_id]['contactgroupmembers'] as $contactgroupmembers_id => $contactgroupmembers_array) {
|
||||
$contactgroupmembers_array['contactgroup_id'] = $contactgoup_id_new;
|
||||
$contactgroupmembers_array['contact_id'] = $contact_id_array_map[$contactgroupmembers_array['contact_id']];
|
||||
$dbQuery = "INSERT INTO rc_contactgroupmembers SET";
|
||||
foreach ($contactgroupmembers_array as $kcontactgroupmembers=>$vcontactgroupmembers) {
|
||||
if (!is_array($vcontactgroupmembers)) {
|
||||
$vcontactgroupmembers = mysqli_escape_string($dbLink, $vcontactgroupmembers);
|
||||
$dbQuery .= " `$kcontactgroupmembers` = \"$vcontactgroupmembers\",";
|
||||
}
|
||||
}
|
||||
$dbQuery = rtrim($dbQuery, ",");
|
||||
$dbResult = mysqli_query($dbLink, $dbQuery);
|
||||
$dbAffectedRows = mysqli_affected_rows($dbLink);
|
||||
if ($dbAffectedRows != '1') {
|
||||
echo "ERROR: $dbResult = $dbAffectedRows\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
echo "$username already exists, skipping\n";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
106
bin/vmail-aliases-add.sh
Executable file
106
bin/vmail-aliases-add.sh
Executable file
|
@ -0,0 +1,106 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
help()
|
||||
{
|
||||
thisfilename=$(basename -- "$0")
|
||||
echo "$thisfilename"
|
||||
echo "Add email alias to vmail system"
|
||||
echo ""
|
||||
echo "usage: $thisfilename email alias [OPTIONS]"
|
||||
echo ""
|
||||
echo " -h Print this help."
|
||||
echo ""
|
||||
echo " 'email' should be the full address 'alias' just the local part (username)."
|
||||
echo " .e.g to have info@example.com delivered (aliased) to joe@example.com do:"
|
||||
echo " $thisfilename joe@example.com info"
|
||||
exit
|
||||
}
|
||||
|
||||
# set any options that were passed
|
||||
while getopts "h" opt; do
|
||||
case "${opt}" in
|
||||
h )
|
||||
help
|
||||
exit;;
|
||||
\? )
|
||||
echo "Invalid option: $OPTARG" 1>&2
|
||||
exit;;
|
||||
: )
|
||||
echo "Invalid option: $OPTARG requires an argument" 1>&2
|
||||
exit;;
|
||||
esac
|
||||
done
|
||||
|
||||
# check for and set alias & email address & split in to local part & domain
|
||||
if [ -n "$2" ]; then
|
||||
if [ $1 == "-h" ] || [ $2 == "-h" ]; then
|
||||
help
|
||||
else
|
||||
email=$1
|
||||
shift
|
||||
alias=$1
|
||||
shift
|
||||
if [[ $email =~ "@" ]] ; then
|
||||
mbox=${email%@*}
|
||||
domain=${email##*@}
|
||||
if [ -z $mbox ] ; then
|
||||
echo "ERROR: No local part in $email."
|
||||
exit
|
||||
elif [ -z $domain ] ; then
|
||||
echo "ERROR: No domain in $email."
|
||||
exit
|
||||
elif [[ ! $domain =~ ^(([a-zA-Z](-?[a-zA-Z0-9])*)\.)+[a-zA-Z]{2,}$ ]] ; then
|
||||
echo "ERROR: $domain is not a valid domain name."
|
||||
exit
|
||||
fi
|
||||
else
|
||||
echo "ERROR: $email is not a valid email."
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
else
|
||||
help
|
||||
fi
|
||||
|
||||
# get domain_id (and thus check if domain already exists)
|
||||
domain_id=`mysql --defaults-extra-file=/usr/local/etc/vmail.conf -s -r -N -e "SELECT id from vm_domains WHERE domain='$domain';"`
|
||||
if [ -z $domain_id ] ; then
|
||||
echo "ERROR: Domain $domain does not exist."
|
||||
exit
|
||||
fi
|
||||
|
||||
# get mbox id, which also verfies that email address exists
|
||||
mbox_id=`mysql --defaults-extra-file=/usr/local/etc/vmail.conf -s -r -N -e "SELECT id FROM vm_mboxes WHERE domain_id='$domain_id' AND mbox='$mbox';"`
|
||||
# rowcount=`mysql --defaults-extra-file=/usr/local/etc/vmail.conf -s -r -N -e "SELECT COUNT(*) FROM vm_mboxes WHERE domain_id='$domain_id' AND mbox='$mbox';"`
|
||||
if [ -z $mbox_id ] ; then
|
||||
# mbox does not exist, can't create alias
|
||||
echo "ERROR: Address to Alias To ($email) does not exist."
|
||||
exit
|
||||
elif [ "$mbox_id" -gt '1' ] ; then
|
||||
# verified mbox, check for existing alias
|
||||
existing_alias=`mysql --defaults-extra-file=/usr/local/etc/vmail.conf -s -r -N -e "SELECT vm_mboxes.mbox FROM vm_mboxes, vm_aliases WHERE vm_aliases.alias='$alias' AND vm_aliases.mbox_id=vm_mboxes.id AND vm_mboxes.domain_id='$domain_id';"`
|
||||
if [ -z $existing_alias ]; then
|
||||
# existing alias does not exist, add new one now
|
||||
dbcmd="mysql --defaults-extra-file=/usr/local/etc/vmail.conf -e 'INSERT INTO vm_aliases SET vm_aliases.alias=\"$alias\", vm_aliases.mbox_id=\"$mbox_id\";'"
|
||||
echo $dbcmd
|
||||
else
|
||||
if [ "$existing_alias" == "$mbox" ]; then
|
||||
echo "ERROR: Alias for $alias To $email already exists."
|
||||
exit
|
||||
else
|
||||
echo "ERROR: Alias for $alias already points to another address ($existing_alias@$domain). To update delete that alias first, then add a new one."
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# db query error
|
||||
echo "ERROR: System error querying vmail database."
|
||||
exit 1
|
||||
fi
|
92
bin/vmail-aliases-del.sh
Executable file
92
bin/vmail-aliases-del.sh
Executable file
|
@ -0,0 +1,92 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
help()
|
||||
{
|
||||
thisfilename=$(basename -- "$0")
|
||||
echo "$thisfilename"
|
||||
echo "Delete email alias from vmail database."
|
||||
echo ""
|
||||
echo "usage: $thisfilename alias"
|
||||
echo ""
|
||||
echo " -h Print this help."
|
||||
echo ""
|
||||
echo " Enter alias in full email address format."
|
||||
exit
|
||||
}
|
||||
|
||||
dbcmd="mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE"
|
||||
dbcmdopts="-e"
|
||||
dbquery="SELECT vm_aliases.alias, vm_mboxes.mbox, vm_domains.domain FROM vm_aliases, vm_mboxes, vm_domains WHERE vm_aliases.mbox_id = vm_mboxes.id AND vm_mboxes.domain_id = vm_domains.id"
|
||||
|
||||
# check for and set alias search term(s)
|
||||
if [ -n "$1" ]; then
|
||||
if [ $1 == "-h" ]; then
|
||||
help
|
||||
elif [[ ! $1 =~ ^- ]] ; then
|
||||
searchterm=$1
|
||||
shift
|
||||
if [[ $searchterm =~ "@" ]] ; then
|
||||
alias=${searchterm%@*}
|
||||
domain=${searchterm##*@}
|
||||
if ! vmail::validate_domain $domain; then
|
||||
echo "ERROR: $searchterm is not a valid email address."
|
||||
exit
|
||||
fi
|
||||
elif vmail::validate_domain $searchterm; then
|
||||
domain=$searchterm
|
||||
else
|
||||
echo "ERROR: $searchterm is not a valid search term."
|
||||
help
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# set any options that were passed
|
||||
while getopts "achs" opt; do
|
||||
case "${opt}" in
|
||||
a )
|
||||
aliassearch=true
|
||||
;;
|
||||
c )
|
||||
cvs="| sed 's/\t/,/g'"
|
||||
;;
|
||||
h )
|
||||
help
|
||||
exit;;
|
||||
s )
|
||||
dbcmdopts="-s -N $dbcmdopts"
|
||||
;;
|
||||
\? )
|
||||
echo "Invalid option: $OPTARG" 1>&2
|
||||
exit;;
|
||||
esac
|
||||
done
|
||||
|
||||
# build query
|
||||
if [ -n "$domain" ]; then
|
||||
# add specific domain
|
||||
dbquery="$dbquery AND vm_domains.domain='$domain'"
|
||||
if [ -n "$localpart" ]; then
|
||||
# search for specific alias or mbox
|
||||
if [ -n "$aliassearch" ]; then
|
||||
# search for specific alias address
|
||||
dbquery="$dbquery AND vm_aliases.alias='$localpart'"
|
||||
else
|
||||
# search for all aliases for specific email address
|
||||
dbquery="$dbquery AND vm_mboxes.mbox='$localpart'"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# set order by
|
||||
dbquery="$dbquery ORDER BY vm_domains.domain, vm_mboxes.mbox, vm_aliases.alias;";
|
||||
|
||||
# execute mysql query
|
||||
eval $dbcmd $dbcmdopts "\"$dbquery\"" $cvs
|
98
bin/vmail-aliases-get.sh
Executable file
98
bin/vmail-aliases-get.sh
Executable file
|
@ -0,0 +1,98 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
help()
|
||||
{
|
||||
thisfilename=$(basename -- "$0")
|
||||
echo "$thisfilename"
|
||||
echo "Get email alias data from vmail database."
|
||||
echo ""
|
||||
echo "usage: $thisfilename [email|alias|domain] [OPTIONS]"
|
||||
echo ""
|
||||
echo " -a Return info for specific alias."
|
||||
echo " -c Output in cvs format."
|
||||
echo " -h Print this help."
|
||||
echo " -s Be more silent - use tabs instead of tables for output, do not display column headers."
|
||||
echo ""
|
||||
echo " Search term is optional. If nothing specified all aliases for all email acccounts for all domains will be returned."
|
||||
echo " Enter email address to get all aliases that route to that email address."
|
||||
echo " Enter alias (in full email address format) with the -a option to get address that alias delivers to."
|
||||
echo " Enter domain name to get all aliases for all email addresses under that domain."
|
||||
exit
|
||||
}
|
||||
|
||||
dbcmd="mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE"
|
||||
dbcmdopts="-e"
|
||||
dbquery="SELECT vm_aliases.alias, vm_mboxes.mbox, vm_domains.domain FROM vm_aliases, vm_mboxes, vm_domains WHERE vm_aliases.mbox_id = vm_mboxes.id AND vm_mboxes.domain_id = vm_domains.id"
|
||||
|
||||
# check for and set alias search term(s)
|
||||
if [ -n "$1" ]; then
|
||||
if [ $1 == "-h" ]; then
|
||||
help
|
||||
elif [[ ! $1 =~ ^- ]] ; then
|
||||
searchterm=$1
|
||||
shift
|
||||
if [[ $searchterm =~ "@" ]] ; then
|
||||
localpart=${searchterm%@*}
|
||||
domain=${searchterm##*@}
|
||||
if ! vmail::validate_domain $domain; then
|
||||
echo "ERROR: $searchterm is not a valid email address."
|
||||
exit
|
||||
fi
|
||||
elif vmail::validate_domain $searchterm; then
|
||||
domain=$searchterm
|
||||
else
|
||||
echo "ERROR: $searchterm is not a valid search term."
|
||||
help
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# set any options that were passed
|
||||
while getopts "achs" opt; do
|
||||
case "${opt}" in
|
||||
a )
|
||||
aliassearch=true
|
||||
;;
|
||||
c )
|
||||
cvs="| sed 's/\t/,/g'"
|
||||
;;
|
||||
h )
|
||||
help
|
||||
exit;;
|
||||
s )
|
||||
dbcmdopts="-s -N $dbcmdopts"
|
||||
;;
|
||||
\? )
|
||||
echo "Invalid option: $OPTARG" 1>&2
|
||||
exit;;
|
||||
esac
|
||||
done
|
||||
|
||||
# build query
|
||||
if [ -n "$domain" ]; then
|
||||
# add specific domain
|
||||
dbquery="$dbquery AND vm_domains.domain='$domain'"
|
||||
if [ -n "$localpart" ]; then
|
||||
# search for specific alias or mbox
|
||||
if [ -n "$aliassearch" ]; then
|
||||
# search for specific alias address
|
||||
dbquery="$dbquery AND vm_aliases.alias='$localpart'"
|
||||
else
|
||||
# search for all aliases for specific email address
|
||||
dbquery="$dbquery AND vm_mboxes.mbox='$localpart'"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# set order by
|
||||
dbquery="$dbquery ORDER BY vm_domains.domain, vm_mboxes.mbox, vm_aliases.alias;";
|
||||
|
||||
# execute mysql query
|
||||
eval $dbcmd $dbcmdopts "\"$dbquery\"" $cvs
|
27
bin/vmail-deploy.sh
Executable file
27
bin/vmail-deploy.sh
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
# check for and set virtualhost
|
||||
if [ -n "$1" ]; then
|
||||
virtualhost=$1
|
||||
else
|
||||
echo "virtualhost not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
vmail.sh create domain
|
||||
dkim create
|
||||
check if stack-dns nameservers
|
||||
add dkim record
|
||||
add dmarc record
|
||||
vmail-secure.sh
|
||||
esle
|
||||
notify dkim & dmar
|
||||
|
||||
|
36
bin/vmail-dkim-add.sh
Executable file
36
bin/vmail-dkim-add.sh
Executable file
|
@ -0,0 +1,36 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
# check for and set virtualhost
|
||||
if [ -n "$1" ]; then
|
||||
virtualhost=$1
|
||||
else
|
||||
echo "virtualhost not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for existing dkim
|
||||
if [ -f /etc/ssl/dkim/$virtualhost.dkim ]; then
|
||||
echo "dkim for $virtualhost already exists"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd /etc/ssl/dkim
|
||||
date +%Y%m%d > $virtualhost.selector
|
||||
openssl genrsa -out $virtualhost.pem 2048
|
||||
openssl rsa -in $virtualhost.pem -out $virtualhost.pub -pubout
|
||||
tail -n +2 $virtualhost.pub |head -n -1|tr -d '\n' > $virtualhost.dkim
|
||||
echo `cat $virtualhost.selector`._domainkey.$virtualhost. 3600 IN TXT \""k=rsa; p=`cat $virtualhost.dkim`"\" > $virtualhost.dns
|
||||
chown Debian-exim:ssl-cert $virtualhost.*
|
||||
|
||||
echo
|
||||
echo create this dns record:
|
||||
echo
|
||||
cat $virtualhost.dns
|
||||
echo
|
29
bin/vmail-dkim-del.sh
Executable file
29
bin/vmail-dkim-del.sh
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
# check for and set virtualhost
|
||||
if [ -n "$1" ]; then
|
||||
virtualhost=$1
|
||||
else
|
||||
echo "virtualhost not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for existing dkim
|
||||
if [ ! -f /etc/ssl/dkim/$virtualhost.dkim ]; then
|
||||
echo "dkim for $virtualhost does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo delete this dkim dns record
|
||||
echo
|
||||
cat /etc/ssl/dkim/$virtualhost.dns
|
||||
echo
|
||||
|
||||
rm /etc/ssl/dkim/$virtualhost.*
|
122
bin/vmail-domains-add.sh
Executable file
122
bin/vmail-domains-add.sh
Executable file
|
@ -0,0 +1,122 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
help()
|
||||
{
|
||||
thisfilename=$(basename -- "$0")
|
||||
echo "$thisfilename"
|
||||
echo "Add domain to vmail system"
|
||||
echo ""
|
||||
echo "usage: $thisfilename domain [OPTIONS]"
|
||||
echo ""
|
||||
echo " -h Print this help."
|
||||
echo " -l LIMIT Maximum number of mailboxes for this domain."
|
||||
echo " -q QUOTA Default mailbox quota in GB."
|
||||
echo " -s STATUS 1 for enabled, 0 for disabled."
|
||||
echo ""
|
||||
echo " Defaults for are all OPTIONS are configured in database."
|
||||
echo " NULL for LIMIT or QUOTA means no limit."
|
||||
exit
|
||||
}
|
||||
|
||||
# check for and set domain
|
||||
if [ -n "$1" ]; then
|
||||
if [ $1 == "-h" ]; then
|
||||
help
|
||||
elif vmail::validate_domain $1; then
|
||||
domain=$1
|
||||
shift
|
||||
else
|
||||
echo "ERROR: Invalid domain name: $1"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
help
|
||||
fi
|
||||
|
||||
# set any options that were passed
|
||||
while getopts "hl:q:s:" opt; do
|
||||
case "${opt}" in
|
||||
h )
|
||||
help
|
||||
exit;;
|
||||
l )
|
||||
limit=${OPTARG}
|
||||
;;
|
||||
q )
|
||||
quota=${OPTARG}
|
||||
;;
|
||||
s )
|
||||
status=${OPTARG}
|
||||
;;
|
||||
\? )
|
||||
echo "Invalid option: $OPTARG" 1>&2
|
||||
exit;;
|
||||
: )
|
||||
echo "Invalid option: $OPTARG requires an argument" 1>&2
|
||||
exit;;
|
||||
esac
|
||||
done
|
||||
|
||||
# check if vmail domain dir exits
|
||||
if [ -d $VMAIL_DIR/$domain ]; then
|
||||
echo "ERROR: Directory $VMAIL_DIR/$domain already exists."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if domain exists in vmail database
|
||||
rowcount=`mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -s -r -N -e "SELECT COUNT(*) from vm_domains WHERE domain='$domain';"`
|
||||
if [ "$rowcount" -eq '0' ] ; then
|
||||
# looks good, build SQL
|
||||
cmd="mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -e \"INSERT INTO vm_domains SET domain='$domain'\""
|
||||
if [ ! -z "$status" ] ; then
|
||||
if [ "$status" == 0 ] || [ "$status" == 1 ]; then
|
||||
cmd="$cmd, status='$status'"
|
||||
else
|
||||
echo "ERROR: status (-s) must be 1 or 0"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ ! -z "$limit" ] ; then
|
||||
if [[ "$limit" == "NULL" ]]; then
|
||||
cmd="$cmd, mbox_limit=NULL"
|
||||
elif [[ "$limit" =~ ^[0-9]+$ ]]; then
|
||||
cmd="$cmd, mbox_limit='$limit'"
|
||||
else
|
||||
echo "ERROR: limit (-l) must numeric or NULL"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ ! -z "$quota" ] ; then
|
||||
if [[ "$quota" == "NULL" ]]; then
|
||||
cmd="$cmd, mbox_quota_default=NULL"
|
||||
elif [[ "$quota" =~ ^[0-9]+$ ]]; then
|
||||
cmd="$cmd, mbox_quota_default='$quota'"
|
||||
else
|
||||
echo "ERROR: quota (-q) must numeric or NULL"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
cmd="$cmd;"
|
||||
# add domain to vmail database
|
||||
echo $cmd
|
||||
# create vmail directory for domain
|
||||
if [ ! -d "$VMAIL_DIR" ] ; then
|
||||
echo "install -o vmail -g vmail -m 750 -d $VMAIL_DIR"
|
||||
fi
|
||||
if [ ! -d "$VMAIL_DIR/$domain" ] ; then
|
||||
echo "install -o vmail -g vmail -m 750 -d $VMAIL_DIR/$domain"
|
||||
fi
|
||||
elif [ "$rowcount" -eq '1' ] ; then
|
||||
echo "ERROR: $domain already exists in vmail database."
|
||||
exit 1
|
||||
else
|
||||
echo "ERROR: System error querying vmail database"
|
||||
exit 1
|
||||
fi
|
115
bin/vmail-domains-del.sh
Executable file
115
bin/vmail-domains-del.sh
Executable file
|
@ -0,0 +1,115 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
help()
|
||||
{
|
||||
thisfilename=$(basename -- "$0")
|
||||
echo "$thisfilename"
|
||||
echo "Delete domain and all associated email accounts from the vmail system."
|
||||
echo ""
|
||||
echo "usage: $thisfilename domain [OPTIONS]"
|
||||
echo ""
|
||||
echo " -h Print this help."
|
||||
exit
|
||||
}
|
||||
|
||||
# check for and set domain
|
||||
if [ -n "$1" ]; then
|
||||
if vmail::validate_domain $1; then
|
||||
domain=$1
|
||||
shift
|
||||
else
|
||||
echo "ERROR: Invalid domain name: $1"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
help
|
||||
fi
|
||||
|
||||
# set any options that were passed
|
||||
while getopts "h" opt; do
|
||||
case "${opt}" in
|
||||
h )
|
||||
help
|
||||
exit;;
|
||||
\? )
|
||||
echo "Invalid option: $OPTARG" 1>&2
|
||||
;;
|
||||
: )
|
||||
echo "Invalid option: $OPTARG requires an argument" 1>&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
|
||||
# check if domain exists in vmail database
|
||||
rowcount=`mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -s -r -N -e "SELECT COUNT(*) from vm_domains WHERE domain='$domain';"`
|
||||
if [ "$rowcount" -eq '0' ] ; then
|
||||
# looks good, build SQL
|
||||
cmd="mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -e \"INSERT INTO vm_domains SET domain='$domain'\""
|
||||
if [ ! -z "$status" ] ; then
|
||||
if [ "$status" == 0 ] || [ "$status" == 1 ]; then
|
||||
cmd="$cmd, status='$status'"
|
||||
else
|
||||
echo "ERROR: status (-s) must be 1 or 0"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ ! -z "$limit" ] ; then
|
||||
if [[ "$limit" == "NULL" ]]; then
|
||||
cmd="$cmd, mbox_limit=NULL"
|
||||
elif [[ "$limit" =~ ^[0-9]+$ ]]; then
|
||||
cmd="$cmd, mbox_limit='$limit'"
|
||||
else
|
||||
echo "ERROR: limit (-l) must numeric or NULL"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ ! -z "$quota" ] ; then
|
||||
if [[ "$quota" == "NULL" ]]; then
|
||||
cmd="$cmd, mbox_quota_default=NULL"
|
||||
elif [[ "$quota" =~ ^[0-9]+$ ]]; then
|
||||
cmd="$cmd, mbox_quota_default='$quota'"
|
||||
else
|
||||
echo "ERROR: quota (-q) must numeric or NULL"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
cmd="$cmd;"
|
||||
# add domain to vmail database
|
||||
echo $cmd
|
||||
elif [ "$rowcount" -eq '1' ] ; then
|
||||
echo "ERROR: $domain already exists in vmail database."
|
||||
exit 1
|
||||
else
|
||||
echo "ERROR: System error querying vmail database"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# delete confirmed
|
||||
echo "mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -e \"DELETE FROM vm_aliases WHERE mbox_id='$mboxes_id';\""
|
||||
echo "mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -e \"DELETE FROM vm_autoresponders WHERE mbox_id='$mboxes_id';\""
|
||||
echo "mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -e \"DELETE FROM vm_filters WHERE mbox_id='$mboxes_id';\""
|
||||
echo "mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -e \"DELETE FROM vm_forwards WHERE domain_id='$domain_id' AND local_part='$mbox';\""
|
||||
echo "mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -e \"DELETE FROM vm_greylisting WHERE recipient='$mbox@$domain';\""
|
||||
echo "mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -e \"DELETE FROM vmail.sa_userpref WHERE username='$mbox@$domain';\""
|
||||
# delete from rc_* tables
|
||||
echo "mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -e \"DELETE FROM vm_mboxes WHERE id='$mboxes_id';\""
|
||||
if [ -d "$VMAIL_DIR/$domain/$mbox" ] ; then
|
||||
echo "rm -r $VMAIL_DIR/$domain/$mbox"
|
||||
fi
|
||||
|
||||
# delete from roundcube too
|
||||
|
||||
# check if vmail domain dir exits
|
||||
if [ -d $VMAIL_DIR/$domain ]; then
|
||||
echo "ERROR: Directory $VMAIL_DIR/$domain already exists."
|
||||
exit 1
|
||||
fi
|
81
bin/vmail-domains-get.sh
Executable file
81
bin/vmail-domains-get.sh
Executable file
|
@ -0,0 +1,81 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
help()
|
||||
{
|
||||
thisfilename=$(basename -- "$0")
|
||||
echo "$thisfilename"
|
||||
echo "Get domain data from vmail database."
|
||||
echo ""
|
||||
echo "usage: $thisfilename [domain] [OPTIONS]"
|
||||
echo ""
|
||||
echo " -c Output in cvs format."
|
||||
echo " -h Print this help."
|
||||
echo " -s Be more silent - use tabs instead of tables for output, do not display column headers."
|
||||
echo " -w Wildcard search when searching for specific domain."
|
||||
echo ""
|
||||
echo " Domain is optional. If not specified all domains will be queried."
|
||||
echo " By default domain search is for an exact matchs."
|
||||
echo " Specify -w to turn them in to wildcard search. e.g:"
|
||||
echo " $thisfilename stack -w # search for all domains that contain 'stack'."
|
||||
exit
|
||||
}
|
||||
|
||||
dbcmd="mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE"
|
||||
dbcmdopts="-e"
|
||||
dbquery="SELECT * from vm_domains"
|
||||
|
||||
# check for and set domain
|
||||
if [ -n "$1" ]; then
|
||||
if [ $1 == "-h" ]; then
|
||||
help
|
||||
elif [[ ! $1 =~ ^- ]] ; then
|
||||
domain=$1
|
||||
shift
|
||||
# query="SELECT * from vm_domains WHERE domain LIKE '%$domain%';"
|
||||
fi
|
||||
fi
|
||||
|
||||
# set any options that were passed
|
||||
while getopts "chsw" opt; do
|
||||
case "${opt}" in
|
||||
c )
|
||||
cvs="| sed 's/\t/,/g'"
|
||||
;;
|
||||
h )
|
||||
help
|
||||
exit;;
|
||||
s )
|
||||
dbcmdopts="-s -N $dbcmdopts"
|
||||
;;
|
||||
w )
|
||||
wildcardsearch=true
|
||||
;;
|
||||
\? )
|
||||
echo "Invalid option: $OPTARG" 1>&2
|
||||
exit;;
|
||||
esac
|
||||
done
|
||||
|
||||
# build query
|
||||
if [ -n "$domain" ]; then
|
||||
if [ -n "$wildcardsearch" ]; then
|
||||
dbquery="$dbquery WHERE domain LIKE '%$domain%'"
|
||||
else
|
||||
if vmail::validate_domain $domain; then
|
||||
dbquery="$dbquery WHERE domain='$domain'"
|
||||
else
|
||||
echo "ERROR: Invalid domain name: $domain"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# execute mysql query
|
||||
eval $dbcmd $dbcmdopts "\"$dbquery;\"" $cvs
|
98
bin/vmail-domains-mod.sh
Executable file
98
bin/vmail-domains-mod.sh
Executable file
|
@ -0,0 +1,98 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
help()
|
||||
{
|
||||
thisfilename=$(basename -- "$0")
|
||||
echo "$thisfilename"
|
||||
echo "Get domain data from vmail database."
|
||||
echo ""
|
||||
echo "usage: $thisfilename [domain] [OPTIONS]"
|
||||
echo ""
|
||||
echo " -e Exact match instead of wildcard search."
|
||||
echo " -c Output in cvs format."
|
||||
echo " -h Print this help."
|
||||
echo " -s Be more silent - use tabs instead of tables for output, do not display column headers."
|
||||
echo ""
|
||||
echo " Domain can either be a FQDN or a search term."
|
||||
echo " e.g. to search for all .org domains enter .org as the domain."
|
||||
echo " Use the -e option to disable wildcard search and require exact match of FQDN."
|
||||
exit
|
||||
}
|
||||
|
||||
# set any options that were passed
|
||||
while getopts ":s:l:q:" opt; do
|
||||
case "${opt}" in
|
||||
s )
|
||||
status=${OPTARG}
|
||||
;;
|
||||
l )
|
||||
limit=${OPTARG}
|
||||
;;
|
||||
q )
|
||||
quota=${OPTARG}
|
||||
;;
|
||||
\? )
|
||||
echo "Invalid option: $OPTARG" 1>&2
|
||||
;;
|
||||
: )
|
||||
echo "Invalid option: $OPTARG requires an argument" 1>&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# check if vmail domain dir exits
|
||||
if [ -d /var/vmail/$domain ]; then
|
||||
echo "ERROR: Directory /var/vmail/$domain already exists."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if domain exists in vmail database
|
||||
rowcount=`mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -s -r -N -e "SELECT COUNT(*) from vm_domains WHERE domain='$domain';"`
|
||||
if [ "$rowcount" -eq '0' ] ; then
|
||||
# looks good, build SQL
|
||||
cmd="mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -e \"INSERT INTO vm_domains SET domain='$domain'\""
|
||||
if [ ! -z "$status" ] ; then
|
||||
if [ "$status" == 0 ] || [ "$status" == 1 ]; then
|
||||
cmd="$cmd, status='$status'"
|
||||
else
|
||||
echo "ERROR: status (-s) must be 1 or 0"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ ! -z "$limit" ] ; then
|
||||
if [[ "$limit" == "NULL" ]]; then
|
||||
cmd="$cmd, mbox_limit=NULL"
|
||||
elif [[ "$limit" =~ ^[0-9]+$ ]]; then
|
||||
cmd="$cmd, mbox_limit='$limit'"
|
||||
else
|
||||
echo "ERROR: limit (-l) must numeric or NULL"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ ! -z "$quota" ] ; then
|
||||
if [[ "$quota" == "NULL" ]]; then
|
||||
cmd="$cmd, mbox_quota_default=NULL"
|
||||
elif [[ "$quota" =~ ^[0-9]+$ ]]; then
|
||||
cmd="$cmd, mbox_quota_default='$quota'"
|
||||
else
|
||||
echo "ERROR: quota (-q) must numeric or NULL"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
cmd="$cmd;"
|
||||
# add domain to vmail database
|
||||
echo $cmd
|
||||
elif [ "$rowcount" -eq '1' ] ; then
|
||||
echo "ERROR: $domain already exists in vmail database."
|
||||
exit 1
|
||||
else
|
||||
echo "ERROR: System error querying vmail database"
|
||||
exit 1
|
||||
fi
|
3
bin/vmail-installer.sh
Executable file
3
bin/vmail-installer.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo 'installing vmail-stack now!'
|
135
bin/vmail-mboxes-add.sh
Executable file
135
bin/vmail-mboxes-add.sh
Executable file
|
@ -0,0 +1,135 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
help()
|
||||
{
|
||||
thisfilename=$(basename -- "$0")
|
||||
echo "$thisfilename"
|
||||
echo "Add email account to vmail system"
|
||||
echo ""
|
||||
echo "usage: $thisfilename email password [OPTIONS]"
|
||||
echo ""
|
||||
echo " -h Print this help."
|
||||
echo " -q QUOTA Set mailbox quota in GB, otherwise default for this domain is used. NULL means no limit."
|
||||
echo " -s STATUS 1 for enabled, 0 for disabled."
|
||||
exit
|
||||
}
|
||||
|
||||
# check for and set email address, local part & domain, password
|
||||
if [ -n "$2" ]; then
|
||||
if [ $1 == "-h" ] || [ $2 == "-h" ]; then
|
||||
help
|
||||
else
|
||||
email=$1
|
||||
shift
|
||||
passwd=$1
|
||||
shift
|
||||
if [[ $email =~ "@" ]] ; then
|
||||
mbox=${email%@*}
|
||||
domain=${email##*@}
|
||||
if [ -z $mbox ] ; then
|
||||
echo "ERROR: No local part in $email."
|
||||
exit
|
||||
elif [ -z $domain ] ; then
|
||||
echo "ERROR: No domain in $email."
|
||||
exit
|
||||
elif ! vmail::validate_domain $domain; then
|
||||
echo "ERROR: $domain is not a valid domain name."
|
||||
exit
|
||||
fi
|
||||
else
|
||||
echo "ERROR: $email is not a valid email."
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
else
|
||||
help
|
||||
fi
|
||||
|
||||
# set any options that were passed
|
||||
while getopts "hq:s:" opt; do
|
||||
case "${opt}" in
|
||||
h )
|
||||
help
|
||||
exit;;
|
||||
q )
|
||||
quota=${OPTARG}
|
||||
;;
|
||||
s )
|
||||
status=${OPTARG}
|
||||
;;
|
||||
\? )
|
||||
echo "Invalid option: $OPTARG" 1>&2
|
||||
exit;;
|
||||
: )
|
||||
echo "Invalid option: $OPTARG requires an argument" 1>&2
|
||||
exit;;
|
||||
esac
|
||||
done
|
||||
|
||||
# get domain_id (and thus check if domain already exists)
|
||||
domain_id=`mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -s -r -N -e "SELECT id from vm_domains WHERE domain='$domain';"`
|
||||
if [ -z $domain_id ] ; then
|
||||
echo "ERROR: Domain $domain does not exist."
|
||||
exit
|
||||
fi
|
||||
|
||||
# make sure mbox doesn't already exist
|
||||
rowcount=`mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -s -r -N -e "SELECT COUNT(*) FROM vm_mboxes WHERE domain_id='$domain_id' AND mbox='$mbox';"`
|
||||
if [ "$rowcount" -eq '0' ] ; then
|
||||
# mbox does not exist, build SQL
|
||||
# first encrypt password
|
||||
passwd=`doveadm pw -s sha512-crypt -p "$passwd"|sed 's|^{SHA512-CRYPT}||'`
|
||||
dbcmd="mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -e 'INSERT INTO vm_mboxes SET domain_id=\"$domain_id\", mbox=\"$mbox\", passwd=\"$passwd\""
|
||||
if [ -n "$status" ] ; then
|
||||
if [ "$status" == 0 ] || [ "$status" == 1 ]; then
|
||||
dbcmd="$dbcmd, status=\"$status\""
|
||||
else
|
||||
echo "ERROR: status (-s) must be 1 or 0"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
if [ -z "$quota" ] ; then
|
||||
# get mbox_quota_default from domains table
|
||||
quota=`mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE -s -r -N -e "SELECT mbox_quota_default from vm_domains WHERE domain='$domain';"`
|
||||
fi
|
||||
if [[ "$quota" == "NULL" ]]; then
|
||||
dbcmd="$dbcmd, quota=NULL"
|
||||
elif [[ "$quota" =~ ^[0-9]+$ ]]; then
|
||||
dbcmd="$dbcmd, quota=\"$quota\""
|
||||
else
|
||||
echo "ERROR: quota (-q) must numeric or NULL"
|
||||
exit 1
|
||||
fi
|
||||
dbcmd="$dbcmd;'"
|
||||
elif [ "$rowcount" -eq '1' ] ; then
|
||||
echo "ERROR: $email already exists in vmail database."
|
||||
exit
|
||||
else
|
||||
echo "ERROR: System error querying vmail database."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# add mbox
|
||||
# evail $dbcmd
|
||||
echo $dbcmd
|
||||
|
||||
# create all required vmail dirs
|
||||
if [ ! -d "/var/vmail/$domain" ] ; then
|
||||
echo "install -o vmail -g vmail -m 750 -d /var/vmail/$domain"
|
||||
fi
|
||||
if [ ! -d "/var/vmail/$domain/$mbox" ] ; then
|
||||
echo "install -o vmail -g vmail -m 750 -d /var/vmail/$domain/$mbox"
|
||||
fi
|
||||
if [ ! -d "/var/vmail/$domain/$mbox/Maildir" ] ; then
|
||||
echo "install -o vmail -g vmail -m 750 -d /var/vmail/$domain/$mbox/Maildir"
|
||||
fi
|
||||
if [ ! -d "/var/vmail/$domain/$mbox/Maildir/cur" ] ; then
|
||||
echo "install -o vmail -g vmail -m 750 -d /var/vmail/$domain/$mbox/Maildir/cur"
|
||||
fi
|
102
bin/vmail-mboxes-get.sh
Executable file
102
bin/vmail-mboxes-get.sh
Executable file
|
@ -0,0 +1,102 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
help()
|
||||
{
|
||||
thisfilename=$(basename -- "$0")
|
||||
echo "$thisfilename"
|
||||
echo "Get email account data from vmail database."
|
||||
echo ""
|
||||
echo "usage: $thisfilename [username|domain|fullemail] [OPTIONS]"
|
||||
echo ""
|
||||
echo " -c Output in cvs format."
|
||||
echo " -h Print this help."
|
||||
echo " -s Be more silent - use tabs instead of tables for output, do not display column headers."
|
||||
echo " -w Wildcard search when searching for username."
|
||||
echo ""
|
||||
echo " Search term is optional. If nothing specified all email acccounts for all domains will be returned."
|
||||
echo " By default username searches are for exact matchs."
|
||||
echo " Specify -w to turn them in to a wildcard search. Examples:"
|
||||
echo " $thisfilename joe@example.com # search for specific email address 'joe@example.com'."
|
||||
echo " $thisfilename joe # search for username 'joe' in all domains."
|
||||
echo " $thisfilename joe -w # search for usernames containing 'joe' in all domains."
|
||||
echo " $thisfilename example.com # search for all usernames in the 'example.com' domain."
|
||||
exit
|
||||
}
|
||||
|
||||
dbcmd="mysql --defaults-extra-file=$MYSQL_CONNECTION_INFO_FILE"
|
||||
dbcmdopts="-e"
|
||||
dbquery="SELECT vm_mboxes.mbox, vm_domains.domain, vm_mboxes.status, vm_mboxes.quota FROM vm_domains, vm_mboxes WHERE vm_domains.id=vm_mboxes.domain_id"
|
||||
|
||||
# check for and set email search term(s)
|
||||
if [ -n "$1" ]; then
|
||||
if [ $1 == "-h" ]; then
|
||||
help
|
||||
elif [[ ! $1 =~ ^- ]] ; then
|
||||
searchterm=$1
|
||||
shift
|
||||
if [[ $searchterm =~ "@" ]] ; then
|
||||
mbox=${searchterm%@*}
|
||||
domain=${searchterm##*@}
|
||||
elif vmail::validate_domain $searchterm; then
|
||||
domain=$searchterm
|
||||
else
|
||||
mbox=$searchterm
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# set any options that were passed
|
||||
while getopts "chsw" opt; do
|
||||
case "${opt}" in
|
||||
c )
|
||||
cvs="| sed 's/\t/,/g'"
|
||||
;;
|
||||
h )
|
||||
help
|
||||
exit;;
|
||||
s )
|
||||
dbcmdopts="-s -N $dbcmdopts"
|
||||
;;
|
||||
w )
|
||||
wildcardsearch=true
|
||||
;;
|
||||
\? )
|
||||
echo "Invalid option: $OPTARG" 1>&2
|
||||
exit;;
|
||||
esac
|
||||
done
|
||||
|
||||
# build query
|
||||
if [ -n "$mbox" ] && [ -n "$domain" ]; then
|
||||
# search for specific email address
|
||||
dbquery="$dbquery AND vm_domains.domain='$domain' AND vm_mboxes.mbox='$mbox'"
|
||||
elif [ -n "$mbox" ] && [ -z "$domain" ]; then
|
||||
# search all domains for username
|
||||
if [ -n "$wildcardsearch" ]; then
|
||||
# wildcard search
|
||||
dbquery="$dbquery AND vm_mboxes.mbox LIKE '%$mbox%'"
|
||||
else
|
||||
# exact match
|
||||
dbquery="$dbquery AND vm_mboxes.mbox='$mbox'"
|
||||
fi
|
||||
elif [ -z "$mbox" ] && [ -n "$domain" ]; then
|
||||
# get all usernames for domain
|
||||
dbquery="$dbquery AND vm_domains.domain='$domain'"
|
||||
# elif [ -z "$mbox" ] && [ -z "$domain" ]; then
|
||||
# echo "ERROR: No username or domain specified."
|
||||
# help
|
||||
# uncomment above 3 lines to force search term, otherwise all email addresses for all domains will be returned
|
||||
fi
|
||||
|
||||
# set order by
|
||||
dbquery="$dbquery ORDER BY vm_domains.domain, vm_mboxes.mbox;";
|
||||
|
||||
# execute mysql query
|
||||
eval $dbcmd $dbcmdopts "\"$dbquery\"" $cvs
|
31
bin/vmail-purge.sh
Executable file
31
bin/vmail-purge.sh
Executable file
|
@ -0,0 +1,31 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /usr/local/etc/vmail.conf
|
||||
|
||||
accounts=(`find $VMAIL_DIR/*/ -mindepth 1 -maxdepth 1 -type d`);
|
||||
dirs=('.Junk' '.Trash');
|
||||
subdirs=('new' 'cur');
|
||||
|
||||
for account in "${accounts[@]}"; do
|
||||
|
||||
for dir in "${dirs[@]}"; do
|
||||
|
||||
for subdir in "${subdirs[@]}"; do
|
||||
|
||||
if [[ -d "$account/Maildir/$dir/$subdir" ]]; then
|
||||
|
||||
/usr/bin/find $account/Maildir/$dir/$subdir -type f -mtime +30 -exec rm -f {} +
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
done
|
||||
|
||||
done
|
||||
|
34
bin/vmail-secure.sh
Executable file
34
bin/vmail-secure.sh
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /opt/stack/include/config.inc
|
||||
|
||||
# check for and set virtualhost
|
||||
if [ -n "$1" ]; then
|
||||
virtualhost=$1
|
||||
else
|
||||
echo "virtualhost not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
check that IP points here
|
||||
install le cert
|
||||
create dovecot conf
|
||||
vhost-enable
|
||||
|
||||
|
||||
dkim
|
||||
_dmarc.example.com 3600 TXT "v=DMARC1; p=reject;"
|
||||
letsencrypt-certonly.sh
|
||||
vmail.sh create domain
|
||||
vhost VHostMAIL
|
||||
dovecot/sites.d/
|
||||
|
||||
|
||||
# enable webmail vhost & restart apache
|
||||
webmail-enable.sh $virtualhost
|
||||
|
24
bin/webmail-disable.sh
Executable file
24
bin/webmail-disable.sh
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /opt/stack/include/config.inc
|
||||
|
||||
# check for and set virtualhost
|
||||
if [ -n "$1" ]; then
|
||||
virtualhost=$1
|
||||
else
|
||||
echo "virtualhost not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -h "/etc/apache2/sites-enabled/mail.$virtualhost.conf" ]; then
|
||||
/usr/sbin/a2dissite --quiet mail.$virtualhost
|
||||
/usr/bin/systemctl --quiet reload apache2
|
||||
fi
|
||||
if [ -f "/etc/apache2/sites-available/mail.$virtualhost.conf" ]; then
|
||||
rm /etc/apache2/sites-available/mail.$virtualhost.conf
|
||||
fi
|
30
bin/webmail-enable.sh
Executable file
30
bin/webmail-enable.sh
Executable file
|
@ -0,0 +1,30 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vmail-stack
|
||||
# https://git.stack-source.com/msb/vmail-stack
|
||||
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||
|
||||
# load config
|
||||
source /opt/stack/include/config.inc
|
||||
|
||||
# check for and set virtualhost
|
||||
if [ -n "$1" ]; then
|
||||
virtualhost=$1
|
||||
else
|
||||
echo "virtualhost not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f /etc/ssl/letsencrypt/mail.$virtualhost.pem ]; then
|
||||
echo "Let's Encrypt cert for mail.$virtualhost does not exist, create that first:"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# enable webmail vhost & restart apache
|
||||
if [ ! -f "/etc/apache2/sites-available/mail.$virtualhost.conf" ]; then
|
||||
echo "Use VHostMAIL $virtualhost" > /etc/apache2/sites-available/mail.$virtualhost.conf
|
||||
fi
|
||||
if [ ! -h "/etc/apache2/sites-enabled/mail.$virtualhost.conf" ]; then
|
||||
/usr/sbin/a2ensite --quiet mail.$virtualhost
|
||||
/usr/bin/systemctl --quiet is-active apache2 && systemctl --quiet reload apache2
|
||||
fi
|
6
etc/vmail-db-info.conf
Normal file
6
etc/vmail-db-info.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
[client]
|
||||
host = localhost
|
||||
database = vmail
|
||||
user = vmail
|
||||
password = passwd
|
||||
socket = /var/run/mysqld/mysqld.sock
|
20
etc/vmail.conf
Normal file
20
etc/vmail.conf
Normal file
|
@ -0,0 +1,20 @@
|
|||
# vmail configs
|
||||
|
||||
# constants
|
||||
|
||||
readonly MYSQL_CONNECTION_INFO_FILE=/usr/local/etc/vmail-db-info.conf
|
||||
readonly VMAIL_DIR=/var/vmail
|
||||
readonly VMAIL_DB=vmail
|
||||
|
||||
# functions
|
||||
|
||||
# crude but good enough domain name format validation
|
||||
function vmail::validate_domain () {
|
||||
local my_domain=$1
|
||||
if [[ $my_domain =~ ^(([a-zA-Z](-?[a-zA-Z0-9])*)\.)+[a-zA-Z]{2,}$ ]] ; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
12
libexec/vmail-quota-warning.sh
Normal file
12
libexec/vmail-quota-warning.sh
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
PERCENT=$1
|
||||
USER=$2
|
||||
DOMAIN=${USER##*@}
|
||||
|
||||
if [ "$PERCENT" -eq '95' ] ; then
|
||||
MSG="Your mailbox is now $PERCENT% full. Please delete some messages immediately to avoid email service interruptions."
|
||||
else
|
||||
MSG="Your mailbox is now $PERCENT% full. Please delete some messages to avoid exceeding your quota."
|
||||
fi
|
||||
|
||||
echo "$MSG" | mail -s "Email quota warning" $USER -aFrom:postmaster@$DOMAIN
|
Loading…
Reference in New Issue
Block a user