# Mail quotas and Virtual Mailhosting System Guide... ???

## jwegman

Hello everyone,

I'm setting up a small virtual mail hosting server (100 users) and would like methods of using mail quotas.

It's my understanding that since we are NOT creating local user accounts, file system quotas are not applicable.

My research then goes to maildirquota's, however I have not found all the ingredients to get it functional.  

Is there anyone willing to assist who has done this?

Thanks

Jake

----------

## SimianRage

I haven't worried about it myself yet, but if you use the virtual delivery agent you can set virtual_mailbox_limit to control the size of a mbox or maildir. May not be exactly what you're looking for, but might help.

From man virtual:

```

       virtual_mailbox_limit

              The maximal size in bytes of a mailbox or maildir file.  Set  to

              zero to disable the limit.

```

EDIT: keep messing up my code tags

----------

## jwegman

The following worked for me..:

1st - #emerge maildrop

2nd - add/modify /etc/maildrop/maildropmysql.cf to the following:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# The attributes are:

#

# mail - The full email address of the user (ie user@yourdomain.com)

#        This is the primary attribute searched upon by maildrop.

#

# maildir - The location (full path including name) of the users

#           mail directory (Maildir)

#

# homedirectory - The location (full path including name) of the 

#                 users home directory.  This may be the same as the

#                 users maildir.

#

# uidnumber - The uid of the user that owns the mail files for 

#             this user.  This may be a specific uid per user, 

#             or a single uid for every user (full 'virtual' user 

#             configuration), or a combination.

#

# gidnumber - The gid of the user that owns the mail files for 

#             this user.  This may be a specific gid per user, 

#             or a single gid for every user (full 'virtual' user 

#             configuration), or a combination.

#

# quota     - *OPTIONAL* The quota for this user.  If blank, or

#             non-existent defaults to no quota.

# mailstatus - account status 

#

# A sample LDAP entry is given at the end of this file.

#

# --- Actual configuration begins here -----------------------------

# hostname - host name of your ldap server

hostname	localhost

port		3306

socket		/var/run/mysqld/mysqld.sock

database	mailsql

dbuser		mailsql

dbpw		somepassword

dbtable		users

#not used now

#timeout		5

# default_uid - default uid (number only) to use incase uidnumber attribute not

# found in users mysql entry

default_uidnumber	1001

# default_gid - default gid (number only) to use incase gidnumber attribute not

# found in users ldap entry

default_gidnumber	1001

# MySQL Field definitions

#

# This section allows you to specify the actual attributes you

# use in your Mysql record

# 

# The example attribute mapping shown below is also the default

# mapping used by maildrop in the case that any are missing

# UID_FIELD - MySQL attribute which contains the users name (w or w/o domain)

uid_field		email

# UIDNUMBER_FIELD - MySQL attribute which contains the system uid to deliver

# mail as

uidnumber_field		uid

# GIDNUMBER_FIELD - MySQL attribute which contains the system gid to deliver

# mail as

gidnumber_field		gid

# MAILDIR_FIELD - MySQL attribute which contains the path to the users

# custom maildir

maildir_field		maildir

# HOMEDIRECTORY_FIELD - MySQL attribute which contains the path to the users

# home directory

homedirectory_field	homedir

# QUOTA_FIELD - MySQL attribute which contains the users quota

quota_field		quota

# MYSQL_DEFAULT_STATUS_FIELD - MySQL attribute which could be created in the

# MySQL entry to set whether or not the user is allowed to receive email on

# this box..

#		-- looks unused for now; but must be valid column ! (2001-11-03)

mailstatus_field	postfix

# MYSQL_DEFAULT_WHERE_CLAUSE - This is optional !

# It can be set to any fixed string starting with keyword 'AND'.

# It will then be appended to the WHERE clause of our query.

where_clause		"where postfix = 'y'"

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

3rd - Modify /etc/postfix/master.cf with the following:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

maildrop  unix  -       n       n       -       -       pipe

  flags=R user=vmail argv=/usr/bin/maildrop -w 90 -d ${recipient}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

4th - Populated the "quota" field in the "users" table in the "mailsql" database with (12MB max size):

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

12000000S

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

5th - Changed the "destination" field in the "transport" table with:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

maildrop:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Each user in the "users" table with the quota field populated will have a maildirsize file generated and used for tracking the .maildir size when Maildrop delivers mail, then when Courier-Imap removes it.

Also when you add the Squirrelmail quota plugin, it will show a usage bar in the folder list.

Regards,

Jake

----------

## tangent

Thanks, mail quotas work great with maildrop as you described.

Have a couple of problems though. Firstly, where i previously relied on postfix to run maildirmake for newly created accounts, maildrop refuses to do so:

Sep 26 18:27:10 [postfix/pipe] 6011E24858: to=<xxx@xxx.xxx>, relay=maildro

