# [SOLVED] :: /etc/maildroprc not executing bash code

## Ateo

I'm not sure which element in my setup creates the user's mail directory in /home/vmail/.... I'm not sure if it's postfix or maildrop. Before installing maildrop, postfix seemed to create these directories on the fly... it worked quit nicely... for non real UNIX system users.

I've set up postfix to hand off mail to maildrop for user quota. Users for my local domain can send/recieve mail to/from the internet and my local network. However, sending an email to a virtual user, either from the internet or locally, and the message is dropped into file /home/vmail/.maildir. It never creates the directory specified by the maildir cell in my database, instead it places the mail text into this file: /home/vmail/.maildir.... So mail does get through, it's just not placed into the correct location, ie: /home/vmail/domain.tld/user/.maildir/.

If I manually create the users maildir, I can login just fine via pop3 or imap but mail *still* doesn't get delivered to the correct location. So I'm thinking maildrop isn't talking to mysql when dealing with virutal domains since it works fine with my locals.

NOTE: vmail UID = 1008, vmail GID = 408 and /home/vmail/ is owned by user vmail (chown -R vmail:vmail /home/vmail)

Here are my relevant files:

```
##

## main.cf

##

virtual_destination_concurrency_limit = $default_destination_concurrency_limit

virtual_transport = maildrop

virtual_minimum_uid = 1000

virtual_create_maildirsize = yes

virtual_mailbox_extended = yes

virtual_mailbox_limit_override = yes

virtual_overquota_bounce = yes

virtual_mailbox_base = /home/vmail/

virtual_mailbox_limit = 1048576000S

virtual_mailbox_domains = mysql:/etc/postfix/maps/mysql-virtual-domain-maps.cf

virtual_mailbox_limit_maps = mysql:/etc/postfix/maps/mysql-mailbox-quota.cf

virtual_mailbox_maps = mysql:/etc/postfix/maps/mysql-virtual-maps.cf

virtual_alias_maps = mysql:/etc/postfix/maps/mysql-virtual-aliases.cf

virtual_maildir_limit_message = mysql:/etc/postfix/maps/mysql-quota-message.cf

virtual_gid_maps = static:mysql:/etc/postfix/maps/mysql-gid.cf

virtual_uid_maps = static:mysql:/etc/postfix/maps/mysql-uid.cf

local_recipient_maps = $alias_maps $virtual_mailbox_maps

unknown_virtual_alias_reject_code = 550

unknown_virtual_mailbox_reject_code = 550
```

```
##

## mysql-virtual-domain-maps.cf

##

user                    = postfix

password                = *******

dbname                  = postfix

table                   = transport

select_field            = destination

where_field             = domain

additional_conditions   = AND active = '1' AND destination = 'maildrop:'

hosts                   = unix:/var/run/mysqld/mysqld.sock
```

```
##

## mysql-mailbox-quota.cf

##

user                    = postfix

password                = *******

dbname                  = postfix

table                   = users

select_field            = quota

where_field             = email

additional_conditions   = AND active='1'

hosts                   = unix:/var/run/mysqld/mysqld.sock
```

```
##

## myql-virtual-maps.cf

##

user                    = postfix

password                = *******

dbname                  = postfix

table                   = users

select_field            = maildir

where_field             = email

additional_conditions   = AND active = '1'

hosts                   = unix:/var/run/mysqld/mysqld.sock
```

```
##

## mysql-virtual-aliases.cf

##

user                    = postfix

password                = *******

dbname                  = postfix

table                   = virtual

select_field            = destination

where_field             = email

additional_conditions   = AND active='1'

hosts                   = unix:/var/run/mysqld/mysqld.sock
```

```
##

## mysql-gid.cf

##

user                    = postfix

password                = *******

dbname                  = postfix

table                   = users

select_field            = gid

where_field             = email

additional_conditions   = AND postfix = 'y'

hosts                   = unix:/var/run/mysqld/mysqld.sock
```

```
##

## mysql-uid.cf

##

user                    = postfix

password                = *******

dbname                  = postfix

table                   = users

select_field            = uid

where_field             = email

additional_conditions   = AND postfix = 'y'

hosts                   = unix:/var/run/mysqld/mysqld.sock
```

All my above maps return no errors when I executre 'postmap -q 'postfix' /path/to/map.cf... 

```
##

## maildropmysql.cf

##

# hostname - host name of your mysql server

hostname                localhost

port                    3306

socket                  /var/run/mysqld/mysqld.sock

database                postfix

dbuser                  postfix

dbpw                    *******

dbtable                 users

default_uidnumber       1008

default_gidnumber       440

default_quota           1048576000S

uid_field               email

uidnumber_field         uid

gidnumber_field         gid

maildir_field           maildir

homedirectory_field     homedir

quota_field             quota

mailstatus_field        postfix

where_clause            AND postfix = 'y'
```

For the record, if I take maildrop out of the picture, everything jumps back to normal. So, I really do think it's maildrop that's giving me the headache.

Any input would be appreciated..

Thanks

[edit]

Nothing in my mail log looks out of the ordinary.Last edited by Ateo on Thu Mar 10, 2005 6:35 pm; edited 6 times in total

----------

## steveb

please post your master.cf

it is needed, because you use transport to maildrop. you can just post the section with maildrop.

cheers

SteveB

----------

## Ateo

Oop. My bad. I forgot that one... but here it is...

```
maildrop  unix  -       n       n       -       -       pipe

  ## flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${user}@${nexthop} ${extension} \

                   ${recipient} ${user} ${nexthop}

  flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}

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

I've tried all 3.

Thanks.

----------

## steveb

ahhaa!! I am an idiot!

maildrop won't automatically create a Maildir for users upon delivery!! procmail does it, but maildrop does it not!

you would need to run a script in cron which does that for you. i have done something like this. if you want i can post it.

cheers

steve

----------

## Ateo

I acutually found your script and used it. So, since it is now known (for me at least) that maildrop doesn't create these directories on the fly, any ideas as to why mail is being delivered /home/vmail/.maildir (a file, not a directory) as opposed to what my maildir cell in my database says?

It's good to know that maildrop doesn't create directories on the fly.. I mean, i wish it did but your script works fine. Thanks for that script.

This is of interest. Perhaps this is where it fails? MAILDIR just doesn't look right.

```
##

