[exim] PLAIN authenticator that checks against two data sour…

Top Page
Delete this message
Reply to this message
Author: Mike Brudenell
Date:  
To: Exim Users
Subject: [exim] PLAIN authenticator that checks against two data sources
Hi!

I have tried so many ways to get this working and have used Exim 4.86.2 in
debug mode on Ubuntu until I'm going crackers but am stuck…

I'm trying to write a LOGIN authenticator using the plaintext driver that
checks two sources for authentication details:

1. First it checks a file for the username in $auth1. If present in the
file the password from the entry in the file is checked against the
supplied password in $auth2. Success/failure of the authentication is
determined by whether the passwords match.

If the username is not present in the file, then…

2. The authenticator then checks against LDAP by attempting to bind
using ldapauth to it. Success/failure of the authentication is determined
by whether bind succeeds or not.

I have got the "check the file first then LDAP" operating (and have done in
many different ways of writing it!) but am having problems getting the
correct final SMTP response when LDAP fails. In particular I'm getting Exim
returning

435 Unable to authenticate at present

instead of

535 Incorrect authentication data


The problem appears to be that when the username/password pair are wrong
then as expected LDAP fails to bind (obviously!) but in the code I've
written this causes a string expansion failure, which eventually leads back
to the 435 SMTP response.

I'm trying hard to get a forced failure to be generated instead — in this
iteration by putting the ldapauth within an if along with a "fail" in
string2 — which I know (from other tests) will give the 535 SMTP response,
but it's flatly refusing to do so; I keep getting the string expansion
error. (I guess it's because the forced-failure happens if the if's
expression evaluates to false, whereas in this case it's having its own
error.)

Can someone help me either debug this, or come up with a different way of
writing it?

Here's my authenticator with apologies: you might need a wide window to
cope with the wrapped lines:

LOGIN:
  driver           = plaintext
  server_set_id    = $auth1
  server_prompts   = <| Username: | Password:


  server_condition = ${if and{ \
                               { def:auth1 } \
                               { bool_lax{ \
                                           ${lookup {$auth1} lsearch
{/etc/exim4/cfg.d/passwords-for-auth-smtp} \
                                              { ${if crypteq {$auth2}
{\{sha1\}$value}} } \
                                              { ${if ldapauth \


 {user="uid=${quote_ldap_dn:$auth1},ou=people,ou=blah,dc=york,dc=ac,dc=uk" \
                                                       pass=${quote:$auth2}
\
                                                       nettime=10 \
                                                       time=7 \
                                                       ldap://
ldap.york.ac.uk/}  \
                                                     {yes} \
                                                     fail }} \
                                            } \
                                         }} \
                             }}


  server_advertise_condition = ${if and{ \
                                         {def:tls_in_cipher} \
                                         {!={$received_port}{25}} \
                                       } }



And here's the relevant extract from an "exim -bd -v -d+all" run when I
attempt to authenticate using a bad username and password:

