Dovecot’s Quota Plugin

The below assumes your using mdbox so dirsize or dict:sql will be the fastest. Since we already have sql setup, were going to go with that.

Enabling the Quota Plugin

mail_plugins = $mail_plugins quota

protocol imap {
  # Space separated list of plugins to load (default is global mail_plugins).
  mail_plugins = $mail_plugins imap_quota
}

plugin {
  # SQL backend:
  quota = dict:User quota::proxy::quota
  quota_rule = *:storage=1024M:messages=100000
  quota_rule2 = Trash:storage=+20%%
  quota_rule3 = Junk:storage=+20%%
}dict {
  quota = mysql:/etc/dovecot/dovecot-dict-mysql.conf
}

The dovecot-dict-mysql.conf file should containe something like this

connect = host=localhost dbname=postfix user=postfix password=postfix
map {
  pattern = priv/quota/storage
  table = quota
  username_field = username
  value_field = bytes
}
map {
  pattern = priv/quota/messages
  table = quota
  username_field = username
  value_field = messages
}

And lastly, add the following table to your email servers database in mySQL.

CREATE TABLE quota (
  username varchar(100) not null,
  bytes bigint not null default 0,
  messages integer not null default 0,
  primary key (username)
);
Advertisements

Postfix mySQL to SQLite export/import scripts

postfixdb-export.sh:

#/bin/bash
TMPDIR=/tmp/postfix_sqlite
DATABASENAME=postfix.sqlite
MYSQLDATABASE=postfix
MYSQLUSER=postfix
MYSQLPASS=postfix
HTTPDIR=/var/www/mail.mattrude.com/noc

if [ ! -e $TMPDIR ]; then
 mkdir -p $TMPDIR
 chmod a+w $TMPDIR
else
 chmod a+w $TMPDIR
fi

if [ ! -e $HTTPDIR ]; then
 mkdir -p $HTTPDIR
 rm -rf $TMPDIR/csv_md5check.md5
else
 if [ ! -e $HTTPDIR/$DATABASENAME.gpg ]; then
  rm -rf $TMPDIR/csv_md5check.md5
 fi
fi

rm -rf $TMPDIR/alias.csv $TMPDIR/domain.csv $TMPDIR/mailbox.csv
echo "SELECT * FROM alias
INTO OUTFILE '$TMPDIR/alias.csv'
FIELDS TERMINATED BY '|'
LINES TERMINATED BY '\n'" |mysql $MYSQLDATABASE

echo "SELECT * FROM domain
INTO OUTFILE '$TMPDIR/domain.csv'
FIELDS TERMINATED BY '|'
LINES TERMINATED BY '\n'" |mysql $MYSQLDATABASE

echo "SELECT * FROM mailbox
INTO OUTFILE '$TMPDIR/mailbox.csv'
FIELDS TERMINATED BY '|'
LINES TERMINATED BY '\n'" |mysql $MYSQLDATABASE

if [ -e $TMPDIR/csv_md5check.md5 ]; then
 MD5STATUS=`md5sum -c $TMPDIR/csv_md5check.md5 |grep -v ".csv: OK" |wc -l` 2>&1
else
 MD5STATUS=999
fi

