[Dovecot] Calling dovecot-lda from within Antispam pipe script (bash) seems to have no effect
Hello,
I'm attempting to configure the Dovecot Antispam plug-in on Ubuntu 12.04 LTS with Dovecot 2.0.19.
Everything seems to be in order with one considerable exception: when my pipe script (a simple Bash shell script) calls the dovecot-lda executable, absolutely nothing seems to result.
If I copy/paste the exact same command into the terminal, the mail is delivered to the target mailbox, as expected.
Here's my pipe script: http://pastebin.com/DBXAZqsN
When I move a message from INBOX -> Junk, or from Junk -> INBOX, the pipe script is called, and here's the output:
31465-start (--debug --username=amavis --ham) Checking if the command-line input argument string (--debug --username=amavis --ham) contains the string "ham" or "spam" Mode is "HAM" Calling (as user vmail) '/usr/lib/dovecot/deliver -d "sa-training@example.com" -m "Training.HAM" -p "/tmp/sendmail-msg-31465.txt"' 31465-end
But, for some reason, the call to "/usr/lib/dovecot/deliver" doesn't seem to do anything.
If I copy the above output and paste it into the terminal:
/usr/lib/dovecot/deliver -d "sa-training@example.com" -m "Training.HAM" -p "/tmp/sendmail-msg-31465.txt"
Dovecot does indeed deliver the message. This works whether I execute the above command as "root" or "vmail".
Why does this command have no effect when called from within the pipe script?
Here is my "doveconf -n" output:
# 2.0.19: /etc/dovecot/dovecot.conf # OS: Linux 2.6.32-042stab076.8 x86_64 Ubuntu 12.04.2 LTS auth_mechanisms = plain login disable_plaintext_auth = no listen = *,[::] log_timestamp = "%Y-%m-%d %H:%M:%S " mail_privileged_group = vmail passdb { args = /etc/dovecot/dovecot-sql.conf driver = sql } plugin { antispam_backend = pipe antispam_debug_target = syslog antispam_pipe_program = /usr/bin/sa-learn-pipe.sh antispam_pipe_program_args = --debug;--username=amavis antispam_pipe_program_notspam_arg = --ham antispam_pipe_program_spam_arg = --spam antispam_pipe_tmpdir = /tmp antispam_spam_pattern_ignorecase = SPAM;JUNK antispam_trash_pattern_ignorecase = trash;Deleted * antispam_verbose_debug = 1 quota = dict:user::file:/var/vmail/%d/%n/.quotausage quota_rule2 = Trash:storage=+100M quota_rule3 = Junk:ignore quota_warning = storage=95%% quota-warning 95 %u %d quota_warning2 = storage=80%% quota-warning 80 %u %d quota_warning3 = -storage=100%% quota-below below %u %d sieve = /var/vmail/%d/%n/.sieve } protocols = imap pop3 service auth { unix_listener /var/spool/postfix/private/auth { group = postfix mode = 0660 user = postfix } unix_listener auth-userdb { group = vmail mode = 0600 user = vmail } user = root } service quota-below { executable = script /usr/local/bin/quota-below.sh user = vmail } service quota-warning { executable = script /usr/local/bin/quota-warning.sh user = vmail } ssl_cert =
Thank you,
-Ben
Hi Ben,
I checked over your script, and I don't see the problem either. You already checked everything that comes to my mind.
Maybe using something like set -e to try and get some output from the script?
--
Computerisms
Bob Miller
867-334-7117 / 867-633-3760
http://computerisms.ca
On Wed, 2013-06-19 at 14:52 -0400, Ben Johnson wrote:
Hello,
I'm attempting to configure the Dovecot Antispam plug-in on Ubuntu 12.04 LTS with Dovecot 2.0.19.
Everything seems to be in order with one considerable exception: when my pipe script (a simple Bash shell script) calls the dovecot-lda executable, absolutely nothing seems to result.
If I copy/paste the exact same command into the terminal, the mail is delivered to the target mailbox, as expected.
Here's my pipe script: http://pastebin.com/DBXAZqsN
When I move a message from INBOX -> Junk, or from Junk -> INBOX, the pipe script is called, and here's the output:
31465-start (--debug --username=amavis --ham) Checking if the command-line input argument string (--debug --username=amavis --ham) contains the string "ham" or "spam" Mode is "HAM" Calling (as user vmail) '/usr/lib/dovecot/deliver -d "sa-training@example.com" -m "Training.HAM" -p "/tmp/sendmail-msg-31465.txt"' 31465-end
But, for some reason, the call to "/usr/lib/dovecot/deliver" doesn't seem to do anything.
If I copy the above output and paste it into the terminal:
/usr/lib/dovecot/deliver -d "sa-training@example.com" -m "Training.HAM" -p "/tmp/sendmail-msg-31465.txt"
Dovecot does indeed deliver the message. This works whether I execute the above command as "root" or "vmail".
Why does this command have no effect when called from within the pipe script?
Here is my "doveconf -n" output:
# 2.0.19: /etc/dovecot/dovecot.conf # OS: Linux 2.6.32-042stab076.8 x86_64 Ubuntu 12.04.2 LTS auth_mechanisms = plain login disable_plaintext_auth = no listen = *,[::] log_timestamp = "%Y-%m-%d %H:%M:%S " mail_privileged_group = vmail passdb { args = /etc/dovecot/dovecot-sql.conf driver = sql } plugin { antispam_backend = pipe antispam_debug_target = syslog antispam_pipe_program = /usr/bin/sa-learn-pipe.sh antispam_pipe_program_args = --debug;--username=amavis antispam_pipe_program_notspam_arg = --ham antispam_pipe_program_spam_arg = --spam antispam_pipe_tmpdir = /tmp antispam_spam_pattern_ignorecase = SPAM;JUNK antispam_trash_pattern_ignorecase = trash;Deleted * antispam_verbose_debug = 1 quota = dict:user::file:/var/vmail/%d/%n/.quotausage quota_rule2 = Trash:storage=+100M quota_rule3 = Junk:ignore quota_warning = storage=95%% quota-warning 95 %u %d quota_warning2 = storage=80%% quota-warning 80 %u %d quota_warning3 = -storage=100%% quota-below below %u %d sieve = /var/vmail/%d/%n/.sieve } protocols = imap pop3 service auth { unix_listener /var/spool/postfix/private/auth { group = postfix mode = 0660 user = postfix } unix_listener auth-userdb { group = vmail mode = 0600 user = vmail } user = root } service quota-below { executable = script /usr/local/bin/quota-below.sh user = vmail } service quota-warning { executable = script /usr/local/bin/quota-warning.sh user = vmail } ssl_cert =
Thank you,
-Ben
On 6/20/2013 12:14 AM, Bob Miller wrote:
Hi Ben,
I checked over your script, and I don't see the problem either. You already checked everything that comes to my mind.
Maybe using something like set -e to try and get some output from the script?
Adding the -e switch doesn't seem to produce any output, either.
But I did think to try echo-ing $? after calling dovecot-lda, which dumps the program's exit status code. The code is 75, which, according to the manual at http://wiki.dovecot.org/LDA , means the following:
75 (EX_TEMPFAIL): A temporary failure. This is returned for almost all failures. See the log file for details.
Well, I checked the log files and there's absolutely nothing written when my script is executed and yields exit code 75. (But other failures are indeed written to the same log file, such as when the message can't be delivered due to over-quota.)
As noted earlier in my doveconf -n output, I added explicit log paths for LDA:
protocol lda { mail_plugins = sieve quota log_path = /var/log/dovecot-lda-errors.log info_log_path = /var/log/dovecot-lda.log }
These are the logs that I am checking, which are devoid of messages relating to this script.
Also, nothing is written to /var/log/mail.log.
The only logging that I am able to discern is to /var/log/syslog:
Jun 20 09:59:33 host imap: antispam: mailbox_is_unsure(Junk): 0 Jun 20 09:59:33 host imap: antispam: mailbox_is_trash(INBOX): 0 Jun 20 09:59:33 host imap: antispam: mailbox_is_trash(Junk): 0 Jun 20 09:59:33 host imap: antispam: mail copy: from trash: 0, to trash: 0 Jun 20 09:59:33 host imap: antispam: mailbox_is_spam(INBOX): 0 Jun 20 09:59:33 host imap: antispam: mailbox_is_spam(Junk): 1 Jun 20 09:59:33 host imap: antispam: mailbox_is_unsure(INBOX): 0 Jun 20 09:59:33 host imap: antispam: mail copy: src spam: 0, dst spam: 1, src unsure: 0 Jun 20 09:59:33 host imap: antispam: running mailtrain backend program /usr/bin/sa-learn-pipe.sh Jun 20 09:59:33 host imap: antispam: running mailtrain backend program /usr/bin/sa-learn-pipe.sh Jun 20 09:59:33 host imap: antispam: running mailtrain backend program parameter 1 --debug Jun 20 09:59:33 host imap: antispam: running mailtrain backend program parameter 2 --username=amavis Jun 20 09:59:33 host imap: antispam: running mailtrain backend program parameter 3 --spam
I'm not sure what to try next...
Thanks for the help,
-Ben
It really boils-down to the fact that I can call the following on the command-line and it functions as expected:
su vmail -c '/usr/lib/dovecot/deliver -a "sa-training@example.com" -d "sa-training@example.com" -m "Training.SPAM" -p "/tmp/sendmail-msg-25794.txt"'
Yet, when I attempt to do the exact same thing from within the pipe script that Dovecot Antispam calls, I receive exit code 75 from deliver/dovecot-lda and absolutely nothing is logged, with exception of the information of which I'm already aware (logged to syslog).
I am echo-ing $(whoami) just before calling "deliver" within the pipe script and the output is "vmail". So, it's not as though the vmail user somehow lacks the permissions required to send via dovecot-lda.
What is the explanation for this behavior? It has to be something to do with how the plug-in calls the script. Does the plug-in call the script in some other context, like chroot?
As a final point of note, is it just me, or is the "90-plugin.conf" snippet incorrect at the bottom of http://wiki2.dovecot.org/Plugins/Antispam ? Those values appear to be for the analogous Dovecot 1 plug-in, e.g., "antispam_mail_sendmail" is used, when the equivalent directive is called "antispam_pipe_program" in versions >= 2.0.
-Ben
Hi Ben,
Maybe using something like set -e to try and get some output from the script?
Adding the -e switch doesn't seem to produce any output, either.
To be clear, I meant putting the line:
set -e
near the top of your script. I forget exactly how it functions, but it
makes it so when a script fails it spits out a why on stdout (or maybe
stderr). I believe the -x argument does something useful for
troubleshooting too, but it's been too long. man bash
knows all...
It really boils-down to the fact that I can call the following on the command-line and it functions as expected:
su vmail -c '/usr/lib/dovecot/deliver -a "sa-training@example.com" -d "sa-training@example.com" -m "Training.SPAM" -p "/tmp/sendmail-msg-25794.txt"'
Yet, when I attempt to do the exact same thing from within the pipe script that Dovecot Antispam calls, I receive exit code 75 from deliver/dovecot-lda and absolutely nothing is logged, with exception of the information of which I'm already aware (logged to syslog).
I am echo-ing $(whoami) just before calling "deliver" within the pipe script and the output is "vmail". So, it's not as though the vmail user somehow lacks the permissions required to send via dovecot-lda.
There are two things that came to mind when I read your mail yesterday. They are the first things I check for when my commands work and my scripts don't.
The first is $PATH, I have found innumerable times when a script
wouldn't run it was because it wasn't running with a fully loaded $PATH
variable, and this is especially true if you are launching your script
from cron. To work around this I either put a PATH= at the top of the
script, or I run the script as an argument to bash instead of using the
executable bit (ie bash /path/to/script.sh
instead of ./script.sh
)
so the path is retained from the shell. I decided against mentioning
this yesterday because I noted you only used full paths in your script,
which should also work to avoid this problem.
The other thing I didn't mention was the permissions on the path to /usr/lib/dovecot/deliver (or any other path, really). Directories with no world read/execute can prevent scripts from using files beneath them if they don't have permissions on each directory level in the path. I didn't mention this yesterday because you said you ran the script as vmail. However, looking at your "su vmail -c" command, I remember some times when "su postrgres -c" didn't work when "su - postrgres" then running the command did.
Probably neither of these will be useful to you, but I mention them in hope that they trigger and idea or set you on an investigative path that proves helpful...
What is the explanation for this behavior? It has to be something to do with how the plug-in calls the script. Does the plug-in call the script in some other context, like chroot?
As a final point of note, is it just me, or is the "90-plugin.conf" snippet incorrect at the bottom of http://wiki2.dovecot.org/Plugins/Antispam ? Those values appear to be for the analogous Dovecot 1 plug-in, e.g., "antispam_mail_sendmail" is used, when the equivalent directive is called "antispam_pipe_program" in versions >= 2.0.
-Ben
I got another quick idea, too; try running dovecot in the foreground. Maybe something that isn't being written to the log will show up on the terminal...
--
Computerisms
Bob Miller
867-334-7117 / 867-633-3760
http://computerisms.ca
On Thu, 2013-06-20 at 19:00 -0700, Bob Miller wrote:
Hi Ben,
Maybe using something like set -e to try and get some output from the script?
Adding the -e switch doesn't seem to produce any output, either.
To be clear, I meant putting the line:
set -e
near the top of your script. I forget exactly how it functions, but it makes it so when a script fails it spits out a why on stdout (or maybe stderr). I believe the -x argument does something useful for troubleshooting too, but it's been too long.
man bash
knows all...It really boils-down to the fact that I can call the following on the command-line and it functions as expected:
su vmail -c '/usr/lib/dovecot/deliver -a "sa-training@example.com" -d "sa-training@example.com" -m "Training.SPAM" -p "/tmp/sendmail-msg-25794.txt"'
Yet, when I attempt to do the exact same thing from within the pipe script that Dovecot Antispam calls, I receive exit code 75 from deliver/dovecot-lda and absolutely nothing is logged, with exception of the information of which I'm already aware (logged to syslog).
I am echo-ing $(whoami) just before calling "deliver" within the pipe script and the output is "vmail". So, it's not as though the vmail user somehow lacks the permissions required to send via dovecot-lda.
There are two things that came to mind when I read your mail yesterday. They are the first things I check for when my commands work and my scripts don't.
The first is $PATH, I have found innumerable times when a script wouldn't run it was because it wasn't running with a fully loaded $PATH variable, and this is especially true if you are launching your script from cron. To work around this I either put a PATH= at the top of the script, or I run the script as an argument to bash instead of using the executable bit (ie
bash /path/to/script.sh
instead of./script.sh
) so the path is retained from the shell. I decided against mentioning this yesterday because I noted you only used full paths in your script, which should also work to avoid this problem.The other thing I didn't mention was the permissions on the path to /usr/lib/dovecot/deliver (or any other path, really). Directories with no world read/execute can prevent scripts from using files beneath them if they don't have permissions on each directory level in the path. I didn't mention this yesterday because you said you ran the script as vmail. However, looking at your "su vmail -c" command, I remember some times when "su postrgres -c" didn't work when "su - postrgres" then running the command did.
Probably neither of these will be useful to you, but I mention them in hope that they trigger and idea or set you on an investigative path that proves helpful...
What is the explanation for this behavior? It has to be something to do with how the plug-in calls the script. Does the plug-in call the script in some other context, like chroot?
As a final point of note, is it just me, or is the "90-plugin.conf" snippet incorrect at the bottom of http://wiki2.dovecot.org/Plugins/Antispam ? Those values appear to be for the analogous Dovecot 1 plug-in, e.g., "antispam_mail_sendmail" is used, when the equivalent directive is called "antispam_pipe_program" in versions >= 2.0.
-Ben
On 6/20/2013 10:00 PM, Bob Miller wrote:
Hi Ben,
Maybe using something like set -e to try and get some output from the script?
Adding the -e switch doesn't seem to produce any output, either.
To be clear, I meant putting the line:
set -e
near the top of your script. I forget exactly how it functions, but it makes it so when a script fails it spits out a why on stdout (or maybe stderr). I believe the -x argument does something useful for troubleshooting too, but it's been too long.
man bash
knows all...
Oops! Now I understand what you meant. I tried adding "set -e" at the top of my shell script, but it doesn't shed much light on the problem.
A quick Google search reveals that "set -e causes the shell to exit if any subcommand or pipeline returns a non-zero status." The result is predictable: the call to "deliver" exits with status 75, so using "set -e" causes the script as a whole to return a non-zero exit status, which in turn causes Dovecot to throw an error in my IMAP client: "[SERVERBUG] failed to send mail".
It really boils-down to the fact that I can call the following on the command-line and it functions as expected:
su vmail -c '/usr/lib/dovecot/deliver -a "sa-training@example.com" -d "sa-training@example.com" -m "Training.SPAM" -p "/tmp/sendmail-msg-25794.txt"'
Yet, when I attempt to do the exact same thing from within the pipe script that Dovecot Antispam calls, I receive exit code 75 from deliver/dovecot-lda and absolutely nothing is logged, with exception of the information of which I'm already aware (logged to syslog).
I am echo-ing $(whoami) just before calling "deliver" within the pipe script and the output is "vmail". So, it's not as though the vmail user somehow lacks the permissions required to send via dovecot-lda.
There are two things that came to mind when I read your mail yesterday. They are the first things I check for when my commands work and my scripts don't.
The first is $PATH, I have found innumerable times when a script wouldn't run it was because it wasn't running with a fully loaded $PATH variable, and this is especially true if you are launching your script from cron. To work around this I either put a PATH= at the top of the script, or I run the script as an argument to bash instead of using the executable bit (ie
bash /path/to/script.sh
instead of./script.sh
) so the path is retained from the shell. I decided against mentioning this yesterday because I noted you only used full paths in your script, which should also work to avoid this problem.
All excellent insights.
You can see the PATH value in my previous message on this subject (from a few minutes ago); it matches the value that I see as "root" when I print the PATH within the shell. So, that seems okay.
Also, I took your good advice and eliminated the potential for the vmail user's shell choice (which happens to be /bin/sh, *not* /bin/bash) to affect the script's behavior. To do this I modified my antispam configuration directives as such:
antispam_pipe_program = /bin/bash antispam_pipe_program_args = /usr/bin/sa-learn-pipe.sh antispam_pipe_program_spam_arg = --spam antispam_pipe_program_notspam_arg = --ham
Unfortunately, this change doesn't change the result at all; the call to "deliver" still exits with status code 75.
The other thing I didn't mention was the permissions on the path to /usr/lib/dovecot/deliver (or any other path, really). Directories with no world read/execute can prevent scripts from using files beneath them if they don't have permissions on each directory level in the path. I didn't mention this yesterday because you said you ran the script as vmail. However, looking at your "su vmail -c" command, I remember some times when "su postrgres -c" didn't work when "su - postrgres" then running the command did.
I have tried using "su vmail -c [...]", as well as "su vmail" and then pasting the command into the shell. Both yield the same result.
Also, there's no question that the vmail user is able to execute dovecot-adm; if he weren't, then a) pasting the command into the shell wouldn't work (and this does work), and b) I wouldn't be receiving exit status code 75, which is unique to dovecot-adm (I assume that I'd receive a more generic code, like 1, if it was a permissions problem).
Probably neither of these will be useful to you, but I mention them in hope that they trigger and idea or set you on an investigative path that proves helpful...
Any help at all is useful! I really appreciate the time and thought you put into your posts. I wish I felt closer to a solution... :(
Please do reply if you have any additional thoughts. I'm at my wit's end here!
Thanks again,
-Ben
What is the explanation for this behavior? It has to be something to do with how the plug-in calls the script. Does the plug-in call the script in some other context, like chroot?
As a final point of note, is it just me, or is the "90-plugin.conf" snippet incorrect at the bottom of http://wiki2.dovecot.org/Plugins/Antispam ? Those values appear to be for the analogous Dovecot 1 plug-in, e.g., "antispam_mail_sendmail" is used, when the equivalent directive is called "antispam_pipe_program" in versions >= 2.0.
-Ben
On 6/21/2013 3:01 PM, Mrten wrote:
On 21/6/2013 19:34 , Ben Johnson wrote:
Please do reply if you have any additional thoughts. I'm at my wit's end here!
When all else failes, use strace -f -F :)
(add it in front of the deliver call and expect LOTS of output)
Maarten.
YES! Brilliant, Maarten! That tells us what we need to know. Here is the relevant bit:
write(2, "\1\00429770 user sa-training@exampl"..., 139^A^D29770 user sa-training@example.com: Error reading configuration: net_connect_unix(/var/run/dovecot/config) failed: Permission denied
It seems the issue here is that "root" is the only user who is allowed to read Dovecot's configuration file. Presumably, Dovecot, like most services, is started as "root" and then drops its permissions to least-required once started.
Obviously, it would be imprudent to modify the permissions on /var/run/dovecot/config; they're set that way for a good reason.
What are the other options? I did see the "System Users" section at http://wiki.dovecot.org/LDA , and maybe that's what I missed.
System users
You can use deliver with a few selected system users (ie. user is found from /etc/passwd / NSS) by calling deliver in the user's ~/.forward file:
| "/usr/local/libexec/dovecot/deliver" This should work with any MTA which supports per-user .forward files. For qmail's per-user setup, see LDA/Qmail.
This method doesn't require the authentication socket explained below since it's executed as the user itself.
I'm struggling to identify this section's relevance to my situation. I thought, "Maybe I need to add the above-cited line to the vmail user's ~/.forward file." But I don't see how that will have any effect.
I feel like I'm almost there; just need one more nudge :)
Thanks for all the help!
-Ben
On 21.06.2013 21:54, wrote Ben Johnson:
write(2, "\1\00429770 user sa-training@exampl"..., 139^A^D29770 user sa-training@example.com: Error reading configuration: net_connect_unix(/var/run/dovecot/config) failed: Permission denied
It seems the issue here is that "root" is the only user who is allowed to read Dovecot's configuration file. Presumably, Dovecot, like most services, is started as "root" and then drops its permissions to least-required once started.
You can change owner and mode for /var/run/dovecot/config with the following entry in 10-master.conf:
service config { unix_listener config { mode = 0600 user = vmail } }
More details can be found here: http://wiki2.dovecot.org/Services
/e-frog
At 1PM -0400 on 21/06/13 you (Ben Johnson) wrote:
On 6/20/2013 10:00 PM, Bob Miller wrote:
It really boils-down to the fact that I can call the following on the command-line and it functions as expected:
su vmail -c '/usr/lib/dovecot/deliver -a "sa-training@example.com" -d "sa-training@example.com" -m "Training.SPAM" -p "/tmp/sendmail-msg-25794.txt"'
Yet, when I attempt to do the exact same thing from within the pipe script that Dovecot Antispam calls, I receive exit code 75 from deliver/dovecot-lda and absolutely nothing is logged, with exception of the information of which I'm already aware (logged to syslog).
Can you change lda to always log to syslog? It's possible you're not seeing any logs because lda doesn't have permission to write to the log files.
I am echo-ing $(whoami) just before calling "deliver" within the pipe script and the output is "vmail". So, it's not as though the vmail user somehow lacks the permissions required to send via dovecot-lda.
There are two things that came to mind when I read your mail yesterday. They are the first things I check for when my commands work and my scripts don't.
The first is $PATH, I have found innumerable times when a script wouldn't run it was because it wasn't running with a fully loaded $PATH variable, and this is especially true if you are launching your script from cron. To work around this I either put a PATH= at the top of the script, or I run the script as an argument to bash instead of using the executable bit (ie
bash /path/to/script.sh
instead of./script.sh
) so the path is retained from the shell. I decided against mentioning this yesterday because I noted you only used full paths in your script, which should also work to avoid this problem.All excellent insights.
You can see the PATH value in my previous message on this subject (from a few minutes ago); it matches the value that I see as "root" when I print the PATH within the shell. So, that seems okay.
Also, I took your good advice and eliminated the potential for the vmail user's shell choice (which happens to be /bin/sh, *not* /bin/bash)
Are you on a system where they are different?
to affect the script's behavior. To do this I modified my antispam configuration directives as such:
antispam_pipe_program = /bin/bash
It's generally better to write scripts in portable (or POSIX, at least) Bourne shell, rather than relying on features of particular shells.
antispam_pipe_program_args = /usr/bin/sa-learn-pipe.sh antispam_pipe_program_spam_arg = --spam antispam_pipe_program_notspam_arg = --ham
Unfortunately, this change doesn't change the result at all; the call to "deliver" still exits with status code 75.
The other thing I didn't mention was the permissions on the path to /usr/lib/dovecot/deliver (or any other path, really). Directories with no world read/execute can prevent scripts from using files beneath them if they don't have permissions on each directory level in the path. I didn't mention this yesterday because you said you ran the script as vmail. However, looking at your "su vmail -c" command, I remember some times when "su postrgres -c" didn't work when "su - postrgres" then running the command did.
I have tried using "su vmail -c [...]", as well as "su vmail" and then pasting the command into the shell. Both yield the same result.
Have you checked the group rights are the same in both cases? Is there any sort of MAC framework (SELinux or something similar) involved here?
Also, there's no question that the vmail user is able to execute dovecot-adm; if he weren't, then a) pasting the command into the shell wouldn't work (and this does work), and b) I wouldn't be receiving exit status code 75, which is unique to dovecot-adm (I assume that I'd receive a more generic code, like 1, if it was a permissions problem).
75 is a standard exit code from
Probably neither of these will be useful to you, but I mention them in hope that they trigger and idea or set you on an investigative path that proves helpful...
Any help at all is useful! I really appreciate the time and thought you put into your posts. I wish I felt closer to a solution... :(
Please do reply if you have any additional thoughts. I'm at my wit's end here!
As I believe someone else has already mentioned, the big hammer of strace is probably the most straightforward next step.
Ben
Ben Morrow, thanks for your reply. I sent an update on the issue shortly before you sent this reply. The issue is that the "vmail" user lacks the rights required to read Dovecot's configuration file (at least that's what I gather from the message obtained with strace).
But for the sake of thoroughness, I'll address each of your questions.
On 6/21/2013 4:01 PM, Ben Morrow wrote:
At 1PM -0400 on 21/06/13 you (Ben Johnson) wrote:
On 6/20/2013 10:00 PM, Bob Miller wrote:
It really boils-down to the fact that I can call the following on the command-line and it functions as expected:
su vmail -c '/usr/lib/dovecot/deliver -a "sa-training@example.com" -d "sa-training@example.com" -m "Training.SPAM" -p "/tmp/sendmail-msg-25794.txt"'
Yet, when I attempt to do the exact same thing from within the pipe script that Dovecot Antispam calls, I receive exit code 75 from deliver/dovecot-lda and absolutely nothing is logged, with exception of the information of which I'm already aware (logged to syslog).
Can you change lda to always log to syslog? It's possible you're not seeing any logs because lda doesn't have permission to write to the log files.
I tried both options: setting LDA to log to syslog (and it logged plenty of items, just nothing related to the pipe script's call to "deliver"), and I tried specifying the log file locations, explicitly, with the "log_path" and "info_log_path" directives within my "protocol lda {}" stanza. Again, LDA wrote to the log files for other reasons, but nothing relevant to the specific problem with "deliver" failing to deliver.
I am echo-ing $(whoami) just before calling "deliver" within the pipe script and the output is "vmail". So, it's not as though the vmail user somehow lacks the permissions required to send via dovecot-lda.
There are two things that came to mind when I read your mail yesterday. They are the first things I check for when my commands work and my scripts don't.
The first is $PATH, I have found innumerable times when a script wouldn't run it was because it wasn't running with a fully loaded $PATH variable, and this is especially true if you are launching your script from cron. To work around this I either put a PATH= at the top of the script, or I run the script as an argument to bash instead of using the executable bit (ie
bash /path/to/script.sh
instead of./script.sh
) so the path is retained from the shell. I decided against mentioning this yesterday because I noted you only used full paths in your script, which should also work to avoid this problem.All excellent insights.
You can see the PATH value in my previous message on this subject (from a few minutes ago); it matches the value that I see as "root" when I print the PATH within the shell. So, that seems okay.
Also, I took your good advice and eliminated the potential for the vmail user's shell choice (which happens to be /bin/sh, *not* /bin/bash)
Are you on a system where they are different?
I believe that they are different in Debian. "ls" for these files produces the following:
/bin/sh -> dash
/bin/bash
Even so, the script seems to function the same way with either interpreter, so, this doesn't seem to be a factor.
to affect the script's behavior. To do this I modified my antispam configuration directives as such:
antispam_pipe_program = /bin/bash
It's generally better to write scripts in portable (or POSIX, at least) Bourne shell, rather than relying on features of particular shells.
That makes fine sense, and I'll take it under advisement and see if I can modify the script to be as universal as possible.
antispam_pipe_program_args = /usr/bin/sa-learn-pipe.sh antispam_pipe_program_spam_arg = --spam antispam_pipe_program_notspam_arg = --ham
Unfortunately, this change doesn't change the result at all; the call to "deliver" still exits with status code 75.
The other thing I didn't mention was the permissions on the path to /usr/lib/dovecot/deliver (or any other path, really). Directories with no world read/execute can prevent scripts from using files beneath them if they don't have permissions on each directory level in the path. I didn't mention this yesterday because you said you ran the script as vmail. However, looking at your "su vmail -c" command, I remember some times when "su postrgres -c" didn't work when "su - postrgres" then running the command did.
I have tried using "su vmail -c [...]", as well as "su vmail" and then pasting the command into the shell. Both yield the same result.
Have you checked the group rights are the same in both cases? Is there any sort of MAC framework (SELinux or something similar) involved here?
Yes, the group rights should be the same, and no MAC framework is at play.
Also, there's no question that the vmail user is able to execute dovecot-adm; if he weren't, then a) pasting the command into the shell wouldn't work (and this does work), and b) I wouldn't be receiving exit status code 75, which is unique to dovecot-adm (I assume that I'd receive a more generic code, like 1, if it was a permissions problem).
75 is a standard exit code from
indicating temporary failure. Mail delivery programs need to be careful to distinguish between temporary and permanent failure, so they nearly always use the appropriate exit code.
Thank you for this informative tidbit!
Probably neither of these will be useful to you, but I mention them in hope that they trigger and idea or set you on an investigative path that proves helpful...
Any help at all is useful! I really appreciate the time and thought you put into your posts. I wish I felt closer to a solution... :(
Please do reply if you have any additional thoughts. I'm at my wit's end here!
As I believe someone else has already mentioned, the big hammer of strace is probably the most straightforward next step.
And it was what lead me to the root-cause (still looking for the solution, however); right you gents were! THANK YOU!
Ben
participants (5)
-
Ben Johnson
-
Ben Morrow
-
Bob Miller
-
e-frog
-
Mrten