17:40:32  4741 LOGIN authenticator server_condition:
17:40:32  4741   $auth1 = badusername
17:40:32  4741   $auth2 = badpassword
17:40:32  4741   $1 = badusername
17:40:32  4741   $2 = badpassword
17:40:32  4741 expanding: $auth1
17:40:32  4741    result: badusername
17:40:32  4741 expanding: /etc/exim4/cfg.d/passwords-for-auth-smtp
17:40:32  4741    result: /etc/exim4/cfg.d/passwords-for-auth-smtp
17:40:32  4741 search_open: lsearch
"/etc/exim4/cfg.d/passwords-for-auth-smtp"
17:40:32  4741 search_find: file="/etc/exim4/cfg.d/passwords-for-auth-smtp"
17:40:32  4741   key="badusername" partial=-1 affix=NULL starflags=0
17:40:32  4741 LRU list:
17:40:32  4741   :/etc/exim4/cfg.d/passwords-for-auth-smtp
17:40:32  4741   End
17:40:32  4741 internal_search_find:
file="/etc/exim4/cfg.d/passwords-for-auth-smtp"
17:40:32  4741   type=lsearch key="badusername"
17:40:32  4741 file lookup required for badusername
17:40:32  4741   in /etc/exim4/cfg.d/passwords-for-auth-smtp
17:40:32  4741 lookup failed
17:40:32  4741 expanding: $auth2
17:40:32  4741    result: badpassword
17:40:32  4741 skipping: result is not used
17:40:32  4741 expanding: \{sha1\}$value
17:40:32  4741    result: {sha1}
17:40:32  4741 skipping: result is not used
17:40:32  4741 condition: crypteq {$auth2} {\{sha1\}$value}
17:40:32  4741    result: false
17:40:32  4741 expanding:  ${if crypteq {$auth2} {\{sha1\}$value}}
17:40:32  4741    result:
17:40:32  4741 skipping: result is not used
17:40:32  4741 expanding: $auth1
17:40:32  4741    result: badusername
17:40:32  4741 expanding: $auth2
17:40:32  4741    result: badpassword
17:40:32  4741 expanding:
user="uid=${quote_ldap_dn:$auth1},ou=people,ou=blah,dc=york,dc=ac,dc=uk"
pass=${quote:$auth2} nettime=10 time=7 ldap://ldap.york.ac.uk/
17:40:32  4741    result:
user="uid=badusername,ou=people,ou=blah,dc=york,dc=ac,dc=uk"
pass=badpassword nettime=10 time=7 ldap://ldap.york.ac.uk/
17:40:32  4741 LDAP parameters:
user=uid=badusername,ou=people,blah,dc=york,dc=ac,dc=uk pass=badpassword
size=0 time=7 connect=10 dereference=0 referrals=on
17:40:32  4741 perform_ldap_search: ldapauth URL = "ldap://ldap.york.ac.uk/"
server=NULL port=0 sizelimit=0 timelimit=7 tcplimit=10
17:40:32  4741 after ldap_url_parse: host=ldap.york.ac.uk port=389
17:40:32  4741 ldap_initialize with URL ldap://ldap.york.ac.uk:389/
17:40:32  4741 initialized for LDAP (v3) server ldap.york.ac.uk:389
17:40:32  4741 LDAP_OPT_X_TLS_TRY set due to ldap:// URI
17:40:32  4741 binding with
user=uid=badusername,ou=people,blah,dc=york,dc=ac,dc=uk password=badpassword
17:40:32  4741 failed to bind the LDAP connection to server
ldap.york.ac.uk:389 - LDAP error 32: No such object
17:40:32  4741 failed to expand:  ${if ldapauth
{user="uid=${quote_ldap_dn:$auth1},ou=people,blah,dc=york,dc=ac,dc=uk"
pass=${quote:$auth2} nettime=10 time=7 ldap://ldap.york.ac.uk/}  {yes} fail
}} } }} }}
17:40:32  4741    error message: failed to bind the LDAP connection to
server ldap.york.ac.uk:389 - LDAP error 32: No such object
17:40:32  4741 failed to expand:  ${lookup {$auth1} lsearch
{/etc/exim4/cfg.d/passwords-for-auth-smtp} { ${if crypteq {$auth2}
{\{sha1\}$value}} } { ${if ldapauth
{user="uid=${quote_ldap_dn:$auth1},ou=people,blah,dc=york,dc=ac,dc=uk"
pass=${quote:$auth2} nettime=10 time=7 ldap://ldap.york.ac.uk/}  {yes} fail
}} } }} }}
17:40:32  4741    error message: failed to bind the LDAP connection to
server ldap.york.ac.uk:389 - LDAP error 32: No such object
17:40:32  4741 failed to expand: ${if and{ { def:auth1 } { bool_lax{
${lookup {$auth1} lsearch {/etc/exim4/cfg.d/passwords-for-auth-smtp} { ${if
crypteq {$auth2} {\{sha1\}$value}} } { ${if ldapauth
{user="uid=${quote_ldap_dn:$auth1},ou=people,blah,dc=york,dc=ac,dc=uk"
pass=${quote:$auth2} nettime=10 time=7 ldap://ldap.york.ac.uk/}  {yes} fail
}} } }} }}
17:40:32  4741    error message: failed to bind the LDAP connection to
server ldap.york.ac.uk:389 - LDAP error 32: No such object inside
"and{...}" condition
17:40:32  4741 expansion failed: failed to bind the LDAP connection to
server ldap.york.ac.uk:389 - LDAP error 32: No such object inside
"and{...}" condition
17:40:32  4741 expanding: $auth1
17:40:32  4741    result: badusername
17:40:32  4741 SMTP>> 435 Unable to authenticate at present



With many thanks for anything you can do to help save my sanity!
Mike B-)

--
Systems Administrator & Change Manager
IT Services, University of York, Heslington, York YO10 5DD, UK
Tel: +44-(0)1904-323811

Web: www.york.ac.uk/it-services
Disclaimer: www.york.ac.uk/docs/disclaimer/email.htm