if [ $MD5STATUS != '0' ]; then
 rm -rf $TMPDIR/$DATABASENAME $TMPDIR/$DATABASENAME.md5 $TMPDIR/schema.txt
 md5sum $TMPDIR/*.csv > $TMPDIR/csv_md5check.md5
 echo "Database $MYSQLDATABASE is being updated"
 echo "
 CREATE TABLE alias (
  address varchar(255) NOT NULL,
  goto text NOT NULL,
  domain varchar(255) NOT NULL,
  created datetime NOT NULL default '0000-00-00 00:00:00',
  modified datetime NOT NULL default '0000-00-00 00:00:00',
  active tinyint(1) NOT NULL default '1');

 CREATE TABLE domain (
  domain varchar(255) NOT NULL,
  description varchar(255) NOT NULL,
  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',
  created datetime NOT NULL default '0000-00-00 00:00:00',
  modified datetime NOT NULL default '0000-00-00 00:00:00',
  active tinyint(1) NOT NULL default '1' );

 CREATE TABLE mailbox (
  username varchar(255) NOT NULL,
  password varchar(255) NOT NULL,
  name varchar(255) NOT NULL,
  maildir varchar(255) NOT NULL,
  mailstore varchar(255) NOT NULL default 'mdbox:',
  quota bigint(20) NOT NULL default '0',
  domain varchar(255) NOT NULL,
  created datetime NOT NULL default '0000-00-00 00:00:00',
  modified datetime NOT NULL default '0000-00-00 00:00:00',
  quota_usage varchar(255),
  quota_usage_date varchar(255),
  active tinyint(1) NOT NULL default '1',
  local_part varchar(255) NOT NULL );
 " > $TMPDIR/schema.txt

 echo ".read $TMPDIR/schema.txt" |sqlite3 $TMPDIR/$DATABASENAME
 echo ".import $TMPDIR/alias.csv alias" |sqlite3 $TMPDIR/$DATABASENAME
 echo ".import $TMPDIR/domain.csv domain" |sqlite3 $TMPDIR/$DATABASENAME
 echo ".import $TMPDIR/mailbox.csv mailbox" |sqlite3 $TMPDIR/$DATABASENAME

 rm -rf $HTTPDIR/$DATABASENAME $HTTPDIR/$DATABASENAME.gpg $HTTPDIR/$DATABASENAME.sig
 cp $TMPDIR/$DATABASENAME $HTTPDIR/$DATABASENAME
 cd $HTTPDIR/
 gpg -b $DATABASENAME
 gpg -se -r E2E70CD8 -r D2FAA865 -r 6503BE11 $DATABASENAME
 rm -f $HTTPDIR/$DATABASENAME
 #md5sum $DATABASENAME > $DATABASENAME.md5
 #bzip2 $DATABASENAME
 #ssh odin.mattrude.com /home/matt/bin/sbin/postfix_sqlite_import.sh
fi

postfixdb-import.sh:

#/bin/bash
DBNAME=postfix.sqlite
DBDIR=/etc/postfix/database
URL=https://mail.mattrude.com/noc/postfix.sqlite
TMPDIR=/tmp/$DBNAME
LOGDIR=$TMPDIR

if [ ! -e $DBDIR ]; then
 mkdir -p $DBDIR
 chmod 700 $DBDIR
 chown 0:0 $DBDIR
fi

if [ ! -e $TMPDIR ]; then
 mkdir -p $TMPDIR
fi

if [ ! -e $LOGDIR ]; then
 mkdir -p $LOGDIR
fi

rm -rf $LOGDIR/postfix_import*.log $TMPDIR/$DBNAME.sig $DBDIR/$DBNAME.sig
wget --no-check-certificate -P $DBDIR $URL.sig > $LOGDIR/postfix_import_sig_download.log  2>&1
SIGDOWNLOAD=$?

if [ $SIGDOWNLOAD != 0 ]; then
 echo "Did not download file $URL.sig; The host may be down or too busy."
 echo "Here is the download log:"
 cat $LOGDIR/postfix_import_sig_download.log
 echo ""
 echo "exiting script"
 exit 1
fi

cd $DBDIR
gpg --verify $DBNAME.sig > /dev/null 2>&1
MD5STATUS=`echo $?`
if [ $MD5STATUS != '0' ]; then
 echo "Update needed, downloading updated $DBNAME."
 cd $TMPDIR
 rm -f $TMPDIR/$DBNAME.sig
 mv $DBDIR/$DBNAME.sig $TMPDIR/$DBNAME.sig
 rm -rf $TMPDIR/$DBNAME.gpg
 wget --no-check-certificate -P $TMPDIR $URL.gpg > $LOGDIR/postfix_import_download.log 2>&1
 if [ -e $TMPDIR/$DBNAME.gpg ]; then
  cd $TMPDIR
  gpg $TMPDIR/$DBNAME.gpg >> $LOGDIR/postfix_import_download.log 2>&1
  echo "sig test 2"
  ls -lh
  gpg --verify $DBNAME.sig > /dev/null 2>&1
  SIGTEST=`echo $?`
  if [ $SIGTEST == '0' ]; then
   cd $DBDIR
   echo "Database file $DBNAME.gpg was successfully downloaded"
   ARCHIVEDATE=`date +%Y%m%d_%H%M`
   mv $DBDIR/$DBNAME $DBDIR/$DBNAME.$ARCHIVEDATE
   mv $TMPDIR/$DBNAME $DBDIR/$DBNAME
   bzip2 $DBDIR/$DBNAME.$ARCHIVEDATE
   chown 0:0 $DBDIR/$DBNAME
   chmod 666 $DBDIR/$DBNAME
   if [ -e $DBDIR/$DBNAME ]; then
    cd $DBDIR
    cp $TMPDIR/$DBNAME.sig $DBDIR/$DBNAME.sig
    MD5TEST2=`gpg --verify $DBNAME.sig |grep -v "gpg: Good signature" |wc -l`
    if [ $MD5TEST2 = '0' ]; then
     echo "$DBNAME was updated successfully!"
     rm -rf $DBDIR/$DBNAME.sig
    else
     echo "$DBNAME was downloaded successfully but the downloaded file dose not match the signature file."
     exit 1
    fi
   else
    echo "$DBNAME was not copied to the database location ($DBDIR)."
    exit 1
   fi
  else
   echo "Database $DBNAME was not updated, the signature check failed."
   echo "Here's the Signature Check Log:"
   cd $TMPDIR
   gpg --verify $DBNAME.sig
   rm -rf $TMPDIR/$DBNAME*
  fi
 else
  echo "Database $DBNAME was not updated, file was not downloaded."
  echo ""
  echo "Here's the download log:"
  cat $LOGDIR/postfix_import_download.log
  rm -rf $TMPDIR/$DBNAME*
  rm -rf $DBDIR/$DBNAME.sig
 fi
fi
rm -rf $TMPDIR/$DBNAME.sig $DBDIR/$DBNAME.sig