## /etc/maildroprc

##

## Global maildrop filter file

##

SHELL="/bin/bash"

DEFAULT = "$HOME/.maildir"

MAILDIR = "$HOME/.maildir"
```

----------

## steveb

 *Ateo wrote:*   

> I acutually found your script and used it. So, since it is now known (for me at least) that maildrop doesn't create these directories on the fly, any ideas as to why mail is being delivered /home/vmail/.maildir (a file, not a directory) as opposed to what my maildir cell in my database says?
> 
> It's good to know that maildrop doesn't create directories on the fly.. I mean, i wish it did but your script works fine. Thanks for that script.
> 
> This is of interest. Perhaps this is where it fails? MAILDIR just doesn't look right.
> ...

 You need to add "import SENDER" after the SHELL line in order to have the correct $HOME set.

cheers

SteveB

----------

## Seather

Could you paste an example mysql entry for one of your accounts?

----------

## steveb

I don't know if this works, but you can maybe give it a try:

```
# Global maildrop filter file

#

# For Gentoo Linux by SteveB <tp22a@softhome.net>

#

#

# set verbose level for debuging

#

VERBOSE=9

logfile "/var/log/maildrop.log"

#

# import maildrop specific stuff

#

import SENDER

import RECIPIENT

import HOME

import USER

#

# set path and shell

#

PATH=/bin:/usr/bin:/usr/local/bin

SHELL=/bin/sh

#

# set default and maildir

#

DEFAULT = "$HOME/.maildir"

MAILDIR = "$HOME/.maildir"

#

# create home if not existing

#

`test -d "$HOME"`

if( $RETURNCODE == 1 )

{

   `mkdir -p "$HOME"`

   #

   # create maildir if not existing

   #

   `test -d "$MAILDIR"`

   if( $RETURNCODE == 1 )

   {

      `maildirmake "$MAILDIR"`

      #

      # create Sent folder if not existing

      #

      `test -d "$MAILDIR/.Sent"`

      if( $RETURNCODE == 1 )

      {

         `maildirmake -f "Sent" "$MAILDIR"`

      }

      

      #

      # create Drafts folder if not existing

      #

      `test -d "$MAILDIR/.Drafts"`

      if( $RETURNCODE == 1 )

      {

         `maildirmake -f "Drafts" "$MAILDIR"`

      }

      

      #

      # create Trash folder if not existing

      #

      `test -d "$MAILDIR/.Trash"`

      if( $RETURNCODE == 1 )

      {

         `maildirmake -f "Trash" "$MAILDIR"`

      }

      

      #

      # create Junk folder if not existing

      #

      `test -d "$MAILDIR/.Junk"`

      if( $RETURNCODE == 1 )

      {

         `maildirmake -f "Junk" "$MAILDIR"`

      }

   }

}
```

I just read the documentation at http://www.courier-mta.org/maildrop/?maildropfilter.html and made this small script. If you want the stuff to be faster (sh is only a symlink to bash), then switching the shell to something more light (maybe app-shells/ash) would speedup the creation process.

I normaly use $() to execute code in shell, but the documentation says I need to use the backtick charackters  :Sad:  *RETURNCODE wrote:*   

> This variable is set when maildrop runs the xfilter command, or a command that's specified within a pair of backtick characters ( command substitution ). The RETURNCODE variable will be set to the exit code of the command, after it completes.

 

I hope this will not use alot of CPU power, since it stats the shell on each delivery. Anyway... I don't know if all this works or does not work. Can you post back the result?

cheers

SteveB

----------

## Ateo

Using that script, this is the error that occurs with *ALL* users, both real system users and virtual:

```
Feb 27 01:53:44 shadow postfix/local[28332]: 66E768FA5: to=<user@domain.tld>, relay=local, delay=0, status=deferred (temporary failure. Command output: /etc/maildroprc(16): Syntax error. )
```

Once I remove the following, system users start getting email again but virtual users still don't:

```
#VERBOSE=9

#logfile="/var/log/maildrop.log"
```

Here's the error one I take out the logging lines, this is the error message which is only happening for virtual users:

```
temporary failure. Command output: /usr/bin/maildrop: Unable to create a dot-lock.
```

Mind you, system users are getting mail at this point again...

----------

## steveb

Okay... I think I made a error. Can you try this:

```
# Global maildrop filter file

#

# For Gentoo Linux by SteveB <tp22a@softhome.net>

#

#

#

# import maildrop specific stuff

#

import SENDER

import RECIPIENT

import HOME

import USER

#

# set path and shell

#

PATH=/bin:/usr/bin:/usr/local/bin

SHELL=/bin/sh

#

# set default and maildir

#

DEFAULT = "$HOME/.maildir"

MAILDIR = "$HOME/.maildir"

#

# create home if not existing

#

`test -d "$HOME" && exit 1 || exit 0`

if($RETURNCODE==0)

{

   `mkdir -p "$HOME" && chown -R vmail:vmail "$HOME" && chmod -R 0700 "$HOME"`

}

#

# create maildir if not existing

#

`test -d "$MAILDIR" && exit 1 || exit 0`

if($RETURNCODE==0)

