View Javadoc

1   /*
2    * NISAccountMapper.java
3    *
4    * Created on May 25, 2004, 2:25 PM
5    */
6   
7   package gov.bnl.gums;
8   
9   import java.util.*;
10  import org.apache.commons.logging.*;
11  
12  /*** Maps a user to a local account based on the CN of the certificate and the
13   * gecos field in the NIS/YP database. The mapping can't be perfect, but contains
14   * a series of heuristics that solve up to 90% of the cases, depending on how
15   * the NIS database itself is kept.
16   * <p>
17   * It's suggested not to use this policy by itself, but to have it part of a 
18   * CompositeAccountMapper in which a ManualAccountMapper comes first. This allows
19   * to override those user mapping that are not satisfying.
20   *
21   * @author  Gabriele Carcassi
22   */
23  public class NISAccountMapper implements AccountMapper {
24      static Log log = LogFactory.getLog(NISAccountMapper.class);
25      static Log adminLog = LogFactory.getLog(GUMS.resourceAdminLog);
26      
27      /***
28       * Holds value of property jndiNisUrl.
29       */
30      private String jndiNisUrl;
31      
32      /*** Creates a new instance of NISAccountMapper */
33      public NISAccountMapper() {
34          adminLog.warn("The use of gov.bnl.gums.NISAccountMapper is deprecated. Please use gov.bnl.gums.GecosNisAccoutMapper: it provides the same functionalities.");
35      }
36      
37      public String mapUser(String userDN) {
38          String[] nameSurname = parseNameAndSurname(userDN);
39          return nisClient(jndiNisUrl).findAccount(nameSurname[0], nameSurname[1]);
40      }
41      
42      public static String[] parseNameAndSurname(String certificateSubject) {
43          int begin = certificateSubject.indexOf("CN=") + 3;
44          String CN = certificateSubject.substring(begin);
45          
46          StringTokenizer tokenizer = new StringTokenizer(CN);
47          List tokens = new ArrayList();
48          while (tokenizer.hasMoreTokens()) {
49              tokens.add(tokenizer.nextToken());
50          }
51          
52          String name = (String) tokens.get(0);
53  
54          int nSurname = 1;
55          while (!checkSurname((String) tokens.get(tokens.size()-nSurname))) {
56              nSurname++;
57          }
58          String surname = (String) tokens.get(tokens.size()-nSurname);
59          
60          log.trace("Certificate '" + certificateSubject + "' divided in name='" + name + "' and surname='" + surname + "'");
61          return new String[] {name, surname};
62      }
63      
64      static boolean checkSurname(String possibleSurname) {
65          if (Character.isDigit(possibleSurname.charAt(0))) {
66              return false;
67          }
68          if (possibleSurname.charAt(possibleSurname.length() - 1) == '.') {
69              return false;
70          }
71          
72          return true;
73      }
74      
75      /***
76       * Getter for property jndiNisUrl.
77       * @return Value of property jndiNisUrl.
78       */
79      public String getJndiNisUrl() {
80          return this.jndiNisUrl;
81      }
82      
83      /***
84       * Setter for property jndiNisUrl.
85       * @param jndiNisUrl New value of property jndiNisUrl.
86       */
87      public void setJndiNisUrl(String jndiNisUrl) {
88          this.jndiNisUrl = jndiNisUrl;
89      }
90      
91      private Map nisClients = new Hashtable();
92      private NisClient nisClient(String jndiNisUrl) {
93          NisClient client = (NisClient) nisClients.get(jndiNisUrl);
94          if (client != null) {
95              log.trace("Reusing NisClient for '" + jndiNisUrl +"'");
96              return client;
97          }
98          log.debug("Creating new NisClient for '" + jndiNisUrl + "'");
99          client = new NisClient(jndiNisUrl);
100         nisClients.put(jndiNisUrl, client);
101         return client;
102     }
103     
104 }