| 1 21 22 package org.jsmtpd.plugins.filters.ldap; 23 24 import java.util.HashSet ; 25 import java.util.Hashtable ; 26 import java.util.List ; 27 import java.util.Set ; 28 29 import javax.naming.Context ; 30 import javax.naming.InitialContext ; 31 import javax.naming.NamingEnumeration ; 32 import javax.naming.NamingException ; 33 import javax.naming.directory.Attribute ; 34 import javax.naming.directory.Attributes ; 35 import javax.naming.directory.DirContext ; 36 import javax.naming.directory.SearchControls ; 37 import javax.naming.directory.SearchResult ; 38 39 import org.apache.commons.logging.Log; 40 import org.apache.commons.logging.LogFactory; 41 import org.jsmtpd.core.common.PluginInitException; 42 import org.jsmtpd.core.common.filter.FilterTreeFailureException; 43 import org.jsmtpd.core.common.filter.FilterTreeSuccesException; 44 import org.jsmtpd.core.common.filter.IFilter; 45 import org.jsmtpd.core.mail.Email; 46 import org.jsmtpd.core.mail.EmailAddress; 47 import org.jsmtpd.core.mail.InvalidAddress; 48 import org.jsmtpd.core.mail.Rcpt; 49 54 public class LdapBodyRewriter implements IFilter { 55 private String adminBindDn; private String adminBindPassword; 57 private String ldapUrl; 59 private String ldapUserProvider; private String ldapUserAliasAttribute="rfc822MailAlias"; private String ldapUserPrimaryMail="mail"; 64 private Hashtable <String ,String > environnement; 65 private static Log log = LogFactory.getLog(LdapBodyRewriter.class); 66 67 public boolean doFilter(Email input) throws FilterTreeFailureException, FilterTreeSuccesException { 68 Set <Rcpt> toRemove = new HashSet <Rcpt>(); 72 Set <Rcpt> toAdd = new HashSet <Rcpt>(); 73 List <Rcpt> recipients=input.getRcpt(); 74 for (Rcpt rcpt : recipients) { 75 if (!isPrimaryMail(rcpt)) { 76 Set <Rcpt> aliases = computeAliases(rcpt); 77 if (aliases!=null) { 78 toRemove.add(rcpt); 79 for (Rcpt alias : aliases) { 80 log.debug("user "+rcpt.toString()+" is aliased to "+alias.toString()+" (recipient changed)"); 81 toAdd.add(alias); 82 } 83 } else { 84 Set <Rcpt> catchAlls = computeCatchAll(rcpt); 85 if (catchAlls!=null) { 86 toRemove.add(rcpt); 87 for (Rcpt catchAll : catchAlls) { 88 log.debug("user "+rcpt.toString()+" is catch all to "+catchAll.toString()+" (recipient changed)"); 89 toAdd.add(catchAll); 90 } 91 } else { 92 log.debug(" user "+rcpt.toString()+" is neither uid, alias, or catchall"); 93 } 94 } 95 } else { 96 log.debug(" user "+rcpt.toString()+" is a real uid"); 97 } 98 } 99 recipients.removeAll(toRemove); 101 recipients.addAll(toAdd); 102 return true; 103 } 104 105 private boolean isPrimaryMail (Rcpt recipient) { 106 InitialContext initialContext; 107 try { 108 initialContext = new InitialContext (environnement); 109 DirContext ctx = (DirContext ) initialContext.lookup(ldapUrl); 110 SearchControls searchControl = new SearchControls (); 111 NamingEnumeration <SearchResult > namingEnumeration; 112 String ldapQuery="("+ldapUserPrimaryMail+"="+recipient.getEmailAddress().toString()+")"; 113 namingEnumeration = ctx.search(ldapUserProvider,ldapQuery,searchControl); 114 if (namingEnumeration.hasMore()) { 115 return true; 116 } 117 } catch (NamingException e1) { 118 log.error(" Failed to query server",e1); 119 } 120 return false; 121 } 122 123 private Set <Rcpt> computeAliases (Rcpt recipient) { 126 Set <Rcpt> newRecipients = new HashSet <Rcpt>(); 127 InitialContext initialContext; 128 try { 129 initialContext = new InitialContext (environnement); 130 DirContext ctx = (DirContext ) initialContext.lookup(ldapUrl); 131 SearchControls searchControl = new SearchControls (); 132 NamingEnumeration <SearchResult > namingEnumeration = ctx.search(ldapUserProvider,"("+ldapUserAliasAttribute+"="+ 133 recipient.getEmailAddress().toString()+")",searchControl); 134 while (namingEnumeration.hasMore()) { 135 SearchResult result = namingEnumeration.next(); 136 Attributes attributes = result.getAttributes(); 137 Attribute uid = attributes.get(ldapUserPrimaryMail); 138 EmailAddress ad = EmailAddress.parseAddress((String )uid.get()); 139 ad.setHost(recipient.getEmailAddress().getHost()); 140 newRecipients.add(new Rcpt(ad)); 141 } 142 } catch (NamingException e) { 143 log.error(" Can't query server for aliases",e); 144 } catch (InvalidAddress e) { 145 log.error(" invalid addres in alias of "+recipient.getEmailAddress().toString(),e); 146 } 147 148 if (newRecipients.size()>0) 149 return newRecipients; 150 else 151 return null; 152 } 153 private Set <Rcpt> computeCatchAll (Rcpt recipient) { 156 Set <Rcpt> newRecipients = new HashSet <Rcpt>(); 157 InitialContext initialContext; 158 try { 159 initialContext = new InitialContext (environnement); 160 DirContext ctx = (DirContext ) initialContext.lookup(ldapUrl); 161 SearchControls searchControl = new SearchControls (); 162 NamingEnumeration <SearchResult > namingEnumeration = ctx.search(ldapUserProvider,"("+ldapUserAliasAttribute+"=@"+ 163 recipient.getEmailAddress().getHost()+")",searchControl); 164 while (namingEnumeration.hasMore()) { 165 SearchResult result = namingEnumeration.next(); 166 Attributes attributes = result.getAttributes(); 167 Attribute uid = attributes.get(ldapUserPrimaryMail); 168 EmailAddress ad = EmailAddress.parseAddress((String )uid.get()); 169 newRecipients.add(new Rcpt(ad)); 170 } 171 } catch (NamingException e) { 172 log.error(" Can't query server for catchAll",e); 173 } catch (InvalidAddress e) { 174 log.error(" invalid addres in alias(catchall) of "+recipient.getEmailAddress().toString(),e); 175 } 176 177 if (newRecipients.size()>0) 178 return newRecipients; 179 else 180 return null; 181 } 182 183 public String getPluginName() { 184 return "Ldap body rewriter for Jsmtpd"; 185 } 186 187 public void initPlugin() throws PluginInitException { 188 environnement = new Hashtable <String ,String >(); 189 environnement.put(Context.SECURITY_PRINCIPAL,adminBindDn); 190 environnement.put(Context.SECURITY_CREDENTIALS,adminBindPassword); 191 } 192 193 public void shutdownPlugin() { 194 195 } 196 197 public void setAdminBindDn(String adminBindDn) { 198 this.adminBindDn = adminBindDn; 199 } 200 201 public void setAdminBindPassword(String adminBindPassword) { 202 this.adminBindPassword = adminBindPassword; 203 } 204 205 public void setLdapUrl(String ldapUrl) { 206 this.ldapUrl = ldapUrl; 207 } 208 209 210 public void setLdapUserAliasAttribute(String ldapUserAliasAttribute) { 211 this.ldapUserAliasAttribute = ldapUserAliasAttribute; 212 } 213 214 public void setLdapUserPrimaryMail(String ldapUserPrimaryMail) { 215 this.ldapUserPrimaryMail = ldapUserPrimaryMail; 216 } 217 218 public void setLdapUserProvider(String ldapUserProvider) { 219 this.ldapUserProvider = ldapUserProvider; 220 } 221 } 222 | Popular Tags |