{

   `maildirmake "$MAILDIR" && chown -R vmail:vmail "$MAILDIR" && chmod -R 0700 "$MAILDIR"`

   #

   # create Sent folder if not existing

   #

   `test -d "$MAILDIR/.Sent" && exit 1 || exit 0`

   if($RETURNCODE==0)

   {

      `maildirmake -f "Sent" "$MAILDIR"`

   }

   #

   # create Drafts folder if not existing

   #

   `test -d "$MAILDIR/.Drafts" && exit 1 || exit 0`

   if($RETURNCODE==0)

   {

      `maildirmake -f "Drafts" "$MAILDIR"`

   }

   #

   # create Trash folder if not existing

   #

   `test -d "$MAILDIR/.Trash" && exit 1 || exit 0`

   if($RETURNCODE==0)

   {

      `maildirmake -f "Trash" "$MAILDIR"`

   }

   #

   # create Junk folder if not existing

   #

   `test -d "$MAILDIR/.Junk" && exit 1 || exit 0`

   if($RETURNCODE==0)

   {

      `maildirmake -f "Junk" "$MAILDIR"`

   }

   #

   # ensure rights on maildir

   #

   `chown -R vmail:vmail "$MAILDIR" && chmod -R 0700 "$MAILDIR"`

}
```

cheers

SteveB

----------

## Ateo

Still failing. It's as if when maildrop is called, it doesn't run as user vmail but I'm probably wrong. Here's my log:

```
Feb 27 08:53:03 shadow postfix/pipe[1657]: CAF821D9AC4: to=<user@domain.tld>, relay=maildrop, delay=1, status=deferred (temporary failure. Command output: mkdir: cannot create directory `': No such file or directory maildirmake: Permission denied maildirmake: No such file or directory maildirmake: No such file or directory maildirmake: No such file or directory maildirmake: No such file or directory chown: cannot access `/.maildir': No such file or directory /usr/bin/maildrop: Unable to create a dot-lock. )
```

I'm still curious about this:

```
DEFAULT = "$HOME/.maildir"

MAILDIR = "$HOME/.maildir" 
```

Doesn't this tell the script to make /home/vmail/.maildir and not /home/vmail/path/to/virtual/.maildir/?

Thanks for your help...

[edit]

Changed title of thread

----------

## sf_alpha

Have you create .maildir for your home ?

man 'maildirmake'  for know how ! then put in /etc/skel

I suggest you to have skel for your virtual users also. I have /etc/vmail-skel with some script to

create maildir for virtual user (from database).

----------

## Ateo

 *sf_alpha wrote:*   

> Have you create .maildir for your home ?
> 
> man 'maildirmake'  for know how ! then put in /etc/skel
> 
> I suggest you to have skel for your virtual users also. I have /etc/vmail-skel with some script to
> ...

 

Please note that everything works fine *IF* maildrop is taken out of the picture. So yes, to answer your question, all .maildir directories in question exist in /home/vmail/domain.tld/user/...

```
root@shadow dracco # ls -la /home/vmail/

total 0

drwxr-xr-x  4 vmail vmail 104 Feb 27 10:32 .

drwxr-xr-x  7 root  root  192 Feb 26 18:38 ..

drwx------  9 vmail vmail 216 Feb 27 01:46 .maildir

drwxr-xr-x  3 vmail vmail  72 Feb 27 10:32 domain.tld

root@shadow dracco # ls -la /home/vmail/domain.tld/

total 0

drwxr-xr-x  3 vmail vmail  72 Feb 27 10:32 .

drwxr-xr-x  4 vmail vmail 104 Feb 27 10:32 ..

drwxr-xr-x  3 vmail vmail  72 Feb 27 10:32 juan

root@shadow dracco # ls -la /home/vmail/domain.tld/juan/

total 0

drwxr-xr-x  3 vmail vmail  72 Feb 27 10:32 .

drwxr-xr-x  3 vmail vmail  72 Feb 27 10:32 ..

drwx------  9 vmail vmail 216 Feb 27 10:32 .maildir
```

Notice on my first `ls -la` that there is a .maildir directory there. That is where all email is sent instead of the proper virtual user directory.

What is vmail-skel? Pardon my ignorance.

----------

## steveb

Do you have actually compiled maildrop to use MySQL? Can you please verify that?

cheers

SteveB

----------

## Ateo

Absolutely...

```
root@shadow home # emerge maildrop -pv

These are the packages that I would merge, in order:

Calculating dependencies ...done!

[ebuild   R   ] mail-filter/maildrop-1.7.0.20040907-r1  +berkdb -gdbm -ldap +mysql 0 kB
```

I just want to make sure I'm deciphering maildroprc correctly. Does this file perform the same task as that bash script you wrote for creating mail directories "on the fly"?

----------

## steveb

 *Ateo wrote:*   

> Absolutely...
> 
> ```
> root@shadow home # emerge maildrop -pv
> 
> ...

 

Yes. But it does not do all the MySQL lookups. However... I just changed the maildroprc to be more clear:

```
# Global maildrop filter file

#

# For Gentoo Linux by SteveB <tp22a@softhome.net>

#

#

#

# import maildrop specific stuff

#

import EXTENSION

import RECIPIENT

import SENDER

import HOME

import USER

#

# set path and shell

#

PATH=/bin:/usr/bin:/usr/local/bin

SHELL=/bin/sh

#

# maildrop entry in master.cf:

#    maildrop  unix  -       n       n       -       -       pipe

#      flags=R user=vmail argv=/usr/bin/maildrop -d ${user}@${nexthop} \

#        ${extension} ${recipient} ${user} ${nexthop} ${sender}

#

LOGNAME=tolower("$LOGNAME")

EXTENSION="$1"

RECIPIENT=tolower("$2")

VUSER=tolower("$3")

VHOST=tolower("$4")

SENDER="$5"

#

# get sure some variables have correct value

#

if ("$EXTENSION" ne "")

{

   DELIMITER="+"

}

if (!$SENDER)

{

   SENDER="<>"

}

if ($VHOST eq "")

{

   VHOST="localhost"

}

VHOME="/home/vmail"

DEFAULT="$VHOME/$VHOST/$VUSER/.maildir"

MAILDIR="$DEFAULT"

#

# create user VHOME if not existing

#

`test -d "$VHOME/$VHOST/$VUSER" && exit 1 || exit 0`

if($RETURNCODE==0)

{

   `mkdir -p "$VHOME/$VHOST/$VUSER"`

   `chown -R vmail:vmail "$VHOME"`

   `chmod -R 0700 "$VHOME"`

}

#

# create maildir if not existing

#

`test -d "$MAILDIR" && exit 1 || exit 0`

if($RETURNCODE==0)

{

   `maildirmake "$MAILDIR"`

   `chown -R vmail:vmail "$MAILDIR"`

   `chmod -R 0700 "$MAILDIR"`

   #

   # create Sent folder if not existing

   #

   `test -d "$MAILDIR/.Sent" && exit 1 || exit 0`

   if($RETURNCODE==0)

   {

      `maildirmake -f "Sent" "$MAILDIR"`

   }

   #

   # create Drafts folder if not existing

   #

   `test -d "$MAILDIR/.Drafts" && exit 1 || exit 0`

   if($RETURNCODE==0)

   {

      `maildirmake -f "Drafts" "$MAILDIR"`

   }

   #

   # create Trash folder if not existing

   #

   `test -d "$MAILDIR/.Trash" && exit 1 || exit 0`

   if($RETURNCODE==0)

   {

      `maildirmake -f "Trash" "$MAILDIR"`

   }

   #

   # create Junk folder if not existing

   #

   `test -d "$MAILDIR/.Junk" && exit 1 || exit 0`

   if($RETURNCODE==0)

   {

      `maildirmake -f "Junk" "$MAILDIR"`

   }

   #

   # ensure rights on maildir

   #

   `chown -R vmail:vmail "$MAILDIR"`

   `chmod -R 0700 "$MAILDIR"`

}

#

# deliver to maildir

#

to "$MAILDIR";
```

Can you please test this one? And can you please change the maildrop entry in master.cf to this:

```
maildrop  unix  -       n       n       -       -       pipe

   flags=R user=vmail argv=/usr/bin/maildrop -d ${user}@${nexthop} \

     ${extension} ${recipient} ${user} ${nexthop} ${sender}
```

cheers

SteveB

----------

## Ateo

Well, shit... Here's the log:

To my virtual user:

```
Feb 27 15:16:13 shadow postfix/pipe[20042]: 1F97B4EF59: to=<juan@domain_2.tld>, relay=maildrop, delay=0, status=deferred (temporary failure. Command output: /usr/bin/maildrop: Unable to open mailbox. )
```

To my system user:

```
Feb 27 15:16:14 shadow postfix/local[20048]: DAF58AFBF0: to=<juan@domain_1.tld>, relay=local, delay=1, status=deferred (temporary failure. Command output: mkdir: cannot create directory `/home/vmail/localhost': Permission denied chown: `/home/vmail/domain_2.tld/juan/.maildir/.Junk': Permission denied chown: `/home/vmail/domain_2.tld/juan/.maildir/.Sent': Permission denied chown: `/home/vmail/domain_2.tld/juan/.maildir/.Trash': Permission denied chown: `/home/vmail/domain_2.tld/juan/.maildir/.Drafts': Permission denied chmod: changing permissions of `/home/vmail': Operation not permitted chmod: changing permissions of `/home/vmail/domain_2.tld': Operation not permitted chmod: changing permissions of `/home/vmail/domain_2.tld/juan': Operation not permitted chmod: changing permissions of `/home/vmail/domain_2.tld/juan/.maildir': Operation not permitted chmod: changing permissions of `/home/vmail/domain_2.tld/juan/.maildir/.Junk': Operation not permitted chmod: `/home/vmail/domain_2.tld/juan/.maildir/.Junk': Permission denied chmod: changing permissions of `/home/vmail/domain_2.tld/juan/.maildir/.Sent': Operation not permitted chmod: `/home/vmail/domain_2.tld/juan/.maildir/.Sent': Permission denied chmod: changing permissions of `/home/vmail/domain_2.tld/juan/.maildir/.Trash': Operation not permitted chmod: `/home/vmail/domain_2.tld/juan/.maildir/.Trash': Permission denied chmod: changing permissions of `/home/vmail/domain_2.tld/juan/.maildir/.Drafts': Operation not permitted chmod: `/home/vmail/domain_2.tld/juan/.maildir/.Drafts': Permission denied maildirmake: No such file or directory chown: cannot access `/home/vmail/localhost//.maildir': No such file or directory chmod: cannot access `/home/vmail/localhost//.maildir': No such file or directory maildirmake: No such file or directory maildirmake: No such file or directory maildirmake: No such file or directory maildirmake: No such file or directory chown: cannot access `/home/vmail/localhost//.maildir': No such file or directory chmod: cannot access `/home/vmail
```

I modified master.cf as you ask.

Also, to verify, my homedir and maildir fields are in correct format, yay or nay? Disregard the other cells I've created. They are there for other purposes.

```

user_id | domain_id | email | password | name | uid | gid | homedir | maildir | quota | postfix | user_level | active | created | modified

30 | 10 | juan@domain.tld | ******** | Juan | 70  | 70  | /home/vmail | /domain.tld/juan/.maildir | 1048576000S | y | 1 | 1 | 1109443413 | 1109443413

```

----------

## steveb

Hm! I think you need to change your maildropmysql.cf to have this:

```
maildir_field           CONCAT(homedir,maildir)

homedirectory_field     CONCAT(homedir,maildir)
```

----------

## Ateo

Ok. I'm back tackling this maildrop issue of mine...

In anycase, to recap, if set virtual_transport in main.cf to virtual, everything works. Directories are created on the fly. Life is great.

Now, when I set virtual_transport to maildrop, system users continue to receive mail, but virtual users do not. I currently have a virtual user for which I receive mail for on a daily basis and this works when virtual_transport is set to virtual. So this user does exist as does the maildir to accompany it......

I've re-read this thread a hundred times, trying different things with information available. It comes down to this:

I'm either configuring /etc/maildrop/maildropmysql.cf incorrectly, or /etc/maildroprc isn't doing what it needs to do. For the time being, using the script above, I've made maildroprc short and simple, bypassing any check for user directory:

```
#

# import maildrop specific stuff

#

import EXTENSION

import RECIPIENT

import SENDER

import HOME

import USER

#

# set path and shell

#

PATH=/bin:/usr/bin:/usr/local/bin

SHELL=/bin/sh

#

# maildrop entry in master.cf:

#    maildrop  unix  -       n       n       -       -       pipe

#      flags=R user=vmail argv=/usr/bin/maildrop -d ${user}@${nexthop} \

#        ${extension} ${recipient} ${user} ${nexthop} ${sender}

#

LOGNAME=tolower("$LOGNAME")

EXTENSION="$1"

RECIPIENT=tolower("$2")

VUSER=tolower("$3")

VHOST=tolower("$4")

SENDER="$5"

#

# get sure some variables have correct value

#

if ("$EXTENSION" ne "")

{

   DELIMITER="+"

}

if (!$SENDER)

{

   SENDER="<>"

}

if ($VHOST eq "")

{

   VHOST="localhost"

}

VHOME="/home/vmail"

DEFAULT="$VHOME/$VHOST/$VUSER/.maildir"

MAILDIR="$DEFAULT"

#

# deliver to maildir

#

to "$MAILDIR";

```

Unless, I've copied and pasted wrong, the above should be able to deliver the mail.

This is the postfix error:

 *Quote:*   

> temporary failure. Command output: /usr/bin/maildrop: Unable to change to home directory.

 

I should also add that maildrop does forward mail for system users just fine.

For something that seems very straight forward, this becoming a big headache. What am I doing wrong?

----------

## Ateo

I found out why my virtual users were not receiving mail via maildrop. One of my *.cf files was producing errors which in turn prevented maildrop from delivering mail to virtual users. My bad line was in main.cf:

```
virtual_maildir_limit_message = mysql:/etc/postfix/maps/mysql-quota-message.cf
```

Once I corrected that, it began to work.

I'm somewhat annoyed that I didn't see any error logs pointing me to even look at that. I decided, on a whim, to start commenting out stuff out of main.cf until maildrop started delivering mail for virt users.

Now to create filters, etc.

Thanks for you help Steve!

----------

## steveb

WOW! Now it works  :Wink: 

cheers

SteveB

----------

## Ateo

 :Exclamation:  Well, actually. It does and it doesn't.  :Exclamation: 

To start off, thanks for the script. I usually figure scripts out when I have something to work with. There's a couple of things I had to do to get it to work for both system and virtual users. Mind you, this only applies to me.

If your script is used, as is, maildrop delivers mail for virtual users but not system users. This probably has to to with the end result of to $MAILDIR and since it would be appending virtual domain info, it fails delivery. I get the following error for system users:

```
temporary failure. Command output: /usr/bin/maildrop: Unable to create a dot-lock.
```

This error seems to be consistent with when .maildir does not exist.

Anyways.

What I did (and I don't know if this is just a band-aid) is encapsulate your script, from the line starting if ("$EXTENSION" ne "")  to the end, into an if statement. It'll run the code if $HOST != $DEFAULT_DOMAIN. $DEFAULT_DOMAIN I declared at the top of the script assigning it my system domain name.

Doing that, maildrop delivers mail for both system and virtual users.

Now, the issue. I create a virtual user. Enter all the info into the mysql table. Send a test mail. No delivery. It doesn't create the directories. I get the same error as above and the message never leaves postfix's queue.

Also, in going over your script, i modified it to make use of a for loop to make .Sent, .Trash, etc... Here it is:

```
#

# import maildrop specific stuff

#

import EXTENSION

import RECIPIENT

import SENDER

import HOME

import USER

#

# set path and shell

#

PATH=/bin:/usr/bin:/usr/local/bin

SHELL=/bin/sh

DEFAULT_DOMAIN="mydomain.tld"

LOGNAME=tolower("$LOGNAME")

EXTENSION="$1"

RECIPIENT=tolower("$2")

VUSER=tolower("$3")

VHOST=tolower("$4")

SENDER="$5"

if ( $VHOST ne $DEFAULT_DOMAIN )

{

  #

  # get sure some variables have correct value

  #

  if ("$EXTENSION" != "")

  {

     DELIMITER="+"

  }

  if (!$SENDER)

  {

     SENDER="<>"

  }

  if ($VHOST == "")

  {

     VHOST="bunk"

  }

  VHOME="/home/vmail"

  DEFAULT="$VHOME/$VHOST/$VUSER/.maildir"

  MAILDIR="$DEFAULT"

  #

  # create user home if not exist

  #

  `test -d "$VHOME/$VHOST/$VUSER" && exit 1 || exit 0`

  if ( $RETURNCODE == 0 )

  {

    `mkdir -p "$VHOME/$VHOST/$VUSER"`

    `chown -R vmail:vmail "$VHOME"`

    `chmod -R 0700 "$VHOME"`

  }

  #

  # create user maildir if not exist

  #

  `test -d "$MAILDIR" && exit 1 || exit 0`

  if ( $RETURNCODE == 0 )

  {

    `maildirmake "$MAILDIR"`

    `chown -R vmail:vmail "$MAILDIR"`

    `chmod -R 0700 "$MAILDIR"`

    #

    # create user Sent, Draft, Trash, Junk

    # folders if not exit

    #

    for new_folder in Sent Drafts Trash Junk Spam

    do

      `test -d "$MAILDIR/.$new_folder" && exit 1 || exit 0`

      if ( $RETURNCODE == 0 )

      {

        `maildirmake -f "$new_folder" "$MAILDIR"`

      }

    done

    #

    # ensure rights on maildir

    #

    `chown -R vmail:vmail "$MAILDIR"`

    `chmod -R 0700 "$MAILDIR"`

  }

  #

  # deliver to maildir

  #

  to "$MAILDIR";

}
```

Ironically, I can't ensure it works because, well, it doesn't create the initial user directory. But I'm sure it does as for loops are pretty much the same in any language. Note that I changed all operators to non-alpha characters. For some reason, it doesn't work for me with "ne" or "eq".

[edit]

I don't think this script is interpreting bash commands. I added `echo "test" > /tmp/tmp.log` and nothing is written. /tmp is world writeable. I added the line after declaring path and shell.

----------

## steveb

I am in no way a maildrop specialist. I only did the stuff for you and read over the various documentation available on the net. One thing which I noticed while reading http://www.courier-mta.org/maildrop/?maildropfilter.html is, that your loop for creating the differend folders will not work. It would work in bash, but not in maildrop.

Anyway... I did not noticed that you need that for local users as well. If I would know that before, then I would probably write some stuff differend. Maybe something like this is suitable for both local and virtual users:

```
#

# import maildrop specific stuff

#

import EXTENSION

import RECIPIENT

import SENDER

import HOME

import USER

#

# set path and shell

#

PATH="/bin:/usr/bin:/usr/local/bin"

SHELL="/bin/sh"

#

# get sure some variables have correct value

# or empty values

#

LOGNAME=tolower("$LOGNAME")

EXTENSION="$1"

RECIPIENT=tolower("$2")

VUSER=tolower("$3")

VHOST=tolower("$4")

SENDER="$5"

DEFAULT=""

MAILDIR=""

VHOME="/home/vmail"

USERTYPE=""

if ("$EXTENSION" != "")

{

   DELIMITER="+"

}

if (!$SENDER)

{

   SENDER="<>"

}

if ($VHOST == "")

{

   VHOST="mydomain.tld"

}

#

# check if this is a local user to who we are delivering

#

`grep -iq "^$LOGNAME:" /etc/passwd && echo 1 || echo 0`

if ($RETURNCODE == 1)

{

   # local user

   DEFAULT="$HOME/.maildir"

   MAILDIR="$DEFAULT"

   USERTYPE="L"

}

else

{

   # virtual user

   #

   # create virtual user home if not exist

   #

   `test -d "$VHOME/$VHOST" && exit 1 || exit 0`

   if ($RETURNCODE == 0)

   {

      `mkdir -p "$VHOME/$VHOST"`

      `chown vmail:vmail "$VHOME/$VHOST"`

      `chmod 0700 "$VHOME/$VHOST"`

   }

   `test -d "$VHOME/$VHOST/$VUSER" && exit 1 || exit 0`

   if ($RETURNCODE == 0)

   {

      `mkdir -p "$VHOME/$VHOST/$VUSER"`

      `chown vmail:vmail "$VHOME/$VHOST/$VUSER"`

      `chmod 0700 "$VHOME/$VHOST/$VUSER"`

   }

   `test -d "$VHOME/$VHOST/$VUSER" && exit 1 || exit 0`

   if ($RETURNCODE == 1)

   {

      DEFAULT="$VHOME/$VHOST/$VUSER/.maildir"

      MAILDIR="$DEFAULT"

      USERTYPE="V"

   }

}

if ($MAILDIR ne "")

{

   #

   # create user maildir if not exist

   #

   `test -d "$MAILDIR" && exit 1 || exit 0`

   if ($RETURNCODE == 0)

   {

      `maildirmake "$MAILDIR"`

      if (USERTYPE eq "V")

      {

         `chown -R vmail:vmail "$MAILDIR"`

      }

      else

      {

         `chown -R $LOGNAME:users "$MAILDIR"`

      }

      `chmod -R 0700 "$MAILDIR"`

   }

   #

   # create Sent folder if not existing

   #

   `test -d "$MAILDIR/.Sent" && exit 1 || exit 0`

   if($RETURNCODE==0)

   {

      `maildirmake -f "Sent" "$MAILDIR"`

      if (USERTYPE eq "V")

      {

         `chown -R vmail:vmail "$MAILDIR/.Sent"`

      }

      else

      {

         `chown -R $LOGNAME:users "$MAILDIR/.Sent"`

      }

      `chmod -R 0700 "$MAILDIR/.Sent"`

   }

   #

   # create Drafts folder if not existing

   #

   `test -d "$MAILDIR/.Drafts" && exit 1 || exit 0`

   if($RETURNCODE==0)

   {

      `maildirmake -f "Drafts" "$MAILDIR"`

      if (USERTYPE eq "V")

      {

         `chown -R vmail:vmail "$MAILDIR/.Drafts"`

      }

      else

      {

         `chown -R $LOGNAME:users "$MAILDIR/.Drafts"`

      }

      `chmod -R 0700 "$MAILDIR/.Drafts"`

   }

   #

   # create Trash folder if not existing

   #

   `test -d "$MAILDIR/.Trash" && exit 1 || exit 0`

   if($RETURNCODE==0)

   {

      `maildirmake -f "Trash" "$MAILDIR"`

      if (USERTYPE eq "V")

      {

         `chown -R vmail:vmail "$MAILDIR/.Trash"`

      }

      else

      {

         `chown -R $LOGNAME:users "$MAILDIR/.Trash"`

      }

      `chmod -R 0700 "$MAILDIR/.Trash"`

   }

   #

   # create Junk folder if not existing

   #

   `test -d "$MAILDIR/.Junk" && exit 1 || exit 0`

   if($RETURNCODE==0)

   {

      `maildirmake -f "Junk" "$MAILDIR"`

      if (USERTYPE eq "V")

      {

         `chown -R vmail:vmail "$MAILDIR/.Junk"`

      }

      else

      {

         `chown -R $LOGNAME:users "$MAILDIR/.Junk"`

      }

      `chmod -R 0700 "$MAILDIR/.Junk"`

   }

   #

   # deliver to maildir

   #

   to "$MAILDIR";

}
```

Hmm.... this is fun. I learn so much by trying to help others on the forum. I hope this maildrop works now for you? Would be nice to know if it works.

cheers

SteveB

----------

## Ateo

For whatever reason, maildrop is not interpreting any bash. Example:

```
`grep -iq "^$LOGNAME:" /etc/passwd && echo 1 || echo 0`

if ($RETURNCODE == 1)

{

   # local user

   DEFAULT="$HOME/.maildir"

   MAILDIR="$DEFAULT"

   USERTYPE="L"

} 
```

This should return a "1" when parsing for local users. It doesn't. It returns a 0 and gives me the "Unable to create a dot-lock" error. I tried your other way of executing code encapulating the command in $() but as you probably know, that does not work.

As of right now, this is the only script that works (not including filtering code as I have no attempted that yet):

```
#

# import maildrop specific stuff

#

import EXTENSION

import RECIPIENT

import SENDER

import HOME

import USER

#

# set path and shell

#

PATH=/bin:/usr/bin:/usr/local/bin

SHELL=/bin/sh

DEFAULT_DOMAIN="domain.tld"

#

# Declared variables from inport

#

LOGNAME=tolower("$LOGNAME")

EXTENSION="$1"

RECIPIENT=tolower("$2")

VUSER=tolower("$3")

VHOST=tolower("$4")

SENDER="$5"

#

# get sure some variables have correct value

#

if ( $EXTENSION != "" )

{

   DELIMITER="+"

}

if ( !$SENDER )

{

   SENDER="<>"

}

if ( $VHOST != $DEFAULT_DOMAIN )

{

  VHOME="/home/vmail"

  DEFAULT="$VHOME/$VHOST/$VUSER/.maildir"

  MAILDIR="$DEFAULT"

  #

  # deliver to maildir

  #

  to "$MAILDIR";

}
```

Oh yea. You're right about the loop. I figured I'd give it a try since the document said it's "like" perl but not at the same time.

Also, correct me if I'm wrong, but your script also attempts to create maildir for system users. I don't think that'll work since maildrop runs as user vmail and will run into permission issues...

WTF. Hmm.

[edit]

Renamed thread title... again.

----------

## steveb

I think if you have disabled the shell for vmail, then it will not be able to use the shell. Could you post the output of:

```
grep ^vmail /etc/passwd
```

If the last parameter is /bin/false or something which prevents vmail using a shell, then I don't belive that you could use the shell in maildrop.

Yes. You are right about the attempt to create maildir for local users. I did not think about the permission problem of creating accounts for users.

cheers

SteveB

----------

## Ateo

That was it. I didn't remember that when I created the vmail user, i assigned /bin/false as the shell.

Again, thanks for all the help.

----------

## steveb

 *Ateo wrote:*   

> That was it. I didn't remember that when I created the vmail user, i assigned /bin/false as the shell.
> 
> Again, thanks for all the help.

 If you followed the guide, then you just typed what they told you to do so (aka using /bin/false):

http://www.gentoo.org/doc/en/virt-mail-howto.xml#doc_chap9

But I am happy, that it worked for you  :Smile: 

FINALY!

cheers

SteveB

----------

## Ateo

Just a note to anyone that might come across this thread in search of help....

When setting the following in main.cf and pointing them to a *.cf file, I found that it did not work if I add them as typed below:

```
virtual_gid_maps = static:mysql:/etc/postfix/maps/mysql-gid.cf

virtual_uid_maps = static:mysql:/etc/postfix/maps/mysql-uid.cf
```

What worked for me was removing static::

```
virtual_gid_maps = mysql:/etc/postfix/maps/mysql-gid.cf

virtual_uid_maps = mysql:/etc/postfix/maps/mysql-uid.cf
```

If you do not want to use a *.cf file, then you need static::

```
virtual_gid_maps = static:5000

virtual_uid_maps = static:5000
```

Anyways, it works well.

----------

## Ateo

Well, dammit. I was wrong about the script working. It still does not execute bash command. My user is now set up correctly:

```
 # grep vmail /etc/passwd

vmail:x:5000:5000::/home/vmail:/bin/bash
```

Simple code as this does not execute:

```
if ( $VHOST != $DDOMAIN )

{

  echo "$VHOST" >> /tmp/tmp.log

}
```

DDOMAIN is declared earlier.

In the end, it does deliver mail to all users that already have maildir set up but it does not create maildir on the fly. Any ideas?

Oh yea. In the script, I changed the shell to bash until I get this working....

----------

## steveb

 *Ateo wrote:*   

> Well, dammit. I was wrong about the script working. It still does not execute bash command. My user is now set up correctly:
> 
> ```
>  # grep vmail /etc/passwd
> 
> ...

 

SHIT! Maybe a limitation of the maildrop environment? Could you try to run the filter with debug loging active or use log statements to see if it jumps into the if statement?

cheers

SteveB

----------

## Ateo

I just don't understand what is going on. The script works with sending mail to virtual users so I KNOW that it tries to execute whatever it can inside the if statement. However, If i turn logging on and I place the log statement inside the if statement, flush my queue (a message to a virtual user), it should execute whatever is in the if statement but it doesn't. Nothing is written to the logfile.

If I put the log statement before the if statement, it does log whatever expression "log" is set to. Funny thing is, all the maildrop documentation says it can execute shell commands (which you already know) so I'm somewhat confused.

blah.

Also, VERBOSE does not log anything if in delivery mode or so says the doc...

----------

## steveb

 *Ateo wrote:*   

> I just don't understand what is going on. The script works with sending mail to virtual users so I KNOW that it tries to execute whatever it can inside the if statement. However, If i turn logging on and I place the log statement inside the if statement, flush my queue (a message to a virtual user), it should execute whatever is in the if statement but it doesn't. Nothing is written to the logfile.
> 
> If I put the log statement before the if statement, it does log whatever expression "log" is set to. Funny thing is, all the maildrop documentation says it can execute shell commands (which you already know) so I'm somewhat confused.
> 
> blah.
> ...

 

Maybe the problem is th entry in main.cf:

```
maildrop  unix  -       n       n       -       -       pipe

  flags=DORhu user=vmail argv=/usr/bin/maildrop -d ${user}@${nexthop} ${extension} ${recipient} ${user} ${nexthop}
```

executing as user vmail does probably not allow you to write any file in the users home directory. Could that be the problem?

cheers

SteveB

----------

## Ateo

I've seen various flags for that syntax in master.cf. The "D" flag (supposedly) cannot be used since it's reserved for the version of maildrop that comes with courier. However, I searched for maildrop after installing courier and didn't find so I installed the stand alone version. No biggie.

What do the ORhu flags tell it to do? Those flags don't seem to be documented here.. In fact, what does the "R" tell it to do?

Interesting though. Even with the "D" flag, I still get mail. Probably good news...

Anyways, I'm beat. I'll play around with maildrop in the morning..

----------

## steveb

Since you are piping to maildrop from Postfix, you need to look at the pipe syntax. They are documented there.

cheers

SteveB

----------

## steveb

maybe readind this helps:

http://www.postfix.org/MAILDROP_README.html

----------

## Ateo

I've read over that link from your last post. That's actually what got me started. However, that pipe link is very helpful. I was looking in the wrong place for info on those flags...

Damn. Ok. NOW it's quitting time.

----------

## Ateo

Ok. So like I stated last night. I've added the flags above, still get mail but the weirdness continues...

Here's the script (again):

```

# import maildrop specific stuff

#

import EXTENSION

import RECIPIENT

import SENDER

import HOME

import USER

#

# set path and shell

#

PATH=/bin:/usr/bin:/usr/local/bin

SHELL=/bin/bash

DDOMAIN=domain.tld

#

# Declared variables from inport

#

LOGNAME=tolower("$LOGNAME")

EXTENSION="$1"

RECIPIENT=tolower("$2")

VUSER=tolower("$3")

VHOST=tolower("$4")

SENDER="$5"

# Statement 1

`echo "Tard" >> /home/vmail/maildrop.log`

#

# get sure some variables have correct value

#

if ( $EXTENSION != "" )

{

   DELIMITER="+"

}

if ( !$SENDER )

{

   SENDER="<>"

}

if ( $VHOST != $DDOMAIN )

{

  VHOME="/home/vmail"

  DEFAULT="$VHOME/$VHOST/$VUSER/.maildir"

  MAILDIR="$DEFAULT"

  # Statement 2

  `echo "$MAILDIR" >> /home/vmail/maildrop.log`

  #

  # Create host directory, if not exist

  #

  `test -d "$VHOME/$VHOST" && echo 1 || echo 0`

  if ( $RETURNCODE == 0 )

  {

    `mkdir -p "$VHOME/$VHOST"`

  }

  #

  # Create user maildir, if not exist

  #

  `test -d "$MAILDIR" && echo 1 || echo 0`

  if ( $RETURNCODE == 0 )

  {

    `maildirmake "$MAILDIR"`

  }

  #

  # Create .Sent directory, if not exist

  #

  `test -d "$MAILDIR/.Sent" && echo 1 || echo 0`

  if ( $RETURNCODE == 0 )

  {

    `maildirmake -f "Sent" "$MAILDIR"`

  }

  #

  # Create .Trash directory, if not exist

  #

  `test -d "$MAILDIR/.Trash" && echo 1 || echo 0`

  if ( $RETURNCODE == 0 )

  {

    `maildirmake -f "Trash" "$MAILDIR"`

  }

  #

  # Create .Drafts directory, if not exist

  #

  `test -d "$MAILDIR/.Drafts" && echo 1 || echo 0`

  if ( $RETURNCODE == 0 )

  {

    `maildirmake -f "Drafts" "$MAILDIR"`

  }

  #

  # Create .Junk directory, if not exist

  #

  `test -d "$MAILDIR/.Junk" && echo 1 || echo 0`

  if ( $RETURNCODE == 0 )

  {

    `maildirmake -f "Junk" "$MAILDIR"`

  }

  #

  # Set proper permissions

  #

  `chown -R vmail:vmail "$VHOME/$VHOST"`

  `chmod -R 0700 "$VHOME/$VHOST"`

  #

  # deliver to maildir

  #

  to "$MAILDIR";

}
```

I've added 2 simple echo statements to write to a log in /home/vmail.. Then I sent a test message to my virtual user. The first echo statement does work. It writes "Tard" to the file /home/vmail/maildrop.log. However, it doesn't write anything when the echo statement is inside the if statement. The weird thing is, the if statement is, in fact, parsed as the incoming message goes to a virutal users NOT on DDOMAIN....

Maybe the maildrop gods just don't like me. hehe. I'm stumped. According to the docs, this *should* work.

I suppose if worse comes to worse, I'll just use php to execute a bash script to create new folder for new users.

----------

## justanothergentoofanatic

I think that will randomly fail due to concurrent writes to the same file. Why can't you use maildrop's 'logfile' and 'log' commands?

If you turn on maildrop's logging (-Vn), you can find out why the echo after the if statement isn't being executed.

-Mike

----------

## Ateo

 *justanothergentoofanatic wrote:*   

> I think that will randomly fail due to concurrent writes to the same file. Why can't you use maildrop's 'logfile' and 'log' commands?
> 
> If you turn on maildrop's logging (-Vn), you can find out why the echo after the if statement isn't being executed.
> 
> -Mike

 

I did try the logfile and log commands. Same thing happens that command as happens with the echo command. However, I didn't try it with -Vn. I'll give that a try.

Thanks

----------

## Ateo

Well, I ended up taking a different approach. Since maildrop wasn't able to execute bash from maildroprc (for whatever reason), I opted for executing a perl script from within a php application I made for administering my email accounts (I wrote a webtool). 

Anyways, thanks for your help steveb. Even though "you're no maildrop" expert (as you claimed) you still helped a great deal.

----------

## Ateo

I forget to post what solved my problem. When I declarce my path and shell, I did not have the value wrapped in double quotes. 

```
SHELL="/bin/ash"

PATH="/bin:/usr/bin:etc"
```

----------

