1
2
3
4
5
6
7 package gov.bnl.gums.userGroup;
8
9 import gov.bnl.gums.GUMS;
10 import gov.bnl.gums.GridUser;
11 import gov.bnl.gums.configuration.Configuration;
12 import gov.bnl.gums.configuration.ConfigurationStore;
13 import gov.bnl.gums.db.UserGroupDB;
14
15 import java.util.*;
16
17 import javax.naming.*;
18 import javax.naming.directory.*;
19
20 import org.apache.log4j.Logger;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 public class LDAPUserGroup extends UserGroup {
40
41
42
43 static public String getTypeStatic() {
44 return "ldap";
45 }
46
47 protected Logger log = Logger.getLogger(LDAPUserGroup.class);
48 protected Logger gumsAdminLog = Logger.getLogger(GUMS.gumsAdminLogName);
49 protected ConfigurationStore confStore;
50 protected UserGroupDB db;
51 protected Configuration conf;
52 protected String persistenceFactory = "";
53 protected String server = "";
54 protected String certDNField = "description";
55 protected String memberUidField = "memberUid";
56 protected String uidField = "uid";
57 protected String peopleTree = "";
58 protected String peopleObject = "ou=People";
59 protected String peopleContext = null;
60 protected String groupTree = "";
61
62
63
64
65 public LDAPUserGroup() {
66 super();
67 }
68
69
70
71
72 public LDAPUserGroup(Configuration configuration) {
73 super(configuration);
74 }
75
76
77
78
79 public LDAPUserGroup(Configuration configuration, String name) {
80 super(configuration, name);
81 }
82
83 public UserGroup clone(Configuration configuration) {
84 LDAPUserGroup userGroup = new LDAPUserGroup(configuration, new String(getName()));
85 userGroup.setDescription(new String(getDescription()));
86 userGroup.setPersistenceFactory(new String(persistenceFactory));
87 userGroup.setAccess(new String(getAccess()));
88 userGroup.setPeopleTree(new String(getPeopleTree()));
89 userGroup.setGroupTree(new String(getGroupTree()));
90 userGroup.setMemberUidField(new String(getMemberUidField()));
91 userGroup.setUidField(new String(getUidField()));
92 userGroup.setServer(new String(getServer()));
93 userGroup.setCertDNField(new String(certDNField));
94 return userGroup;
95 }
96
97 public boolean equals(Object obj) {
98 if (obj instanceof LDAPUserGroup) {
99 LDAPUserGroup group = (LDAPUserGroup) obj;
100 if ((server == null ? group.server == null : server.equals(group.server)) &&
101 (peopleTree == null ? group.peopleTree == null : peopleTree.equals(group.peopleTree)) &&
102 (groupTree == null ? group.groupTree == null : groupTree.equals(group.groupTree)) &&
103 (certDNField == null ? group.certDNField == null : certDNField.equals(group.certDNField)) &&
104 (memberUidField == null ? group.memberUidField == null : memberUidField.equals(group.memberUidField)) &&
105 (uidField == null ? group.uidField == null : uidField.equals(group.uidField)) &&
106 (getName() == null ? group.getName() == null : getName().equals(group.getName())) &&
107 (persistenceFactory == null ? group.persistenceFactory == null : persistenceFactory.equals(group.persistenceFactory))) {
108 return true;
109 }
110 }
111 return false;
112 }
113
114
115
116
117
118
119 public String getCertDNField() {
120 return certDNField;
121 }
122
123
124
125
126
127
128 public String getGroupTree() {
129 return groupTree;
130 }
131
132 public java.util.List getMemberList() {
133 return getDB().retrieveMembers();
134 }
135
136 public String getMemberUidField() {
137 return memberUidField;
138 }
139
140
141
142
143
144
145 public String getPeopleTree() {
146 return peopleTree;
147 }
148
149
150
151
152
153
154 public String getPersistenceFactory() {
155 return persistenceFactory;
156 }
157
158
159
160
161
162
163 public String getQuery() {
164 return peopleTree;
165 }
166
167
168
169
170
171
172 public String getServer() {
173 return this.server;
174 }
175
176 public String getType() {
177 return "ldap";
178 }
179
180 public String getUidField() {
181 return uidField;
182 }
183
184 public int hashCode() {
185 return new String(peopleTree + " " + groupTree).hashCode();
186 }
187
188 public boolean isInGroup(GridUser user) {
189 return getDB().isMemberInGroup(user);
190 }
191
192
193
194
195
196
197 public void setCertDNField(String certDNField) {
198 this.certDNField = certDNField;
199 }
200
201
202
203
204
205
206 public void setGroupTree(String groupTree) {
207 this.groupTree = groupTree;
208 }
209
210 public void setMemberUidField(String memberUidField) {
211 this.memberUidField = memberUidField;
212 }
213
214
215
216
217
218
219 public void setPeopleTree(String peopleTree) {
220 this.peopleTree = peopleTree;
221 this.peopleObject = peopleTree.substring(0, peopleTree.indexOf(','));
222 this.peopleContext = peopleTree.substring(peopleTree.indexOf(',')+1);
223 }
224
225
226
227
228
229
230 public void setPersistenceFactory(String persistenceFactory) {
231 this.persistenceFactory = persistenceFactory;
232 }
233
234
235
236
237
238
239
240 public void setQuery(String query) {
241 if (query.startsWith(peopleObject+",")) {
242 peopleTree = query;
243 peopleObject = query.substring(0, query.indexOf(','));
244 peopleContext = query.substring(query.indexOf(',')+1);
245 } else if (query.startsWith("ou=")) {
246 peopleObject = "ou=People";
247 peopleContext = query.substring(query.indexOf(',')+1);
248 peopleTree = peopleObject + "," + peopleContext;
249 } else if (query.startsWith("o=")) {
250 peopleObject = "ou=People";
251 peopleContext = query;
252 peopleTree = peopleObject + "," + peopleContext;
253 } else {
254 throw new IllegalArgumentException("The query is not understood by the LDAP group. It is expected to start with \"ou=...\" or \"o=...\"");
255 }
256 }
257
258
259
260
261
262 public void setServer(String server) {
263 this.server = server;
264 }
265
266 public void setUidField(String uidField) {
267 this.uidField = uidField;
268 }
269
270 public String toString() {
271 return "LDAPGroup: ldap://"+server+"/"+peopleTree+","+groupTree;
272 }
273
274 public String toString(String bgColor) {
275 return "<td bgcolor=\""+bgColor+"\"><a href=\"userGroups.jsp?command=edit&name=" + getName() + "\">" + getName() + "</a></td><td bgcolor=\""+bgColor+"\">" + getType() + "</td><td bgcolor=\""+bgColor+"\"> </td><td bgcolor=\""+bgColor+"\"> </td><td bgcolor=\""+bgColor+"\"></td><td bgcolor=\""+bgColor+"\"> </td>";
276 }
277
278 public String toXML() {
279 return "\t\t<ldapUserGroup\n"+
280 "\t\t\tname='"+getName()+"'\n"+
281 "\t\t\taccess='"+accessTypes[accessIndex]+"'\n" +
282 "\t\t\tdescription='"+getDescription()+"'\n"+
283 "\t\t\tserver='"+server+"'\n" +
284 "\t\t\tpeopleTree='"+peopleTree+"'\n" +
285 "\t\t\tgroupTree='"+groupTree+"'\n" +
286 "\t\t\tmemberUidField='"+memberUidField+"'\n" +
287 "\t\t\tuidField='" + uidField+"'\n" +
288 "\t\t\tcertDNField='"+certDNField+"'\n" +
289 "\t\t\tpersistenceFactory='"+persistenceFactory+"'/>\n\n";
290 }
291
292 public void updateMembers() {
293 getDB().loadUpdatedList(retrieveMembers());
294 }
295
296 private UserGroupDB getDB() {
297 if (db==null)
298 db = getConfiguration().getPersistenceFactory(persistenceFactory).retrieveUserGroupDB( getName() );
299 return db;
300 }
301
302 private List retrieveGroupMembers(DirContext rootCtx, Attribute members) throws javax.naming.NamingException {
303 Map people = retrievePeopleMap(rootCtx);
304 NamingEnumeration names = members.getAll();
305 List list = new ArrayList();
306 while (names.hasMore()) {
307
308 String ldapName = (String) names.next();
309 ldapName = ldapName.trim();
310 String certDN = (String) people.get(ldapName);
311 if (certDN == null) {
312 gumsAdminLog.warn("Member of a LDAP VO group not mapped to any certificate: '" + ldapName + "'");
313 } else {
314 list.add(new GridUser(certDN, null));
315 }
316 }
317 if (list.isEmpty()) {
318 gumsAdminLog.warn("The following group returned no members: " + this);
319 }
320 return list;
321 }
322
323
324
325
326
327
328
329 private synchronized List retrieveMembers() {
330 java.util.Properties properties = retrieveProperties();
331 log.info("Retrieving members from '" + properties.getProperty("java.naming.provider.url") + "' '" + peopleTree + "' '" + groupTree + "'");
332 try {
333 javax.naming.directory.DirContext jndiCtx = new javax.naming.directory.InitialDirContext(properties);
334 if (!peopleTree.equals("") && groupTree.equals("")) {
335 DirContext rootCtx = (DirContext) jndiCtx.lookup(peopleContext);
336 return retrieveVOMembers(rootCtx);
337 }
338 else if (!groupTree.equals("") && !peopleTree.equals("")) {
339 Attributes atts = jndiCtx.getAttributes(groupTree);
340 Attribute members = atts.get(memberUidField);
341 if (members == null) {
342 String message = "Couldn't retrieve the list of members from the LDAP group: missing attribute member";
343 GUMS.gumsAdminEmailLog.put("ldapUpdateProblem", message, false);
344 throw new RuntimeException(message);
345 }
346 DirContext rootCtx = (DirContext) jndiCtx.lookup(peopleContext);
347 return retrieveGroupMembers(rootCtx, members);
348 }
349 } catch (javax.naming.NamingException e) {
350 String message = "Couldn't retrieve users from LDAP server: " + e;
351
352
353
354 log.error("Couldn't retrieve LDAP users: ", e);
355 throw new RuntimeException(message, e);
356 }
357 return null;
358 }
359
360 private Properties retrieveProperties() {
361 Properties properties = new java.util.Properties();
362 properties.put(Context.PROVIDER_URL, "ldap://"+server);
363 properties.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
364 properties.put(Context.SECURITY_PROTOCOL, "none");
365 return properties;
366 }
367
368 private List retrieveVOMembers(DirContext rootCtx) throws NamingException {
369 Map people = retrievePeopleMap(rootCtx);
370 List list = new ArrayList(people.values());
371 if (list.isEmpty()) {
372 gumsAdminLog.warn("The following group returned no members: " + this);
373 }
374 Iterator iter = list.iterator();
375 List users = new ArrayList();
376 while (iter.hasNext()) {
377 String dn = (String) iter.next();
378 users.add(new GridUser(dn, null));
379 }
380 if (list.isEmpty()) {
381 gumsAdminLog.warn("The following group returned no members: " + this);
382 }
383 return users;
384 }
385
386 protected Map retrievePeopleMap(DirContext ldap) throws javax.naming.NamingException {
387 NamingEnumeration people = ldap.search(peopleObject, "("+certDNField+"=*)", null);
388 Map map = new Hashtable();
389 while (people.hasMore()) {
390 SearchResult person = (SearchResult) people.next();
391 Attributes personAtts = person.getAttributes();
392 String ldapDN = (String)personAtts.get(uidField).get();
393
394
395
396 String certDN = (String) personAtts.get(certDNField).get();
397 if (certDN.startsWith("subject=")) {
398 certDN = certDN.substring(8);
399 }
400 certDN = certDN.trim();
401 map.put(ldapDN, certDN);
402 }
403 return map;
404 }
405 }