p, delay=7252, status=deferred (temporary failure. Command output: /usr/bin/mail

drop: Unable to create a dot-lock. )

Secondly, anyway to change the error message on the bounced email?

    The e-mail system was unable to deliver the message, but did not

report a specific reason.  Check the address and try again.  If it still

fails, contact your system administrator.

    < mail.xxx.com #5.0.0 X-Postfix; permission denied. Command

output: maildrop:    maildir over quota.>

----------

## jwegman

There is a patch for Maildrop to create maildir/'s upon delivery to a new recipient however I decided to patch postfix's vda (virtual delivery agent) so that it supports the softquota.  Now my maildir/'s are created on the fly and it updates the maildirsize file for the softquotas.

The vda also supports the over_quota bounced error message.  The current patch can be found at the following link:  http://web.onda.com.br/nadal/

I simply unpacked the patch, modified the latest postfix ebuild to include the patch and re-emerged postfix - added the following to my /etc/postfix/main.cf file:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

virtual_mailbox_limit = 13000000

virtual_mailbox_limit_maps = static:12000000

virtual_create_maildirsize = yes

virtual_overquota_bounce = yes

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I'm using a hard limit of 13MB's per maildir/ and set the softquota to 12MB's.  The postfix vda will create the maildirsize file with the 12MB quota specified and it will bounce a over quota message (with a customizable message) to the sender with (see the vda patch for details):

virtual_mailbox_limit_message =

I am finding this is a better solution than using maildrop as the message delivery agent because it will create the new maildir/'s which I didn't think matter that much, but now that I'm using Mischa Peter's "Postfix Admin" -  PHP virtual domain / account creator / administrator - I find that manualy creating the maildir/'s too much of a bother.  (I'm also using Mischa Peter's mySQL postfix database layout instead of the one detailed in the Gentoo's Virtual Mailhosting Guide - very easy to adapt to the guide.  Mischa also has a step by step how-to for his virtual mail system.

Postfix Admin can be found at: http://high5.net/postfixadmin

With this I'm just about ready to roll out a production virtual webmail system!

regards,

jake

----------

## cchee

Hi,

I am attempting to create an ebuild file based upon 2.0.16-r1 to include the vda patch option. But I keep getting the 

```
No message digest entry found for file 
```

 error  when I try to test my ebuild file. I have tried to recreate the digest as suggested to solve the problem but it doesn't seems to work.

Anyone can help?

----------

## cchee

Here is the ebuild file with vda patch:

