Bug with $default_ldap setting

Mark Martinec Mark.Martinec+amavis at ijs.si
Tue Mar 29 17:13:04 CEST 2011


Huangbin,

> I get an unexpected result with $default_ldap setting: If base dn doesn't
> exist, amavisd should bypass/dunno this check and continue sending mail
> out, instead of defer this mail.
> 
> My settings in amavisd.conf
> 
> # ----
> $enable_ldap    = 1;
> $default_ldap   = {
>     [...]
>     base            => "domainName=%d,o=domains,dc=example,dc=com",
>     [...]
> };
> # ----
> 
> I have several virtual domains under "o=domains,dc=example,dc=com", i want
> to make it query "domainName=%d,o=domains,dc=example,dc=com" instead of
> "o=domains,dc=example,dc=com" for better performance.
> 
> The problem is, when i send mail to an external mail address, e.g. gmail,
> yahoo, hotmail, Amavisd raises below error log and mails can **NOT** be
> sent out:

> (!!)TROUBLE in process_request: do_search: failed again,
> LDAP_NO_SUCH_OBJECT at (eval 104) line 159,
> <DATA> line 392. at (eval 104) line 445, <DATA> line 392.
> 
> Amavisd should bypass/dunno this mail and continue sending it out, isn't
> it?

Please try the following patch (for 2.6.4), it will let LDAP lookup
code ignore the LDAP_NO_SUCH_OBJECT status, and avoid
retry attempts in cases where they are unlikely to succeed.


--- amavisd~	2011-03-29 03:09:05.000000000 +0200
+++ amavisd	2011-03-29 17:06:42.919174884 +0200
@@ -15069,5 +15069,5 @@
 sub do_search {
   my($self,$base,$scope,$filter) = @_;
-  my($result);
+  my($result,$error_name);
   $self->ldap or die "do_search: ldap not available";
   do_log(5,"lookup_ldap: searching base=\"%s\", scope=\"%s\", filter=\"%s\"",
@@ -15079,5 +15079,13 @@
                                     deref  => $self->{deref},
                                     );
-    if ($result->code) { die $result->error_name, "\n"; }
+    if ($result->code) {
+      $error_name = $result->error_name;
+      if ($error_name eq 'LDAP_NO_SUCH_OBJECT') {
+        # probably alright, e.g. a foreign %d
+        do_log(4, 'do_search failed in "%s": %s', $base, $error_name);
+      } else {
+        die $error_name."\n";
+      }
+    }
     1;
   } or do {
@@ -15086,6 +15094,9 @@
     if ($err !~ /^LDAP_/) {
       die "do_search: $err";
-    } else {  #  LDAP related error
-      do_log(0, "NOTICE: do_search: trying again: %s", $err);
+    } elsif ($error_name !~ /^LDAP_(?:BUSY|UNAVAILABLE|UNWILLING_TO_PERFORM|
+                             TIMEOUT|SERVER_DOWN|CONNECT_ERROR|OTHER)\z/x) {
+      die "do_search: failed: $error_name\n";
+    } else {  # LDAP related error, worth retrying
+      do_log(0, "NOTICE: do_search: trying again: %s", $error_name);
       $self->disconnect_from_ldap;
       $self->connect_to_ldap;
@@ -15351,6 +15362,7 @@
   eval {
     snmp_count('OpsLDAPSearch');
-    my($result) = $conn_h->do_search($base, $self->{scope}, $filter);
-    my(@entry) = $result->entries;
+    my(@entry);
+    my($search_obj) = $conn_h->do_search($base, $self->{scope}, $filter);
+    @entry = $search_obj->entries  if $search_obj && !$search_obj->code;
     my(%mv_ldap_attrs) = map { (lc($_), 1) } @mv_ldap_attrs;
     for my $entry (@entry) {


Mark


More information about the amavis-users mailing list