gunnar: server/perl-kolab/bin kolab_smtpdpolicy.in,1.2,1.3

cvs at kolab.org cvs at kolab.org
Tue Jan 5 19:37:40 CET 2010


Author: gunnar

Update of /kolabrepository/server/perl-kolab/bin
In directory doto:/tmp/cvs-serv3360/perl-kolab/bin

Modified Files:
	kolab_smtpdpolicy.in 
Log Message:
MFB: kolab/issue1340 (RFC: restrict users to sending mail only to internal recipients)

Index: kolab_smtpdpolicy.in
===================================================================
RCS file: /kolabrepository/server/perl-kolab/bin/kolab_smtpdpolicy.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- kolab_smtpdpolicy.in	20 Jan 2009 17:22:12 -0000	1.2
+++ kolab_smtpdpolicy.in	5 Jan 2010 18:37:38 -0000	1.3
@@ -281,6 +281,59 @@
   return 1;
 }
 
+sub check_restricted_sender {
+  my $username = shift;
+  my $recipient = shift;
+  my $tries = 0;
+ AGAIN:
+  my $mesg = $ldap->search( base=> $conf_basedn,
+			    scope=> 'sub',
+			    filter=> "(&(objectClass=kolabinetorgperson)(|(mail=$username)(uid=$username)))",
+			    attrs => [ 'kolabAllowSMTPRecipient' ]);
+  if( !$mesg->code && $mesg->count() > 0 ) {
+    mylog($syslog_priority, "LDAP search returned ".$mesg->count()." objects") if $verbose;
+    my $global_permit = 1;
+    foreach my $entry ( $mesg->entries ) {
+      my $allowed_recipient;
+      my $permit;
+      for $allowed_recipient ($entry->get_value('kolabAllowSMTPRecipient')) {
+          mylog($syslog_priority, lc($username." has allowed recipient ".$allowed_recipient)) if $verbose;
+	  # Return early with REJECT if the sender may not send at all ('-')
+	  return undef if $allowed_recipient eq '-';
+	  # Check if the entry is a negation (leading '-')
+	  if ( $allowed_recipient =~ /^-(.*)/ ) {
+	      $permit = undef;
+	      $allowed_recipient = $1;
+	  } else {
+	      # Once there is a non-negating entry we need REJECT if no rule matched
+	      $global_permit = undef;
+	      $permit = 1;
+	  }
+	  if ( $allowed_recipient =~ /@/ ) {
+	      # If the entry contains '@' the leading segment must match
+	      return $permit if  $recipient =~ /^$allowed_recipient/;
+	  } elsif ( $allowed_recipient =~ /^\.(.*)/ ) {
+	      # If the entry starts with '.' the trailing domain must match
+	      return $permit if $recipient =~ /${1}$/;
+	  } else {
+	      # All other entries must match the last part of the mail address
+	      return $permit if $recipient =~ /\@${allowed_recipient}$/;
+	  }
+      }
+    }
+    # Allow sending if there was no entry or no negated entry rejected
+    return $global_permit;
+  } elsif( $mesg->code && $mesg->code != LDAP_NO_SUCH_OBJECT && $tries++ <= $ldap_max_tries ) {
+    mylog($syslog_priority, "LDAP Connection error during CHECKRESTRICTEDSENDER: ".$mesg->error.", trying to reconnect" );
+    ldap_connect;
+    goto AGAIN;
+  } elsif( $mesg->code ) {
+    mylog( $syslog_priority, "LDAP Error during CHECKRESTRICTEDSENDER: ".$mesg->error ) if $verbose;
+    # Just fall through and accept the message in case there was an LDAP problem.
+  }
+  return 1;
+}
+
 #
 # SMTPD access policy routine. The result is an action just like
 # it would be specified on the right-hand side of a Postfix access
@@ -306,6 +359,9 @@
   return "REJECT Access denied" if( !$username && !$conf_allowunauth );
 
   eval{ $username = lookup_uid($username) }; return "DEFER_IF_PERMIT $@" if $@;
+
+  # Check for valid access from a restricted sender
+  return "REJECT Recipient denied" unless check_restricted_sender($username, $recipient);
 
   # See if sender is owned by someone
   my @uids;





More information about the commits mailing list