```

# Copyright 1999-2004 Gentoo Technologies, Inc.

# Distributed under the terms of the GNU General Public License v2

# $Header: /home/cvsroot/gentoo-x86/net-mail/postfix/postfix-2.0.16-r1.ebuild,v 1.10 2004/01/14 20:38:12 max Exp $

inherit eutils ssl-cert

TLS_P="pfixtls-0.8.16-2.0.16-0.9.7b"

IPV6="1.18a"

IPV6_P="ipv6-${IPV6}-pf-2.0.16"

IPV6_TLS_P="tls+${IPV6_P}"

PGSQL_P="postfix-pg.postfix-2.0.0.2"

VDA="2.0.16"

DESCRIPTION="A fast and secure drop-in replacement for sendmail."

HOMEPAGE="http://www.postfix.org/"

SRC_URI="ftp://ftp.porcupine.org/mirrors/postfix-release/official/${P}.tar.gz

   ftp://ftp.porcupine.org/mirrors/postfix-release/official/${PN}-2.0-ns-mx-acl-patch.gz

   ssl? ( ftp://ftp.aet.tu-cottbus.de/pub/postfix_tls/${TLS_P}.tar.gz )

   ipv6? ( ftp://ftp.stack.nl/pub/postfix/tls+ipv6/${IPV6}/${IPV6_P}.patch.gz )

   ipv6? ( ftp://ftp.stack.nl/pub/postfix/tls+ipv6/${IPV6}/${IPV6_TLS_P}.patch.gz )

   postgres? ( http://www.mat.cc/postfix/${PGSQL_P}.patch )

   vda? ( http://web.onda.com.br/nadal/postfix/VDA/postfix-${VDA}.patch.gz )"

LICENSE="IPL-1"

SLOT="0"

KEYWORDS="x86 ~sparc ~ppc ~alpha"

IUSE="ipv6 pam ldap mysql postgres ssl sasl maildir mbox vda"

PROVIDE="virtual/mta virtual/mda"

DEPEND=">=sys-libs/db-3.2

   >=dev-libs/libpcre-3.4

   >=sys-apps/sed-4

   ldap? ( >=net-nds/openldap-1.2 )

   mysql? ( >=dev-db/mysql-3.23.51 )

   postgres? ( >=dev-db/postgresql-7.1 )

   ssl? ( >=dev-libs/openssl-0.9.6g )

   sasl? ( >=dev-libs/cyrus-sasl-2 )"

RDEPEND="${DEPEND}

   >=net-mail/mailbase-0.00

   !virtual/mta"

# Is this still necessary since gentoo sasl looks

# in /etc/sasl2 for it's config files?

pkg_setup() {

   # Prevent mangling the smtpd.conf file.

   if [ ! -L "${ROOT}/usr/lib/sasl2/smtpd.conf" ] ; then

      if [ -f "${ROOT}/usr/lib/sasl2/smtpd.conf" ] ; then

         ebegin "Protecting your smtpd.conf file"

         if [ ! -d "${ROOT}/etc/sasl2" ] ; then

            mkdir -p "${ROOT}/etc/sasl2"

         fi

         # This shouldn't be necessary, but apparently

         # without it things can still get messy.

         if [ -L "${ROOT}/etc/sasl2/smtpd.conf" ] ; then

            rm "${ROOT}/etc/sasl2/smtpd.conf"

         fi

         # If both files exist, make sure that we preserve

         # a copy of each with the ._cfg system.

         if [ -f "${ROOT}/etc/sasl2/smtpd.conf" ] ; then

            mv "${ROOT}/etc/sasl2/smtpd.conf" \

               "${ROOT}/etc/sasl2/._cfg0000_smtpd.conf"

         fi

         mv "${ROOT}/usr/lib/sasl2/smtpd.conf" "${ROOT}/etc/sasl2"

         eend

      fi

   fi

}

src_unpack() {

   unpack ${A} && cd "${S}"

   if [ "`use ssl`" ] ; then

      if [ "`use ipv6`" ] ; then

         epatch "${WORKDIR}/${IPV6_TLS_P}.patch"

      else

         epatch "${WORKDIR}/${TLS_P}/pfixtls.diff"

      fi

   elif [ "`use ipv6`" ]; then

      epatch "${WORKDIR}/${IPV6_P}.patch"

   fi

   if [ "`use postgres`" ] ; then

      epatch "${DISTDIR}/${PGSQL_P}.patch"

   fi

    if [ "`use vda`" ]; then

      epatch "${WORKDIR}/postfix-${VDA}.patch.gz"

   fi

   # Verisign name services fixes.

   epatch "${WORKDIR}/${PN}-2.0-ns-mx-acl-patch"

   # Postfix does not get the FQDN if no hostname is configured.

   epatch "${FILESDIR}/${PN}-2.0.9-get-FQDN.patch"

   # Fix install paths.

   sed -e "s:/usr/libexec/postfix:/usr/lib/postfix:" \

      -i src/global/mail_params.h -i conf/main.cf || die "sed failed"

}

src_compile() {

   local mycc="-DHAS_PCRE" mylibs="-L/usr/lib -lpcre -ldl -lcrypt -lpthread"

   if [ "`use pam`" ] ; then

      mylibs="${mylibs} -lpam"

   fi

   if [ "`use ldap`" ] ; then

      mycc="${mycc} -DHAS_LDAP"

      mylibs="${mylibs} -lldap -llber"

   fi

   if [ "`use mysql`" ] ; then

      mycc="${mycc} -DHAS_MYSQL -I/usr/include/mysql"

      mylibs="${mylibs} -lmysqlclient -lm -lz"

   fi

   if [ "`use postgres`" ] ; then

      mycc="${mycc} -DHAS_PGSQL -I/usr/include/postgresql"

      mylibs="${mylibs} -lpq"

   fi

   if [ "`use ssl`" ] ; then

      mycc="${mycc} -DUSE_SSL"

      mylibs="${mylibs} -lssl -lcrypto"

   fi

   if [ "`use sasl`" ] ; then

      mycc="${mycc} -DUSE_SASL_AUTH -I/usr/include/sasl"

      mylibs="${mylibs} -lsasl2"

   fi

   mycc="${mycc} -DDEF_CONFIG_DIR=\\\"/etc/postfix\\\""

   mycc="${mycc} -DDEF_DAEMON_DIR=\\\"/usr/lib/postfix\\\""

   mycc="${mycc} -DDEF_PROGRAM_DIR=\\\"/usr/lib/postfix\\\""

   mycc="${mycc} -DDEF_MANPAGE_DIR=\\\"/usr/share/man\\\""

   mycc="${mycc} -DDEF_README_DIR=\\\"/usr/share/doc/${PF}/readme\\\""

   mycc="${mycc} -DDEF_SAMPLE_DIR=\\\"/usr/share/doc/${PF}/sample\\\""

   make CC="${CC:=gcc}" OPT="${CFLAGS}" CCARGS="${mycc}" AUXLIBS="${mylibs}" \

      makefiles || die "configure problem"

   emake || die "compile problem"

}

src_install () {

   /bin/sh postfix-install \

      -non-interactive \

      install_root="${D}" \

      daemon_directory="/usr/lib/postfix" \

      program_directory="/usr/lib/postfix" \

      config_directory="/usr/share/doc/${PF}/defaults" \

      readme_directory="/usr/share/doc/${PF}/readme" \

      sample_directory="/usr/share/doc/${PF}/sample" \

      manpage_directory="/usr/share/man" \

      mail_owner="postfix" \

      setgid_group="postdrop" || die "postfix-install failed"

   # Provide another link for legacy FSH.

   dosym /usr/sbin/sendmail /usr/lib/sendmail

   # Install an rmail for UUCP, closing bug #19127.

   dobin auxiliary/rmail/rmail

   # Set proper permissions on required files/directories.

   fowners root:postdrop /usr/sbin/post{drop,queue}

   fperms 02711 /usr/sbin/post{drop,queue}

   keepdir /etc/postfix

   mv "${D}/usr/share/doc/${PF}/defaults/"{*.cf,post*-*} "${D}/etc/postfix"

   if [ "`use maildir`" ] ; then

      mypostconf="home_mailbox=.maildir/"

   elif [ "`use mbox`" ] ; then

      mypostconf="mail_spool_directory=/var/spool/mail"

   fi

   "${D}/usr/sbin/postconf" -c "${D}/etc/postfix" -e \

      "alias_maps=hash:/etc/mail/aliases" \

      "alias_database=hash:/etc/mail/aliases" \

      "local_destination_concurrency_limit=2" \

      "default_destination_concurrency_limit=2" \

      ${mypostconf} || die "postconf failed"

   insinto /etc/postfix

   newins "${FILESDIR}/smtp.pass" saslpass

   fperms 600 /etc/postfix/saslpass

   exeinto /etc/init.d

   newexe "${FILESDIR}/postfix.rc6" postfix

   dodoc *README COMPATIBILITY HISTORY INSTALL LICENSE PORTING RELEASE_NOTES*

   dohtml html/*

   if [ "`use pam`" ] ; then

      insinto /etc/pam.d

      newins "${FILESDIR}/smtp.pam" smtp

   fi

   if [ "`use ssl`" ] ; then

      SSL_ORGANIZATION="${SSL_ORGANIZATION:-Postfix SMTP Server}"

      insinto /etc/ssl/postfix

      docert server

      fowners postfix:mail /etc/ssl/postfix/server.{key,pem}

   fi

   if [ "`use sasl`" ] ; then

      insinto /etc/sasl2

      newins "${FILESDIR}/smtp.sasl" smtpd.conf

   fi

}

pkg_postinst() {

   ebegin "Fixing queue directories and permissions"

   "${ROOT}/etc/postfix/post-install" upgrade-permissions

   eend $?

   echo

   ewarn "If you upgraded from postfix-1.x, you must revisit"

   ewarn "your configuration files.  See"

   ewarn "  /usr/share/doc/${PF}/RELEASE_NOTES"

   ewarn "for a list of changes."

   if [ ! -e /etc/mail/aliases.db ] ; then

      echo

      ewarn "You must edit /etc/mail/aliases to suit your needs"

      ewarn "and then run /usr/bin/newaliases. Postfix will not"

      ewarn "work correctly without it."

   fi

}

```

