1
2
3
4
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 }