View Javadoc

1   /*
2    * GecosNisAccountMapper.java
3    *
4    * Created on April 13, 2005, 4:21 PM
5    */
6   
7   package gov.bnl.gums.account;
8   
9   import gov.bnl.gums.GUMS;
10  import gov.bnl.gums.SiteUser;
11  import gov.bnl.gums.configuration.Configuration;
12  import gov.bnl.gums.util.CertToolkit;
13  import gov.bnl.gums.util.GecosMap;
14  
15  import java.util.Hashtable;
16  import java.util.Map;
17  import java.util.Properties;
18  
19  import javax.naming.NamingEnumeration;
20  import javax.naming.directory.Attribute;
21  import javax.naming.directory.Attributes;
22  import javax.naming.directory.DirContext;
23  import javax.naming.directory.InitialDirContext;
24  import javax.naming.directory.SearchResult;
25  import javax.persistence.Entity;
26  import javax.persistence.Transient;
27  
28  import org.apache.log4j.Logger;
29  
30  /** 
31   * Matches the DN with the account information retrieved from a NIS server.
32   *
33   * @author Gabriele Carcassi, Jay Packard
34   * @deprecated
35   */
36  @Entity
37  public class GecosNisAccountMapper extends AccountMapper {
38      static private Logger log = Logger.getLogger(GecosNisAccountMapper.class);
39      static Logger gumsAdminLog = Logger.getLogger(GUMS.gumsAdminLogName);
40      static private Map<String, GecosMap> gecosMaps = new Hashtable<String, GecosMap>();
41  
42      // persistent variables
43      private String jndiNisUrl;
44      private String accountField = "cn";
45      private String gecosField = "gecos";
46      
47      public GecosNisAccountMapper() {
48      	super();
49      	gumsAdminLog.debug("The use of gov.bnl.gums.GecosNisAccountMapper is unsupported.");
50      }
51      
52      public GecosNisAccountMapper(Configuration configuration, String name) {
53      	super(configuration, name);
54      }
55      
56      public GecosMap createMap() {
57          Properties jndiProperties = retrieveJndiProperties();
58          int nTries = 5;
59          Exception lastException = null;
60          int i = 0;
61          for (; i < nTries; i++) {
62              GecosMap map = new GecosMap();
63              log.debug("Attempt " + i + " to retrieve map for '" + jndiNisUrl + "'");
64              try {
65                  DirContext jndiCtx = new InitialDirContext(jndiProperties);
66                  NamingEnumeration<SearchResult> nisMap = jndiCtx.search("system/passwd.byname", "(cn=*)", null);
67                  log.trace("Server responded");
68                  while (nisMap.hasMore()) {
69                      SearchResult res = (SearchResult) nisMap.next();
70                      Attributes atts = res.getAttributes();
71                      String account = (String) atts.get(accountField).get();
72                      Attribute gecosAtt = atts.get(gecosField);
73                      if (gecosAtt != null) {
74                          String gecos = gecosAtt.get().toString();
75                          map.addEntry(account, gecos);
76                      } else {
77                          log.trace("Found user '" + account + "' with no GECOS field");
78                      }
79                  }
80                  jndiCtx.close();
81                  return map;
82              } catch (javax.naming.NamingException ne) {
83                  log.warn("Error filling the maps for NIS "+jndiNisUrl, ne);
84                  lastException = ne;
85                  try {
86                      Thread.sleep(100);
87                  } catch (InterruptedException e) {
88                      log.warn("Interrupted", e);
89                  }
90              } catch (Exception e) {
91                  log.warn("Error filling the maps for NIS "+jndiNisUrl, e);
92                  lastException = e;
93                  try {
94                      Thread.sleep(100);
95                  } catch (InterruptedException ie) {
96                      log.warn("Interrupted", e);
97                  }
98              }
99          }
100         if (i == nTries) {
101             throw new RuntimeException("Couldn't retrieve NIS maps from " + jndiNisUrl, lastException);
102         }
103         return null;
104     }
105     
106     public String getAccountField() {
107     	return accountField;
108     }
109     
110     public String getGecosField() {
111     	return gecosField;
112     }
113     
114     public String getJndiNisUrl() {
115         return jndiNisUrl;
116     }
117     
118     public SiteUser mapDn(String dn, boolean createIfDoesNotExist) {
119         String[] nameSurname = CertToolkit.parseNameAndSurname(dn);
120         GecosMap map = gecosMap();
121         log.trace("GECOS findAccount. Name: " + nameSurname[0] + " - Surname: " + nameSurname[1] + " - GECOSMap: " + gecosMap());
122         return new SiteUser(map.findAccount(nameSurname[0], nameSurname[1]));
123     }
124     
125     @ConfigFieldAnnotation(label="NIS Account UID Field", example="uid")
126     public void setAccountField(String accountField) {
127     	this.accountField = accountField;
128     }
129     
130     @ConfigFieldAnnotation(label="NIS Name Field", example="gecos") 
131     public void setGecosField(String gecosField) {
132     	this.gecosField = gecosField;
133     }
134     
135     @ConfigFieldAnnotation(label="JNDI NIS URL", example="nis://localhost/usatlas.bnl.gov ")
136     public void setJndiNisUrl(String jndiNisUrl) {
137         this.jndiNisUrl = jndiNisUrl;
138     }
139     
140     private GecosMap gecosMap() {
141         synchronized (gecosMaps) {
142             GecosMap map = (GecosMap) gecosMaps.get(getMapName());
143             if (map != null) {
144                 if (map.isValid()) {
145                     log.trace("Reusing GECOS map for '" + getMapName() +"'");
146                     return map;
147                 } else {
148                     log.trace("Invalidating expired GECOS map for '" + getMapName() +"'");
149                     gecosMaps.remove(getMapName());
150                 }
151             }
152             log.debug("Creating new GECOS map for '" + getMapName() + "'");
153             map = createMap();
154             gecosMaps.put(getMapName(), map);
155             return map;
156         }
157     }
158 
159     private Properties retrieveJndiProperties() {
160         Properties jndiProperties = new java.util.Properties();
161         jndiProperties.put("java.naming.provider.url", jndiNisUrl);
162         jndiProperties.put("java.naming.factory.initial","com.sun.jndi.nis.NISCtxFactory");
163         return jndiProperties;
164     }      
165     
166     @Transient
167     protected String getMapName() {
168         return jndiNisUrl;
169     }
170 }