----------

## cchee

I have also notice that deliverquota does not seem to work properly in term of putting warning message when quota has reached the threshold set by me.

in the /etc/postfix/main.cf, I have added:

```
mailbox_command = /usr/sbin/deliverquota -w 90 $HOME/.maildir
```

But it is not sending out warning to user (virtual domain) base upon the message template in /etc/courier-imap/quotawarnmsg.

On the otherhand, if I do the command manually:

```
echo "" | /usr/sbin/deliverquota -w 90 /home/virtual/mydomain/me/.maildir
```

I got the warning message put into my inbox.

So I suspects may be there is something wrong with the $HOME in virtual domain setup. And I am not sure how to make postfix to print these environment variables to syslog while it is running.

Anyone has similar experience that can shred some light here? TIA.

----------

## cchee

Just found the bug entry for this https://bugs.gentoo.org/show_bug.cgi?id=31819

----------

## cchee

Ok. there were some problem with creating maildirsize file when it doesn't exist, the solution to that is to make sure you have the / at the end of the maildir in mailbox_command. so it should looks like:

```
mailbox_command = /usr/sbin/deliverquota -w 90 $HOME/.maildir/
```

instead of

```
mailbox_command = /usr/sbin/deliverquota -w 90 $HOME/.maildir
```

----------

## Seather

Anyone know if it's possible to get the squirrelmail quota plugin working, when using quotas with the VDA patch?

----------

